f)u
6pFrf
+bD5de,G?[lrdnik"}lF zdQdA&=کΰ)(B8eUyDK?]zr7?H
\ No newline at end of file
diff --git a/_modules/bench-chain/_.git/objects/63/9c8a61491739b59eebb96ca948e467aa4e868a b/_modules/bench-chain/_.git/objects/63/9c8a61491739b59eebb96ca948e467aa4e868a
new file mode 100644
index 0000000..51bfc11
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/63/9c8a61491739b59eebb96ca948e467aa4e868a differ
diff --git a/_modules/bench-chain/_.git/objects/63/a62910eb7fbdda354ca2cef533504700bcfdd5 b/_modules/bench-chain/_.git/objects/63/a62910eb7fbdda354ca2cef533504700bcfdd5
new file mode 100644
index 0000000..206895e
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/63/a62910eb7fbdda354ca2cef533504700bcfdd5 differ
diff --git a/_modules/bench-chain/_.git/objects/66/7312b2750a33926692d8ce6f642cc67844c54a b/_modules/bench-chain/_.git/objects/66/7312b2750a33926692d8ce6f642cc67844c54a
new file mode 100644
index 0000000..6bc9a80
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/66/7312b2750a33926692d8ce6f642cc67844c54a differ
diff --git a/_modules/bench-chain/_.git/objects/68/6e64bd5e62c5b644e4c179b19c76fc94b0e5f5 b/_modules/bench-chain/_.git/objects/68/6e64bd5e62c5b644e4c179b19c76fc94b0e5f5
new file mode 100644
index 0000000..6a8c479
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/68/6e64bd5e62c5b644e4c179b19c76fc94b0e5f5 differ
diff --git a/_modules/bench-chain/_.git/objects/68/8f8d1fe007ed28d157999988b36530c86fdffa b/_modules/bench-chain/_.git/objects/68/8f8d1fe007ed28d157999988b36530c86fdffa
new file mode 100644
index 0000000..6b5a3b6
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/68/8f8d1fe007ed28d157999988b36530c86fdffa differ
diff --git a/_modules/bench-chain/_.git/objects/69/2de92c621ca666f7c9370ed21ccad450249d1b b/_modules/bench-chain/_.git/objects/69/2de92c621ca666f7c9370ed21ccad450249d1b
new file mode 100644
index 0000000..822fdeb
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/69/2de92c621ca666f7c9370ed21ccad450249d1b differ
diff --git a/_modules/bench-chain/_.git/objects/69/e155eb5d7dfa06bb571a2b69fa5e74c639ce33 b/_modules/bench-chain/_.git/objects/69/e155eb5d7dfa06bb571a2b69fa5e74c639ce33
new file mode 100644
index 0000000..c8947e3
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/69/e155eb5d7dfa06bb571a2b69fa5e74c639ce33 differ
diff --git a/_modules/bench-chain/_.git/objects/6a/bb00cfda5a2ea3d34b149f4c3546d10047e55f b/_modules/bench-chain/_.git/objects/6a/bb00cfda5a2ea3d34b149f4c3546d10047e55f
new file mode 100644
index 0000000..26255c8
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/6a/bb00cfda5a2ea3d34b149f4c3546d10047e55f differ
diff --git a/_modules/bench-chain/_.git/objects/6d/47ba3ea40bad9ffcbc0672f8af80de29da6176 b/_modules/bench-chain/_.git/objects/6d/47ba3ea40bad9ffcbc0672f8af80de29da6176
new file mode 100644
index 0000000..afb4fa4
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/6d/47ba3ea40bad9ffcbc0672f8af80de29da6176 differ
diff --git a/_modules/bench-chain/_.git/objects/6d/5aad9531e04962548d632370e32c4fa3c7e40c b/_modules/bench-chain/_.git/objects/6d/5aad9531e04962548d632370e32c4fa3c7e40c
new file mode 100644
index 0000000..2f3e197
--- /dev/null
+++ b/_modules/bench-chain/_.git/objects/6d/5aad9531e04962548d632370e32c4fa3c7e40c
@@ -0,0 +1,2 @@
+xAN0EY
+ZiLI2Fj*qn1`50h$goCwAJյU{Ij/fNJZӶ8bШ;ch srДqϵhjTjVԒ?e 6T"LG,eA@'o&?zxpEvAʈ"loW/fBY=o7qvN2Oς
\ No newline at end of file
diff --git a/_modules/bench-chain/_.git/objects/6d/cefddf6246457f4dd6dd726450bb44dbdd29bf b/_modules/bench-chain/_.git/objects/6d/cefddf6246457f4dd6dd726450bb44dbdd29bf
new file mode 100644
index 0000000..3e5cb08
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/6d/cefddf6246457f4dd6dd726450bb44dbdd29bf differ
diff --git a/_modules/bench-chain/_.git/objects/70/7a8049d0f3e2bcebc0b5791df18fb0ded453e1 b/_modules/bench-chain/_.git/objects/70/7a8049d0f3e2bcebc0b5791df18fb0ded453e1
new file mode 100644
index 0000000..c715329
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/70/7a8049d0f3e2bcebc0b5791df18fb0ded453e1 differ
diff --git a/_modules/bench-chain/_.git/objects/73/9a538857bf0613958154ba447718f1eaceb6e2 b/_modules/bench-chain/_.git/objects/73/9a538857bf0613958154ba447718f1eaceb6e2
new file mode 100644
index 0000000..fde270b
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/73/9a538857bf0613958154ba447718f1eaceb6e2 differ
diff --git a/_modules/bench-chain/_.git/objects/73/f883d218a72af91eefdcff9e306c700cc8d27d b/_modules/bench-chain/_.git/objects/73/f883d218a72af91eefdcff9e306c700cc8d27d
new file mode 100644
index 0000000..98e5a40
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/73/f883d218a72af91eefdcff9e306c700cc8d27d differ
diff --git a/_modules/bench-chain/_.git/objects/77/343d86414723f4e3d44df76a6781e7d1258c8a b/_modules/bench-chain/_.git/objects/77/343d86414723f4e3d44df76a6781e7d1258c8a
new file mode 100644
index 0000000..5fd34f6
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/77/343d86414723f4e3d44df76a6781e7d1258c8a differ
diff --git a/_modules/bench-chain/_.git/objects/7c/0a9623ff2634cc85cf410682a9158558216cd5 b/_modules/bench-chain/_.git/objects/7c/0a9623ff2634cc85cf410682a9158558216cd5
new file mode 100644
index 0000000..eb54e0d
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/7c/0a9623ff2634cc85cf410682a9158558216cd5 differ
diff --git a/_modules/bench-chain/_.git/objects/7c/7bdcf5e4330ccc5f9fc3a141b8727b466abb80 b/_modules/bench-chain/_.git/objects/7c/7bdcf5e4330ccc5f9fc3a141b8727b466abb80
new file mode 100644
index 0000000..6c82f42
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/7c/7bdcf5e4330ccc5f9fc3a141b8727b466abb80 differ
diff --git a/_modules/bench-chain/_.git/objects/7d/c83bcfba8cbf9adb282c2baff15124073b102b b/_modules/bench-chain/_.git/objects/7d/c83bcfba8cbf9adb282c2baff15124073b102b
new file mode 100644
index 0000000..47538d5
--- /dev/null
+++ b/_modules/bench-chain/_.git/objects/7d/c83bcfba8cbf9adb282c2baff15124073b102b
@@ -0,0 +1,2 @@
+xMN@Y>@0$B n
LT3%+6,X5:\BD²{d!N(!tkz!48\vB0`hg*jԶF5NUP3
1UBB
I*ы[l˲)[w/O`tdM0#jo\6\KQY=#e!o1C!a
+0;L8UX[Os9sLί278zޡ
\ No newline at end of file
diff --git a/_modules/bench-chain/_.git/objects/7f/79a8e8d45e5023289816c1d16711d1f430cbfe b/_modules/bench-chain/_.git/objects/7f/79a8e8d45e5023289816c1d16711d1f430cbfe
new file mode 100644
index 0000000..fc517b8
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/7f/79a8e8d45e5023289816c1d16711d1f430cbfe differ
diff --git a/_modules/bench-chain/_.git/objects/82/42725aab19956e74db7f7d57ba827ca11fa79e b/_modules/bench-chain/_.git/objects/82/42725aab19956e74db7f7d57ba827ca11fa79e
new file mode 100644
index 0000000..9c983ed
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/82/42725aab19956e74db7f7d57ba827ca11fa79e differ
diff --git a/_modules/bench-chain/_.git/objects/84/10cfabca006bf488cb8be4067415a4feb2a8a4 b/_modules/bench-chain/_.git/objects/84/10cfabca006bf488cb8be4067415a4feb2a8a4
new file mode 100644
index 0000000..3b84303
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/84/10cfabca006bf488cb8be4067415a4feb2a8a4 differ
diff --git a/_modules/bench-chain/_.git/objects/84/4b254a5a97a8f7995301d236e07ba8f69a4096 b/_modules/bench-chain/_.git/objects/84/4b254a5a97a8f7995301d236e07ba8f69a4096
new file mode 100644
index 0000000..5dbb6b0
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/84/4b254a5a97a8f7995301d236e07ba8f69a4096 differ
diff --git a/_modules/bench-chain/_.git/objects/87/1304b8970da16284172037484df2628ae23377 b/_modules/bench-chain/_.git/objects/87/1304b8970da16284172037484df2628ae23377
new file mode 100644
index 0000000..a356448
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/87/1304b8970da16284172037484df2628ae23377 differ
diff --git a/_modules/bench-chain/_.git/objects/87/409b56660ebc25080f6ece82c532330b88da17 b/_modules/bench-chain/_.git/objects/87/409b56660ebc25080f6ece82c532330b88da17
new file mode 100644
index 0000000..c54720d
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/87/409b56660ebc25080f6ece82c532330b88da17 differ
diff --git a/_modules/bench-chain/_.git/objects/88/a3bca4df3b527a3628ca4b59f1b9dfcd5f34b3 b/_modules/bench-chain/_.git/objects/88/a3bca4df3b527a3628ca4b59f1b9dfcd5f34b3
new file mode 100644
index 0000000..ed5add1
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/88/a3bca4df3b527a3628ca4b59f1b9dfcd5f34b3 differ
diff --git a/_modules/bench-chain/_.git/objects/8a/4f13dd544b5b1708d785c1a696d59cdb2d7881 b/_modules/bench-chain/_.git/objects/8a/4f13dd544b5b1708d785c1a696d59cdb2d7881
new file mode 100644
index 0000000..3ed1cf4
--- /dev/null
+++ b/_modules/bench-chain/_.git/objects/8a/4f13dd544b5b1708d785c1a696d59cdb2d7881
@@ -0,0 +1,2 @@
+xAj0E)tEbJғ(Ɠ!べG7=Bs>Ez;HV%)NQф4[β0~l%ɔR"ZNQ|IE0n;7sx9
+1OMs+D̅az<7
jv=-FH
\ No newline at end of file
diff --git a/_modules/bench-chain/_.git/objects/8a/5eec4d6179f215a123bca1608ed11e9437197c b/_modules/bench-chain/_.git/objects/8a/5eec4d6179f215a123bca1608ed11e9437197c
new file mode 100644
index 0000000..3c183a9
--- /dev/null
+++ b/_modules/bench-chain/_.git/objects/8a/5eec4d6179f215a123bca1608ed11e9437197c
@@ -0,0 +1,4 @@
+xUQ;NP)F(
+@uې
+.EJ:*I33;[X~6tr7B ϐ癏Q%9Oh2x,˺>\dCNi\eXߦ^Z^os&S}_(ISRa:E,X5@dn}!%xJ$61U35)ջwzZ8T0
ߌ{Yv@/h<>lc'h4`oڮ!gU
+Dj؏"/'kUݘXqѹfNkDmoɼ
\ No newline at end of file
diff --git a/_modules/bench-chain/_.git/objects/8a/95d57e7438d2e668cc57a1d8a7cd1677690815 b/_modules/bench-chain/_.git/objects/8a/95d57e7438d2e668cc57a1d8a7cd1677690815
new file mode 100644
index 0000000..69d2b53
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/8a/95d57e7438d2e668cc57a1d8a7cd1677690815 differ
diff --git a/_modules/bench-chain/_.git/objects/8c/d1baf7cf270a61959ab09413f74388680f400b b/_modules/bench-chain/_.git/objects/8c/d1baf7cf270a61959ab09413f74388680f400b
new file mode 100644
index 0000000..6ceb30c
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/8c/d1baf7cf270a61959ab09413f74388680f400b differ
diff --git a/_modules/bench-chain/_.git/objects/8d/f8e421e1fcde885342c00bec2bf1df88b15cf0 b/_modules/bench-chain/_.git/objects/8d/f8e421e1fcde885342c00bec2bf1df88b15cf0
new file mode 100644
index 0000000..14bd7a1
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/8d/f8e421e1fcde885342c00bec2bf1df88b15cf0 differ
diff --git a/_modules/bench-chain/_.git/objects/8f/07639c40435ee1acb5354f742b0e76289fccbb b/_modules/bench-chain/_.git/objects/8f/07639c40435ee1acb5354f742b0e76289fccbb
new file mode 100644
index 0000000..96efb7f
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/8f/07639c40435ee1acb5354f742b0e76289fccbb differ
diff --git a/_modules/bench-chain/_.git/objects/8f/7bf451cfc95ee19c79889a3e1e6ee1073bf3e6 b/_modules/bench-chain/_.git/objects/8f/7bf451cfc95ee19c79889a3e1e6ee1073bf3e6
new file mode 100644
index 0000000..bcf71cd
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/8f/7bf451cfc95ee19c79889a3e1e6ee1073bf3e6 differ
diff --git a/_modules/bench-chain/_.git/objects/91/62fd6916ba61c178340cb90f933261471f917a b/_modules/bench-chain/_.git/objects/91/62fd6916ba61c178340cb90f933261471f917a
new file mode 100644
index 0000000..445e612
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/91/62fd6916ba61c178340cb90f933261471f917a differ
diff --git a/_modules/bench-chain/_.git/objects/91/ab301e3632fcc8be372dc9abc0bbe9be904487 b/_modules/bench-chain/_.git/objects/91/ab301e3632fcc8be372dc9abc0bbe9be904487
new file mode 100644
index 0000000..5f13146
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/91/ab301e3632fcc8be372dc9abc0bbe9be904487 differ
diff --git a/_modules/bench-chain/_.git/objects/94/0800ac9f0b38d932fee124365f2630c804aae4 b/_modules/bench-chain/_.git/objects/94/0800ac9f0b38d932fee124365f2630c804aae4
new file mode 100644
index 0000000..fa54c42
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/94/0800ac9f0b38d932fee124365f2630c804aae4 differ
diff --git a/_modules/bench-chain/_.git/objects/94/4f4a3d882b52ae2cfd9fd85129557bd00512b5 b/_modules/bench-chain/_.git/objects/94/4f4a3d882b52ae2cfd9fd85129557bd00512b5
new file mode 100644
index 0000000..b4e82cb
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/94/4f4a3d882b52ae2cfd9fd85129557bd00512b5 differ
diff --git a/_modules/bench-chain/_.git/objects/98/0b0967ad6d6cbc7ade5d51fdcfe3d150ee95c4 b/_modules/bench-chain/_.git/objects/98/0b0967ad6d6cbc7ade5d51fdcfe3d150ee95c4
new file mode 100644
index 0000000..f41333d
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/98/0b0967ad6d6cbc7ade5d51fdcfe3d150ee95c4 differ
diff --git a/_modules/bench-chain/_.git/objects/98/dcc818b1507299d15ae336d17fbc4c7234299f b/_modules/bench-chain/_.git/objects/98/dcc818b1507299d15ae336d17fbc4c7234299f
new file mode 100644
index 0000000..ef952ea
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/98/dcc818b1507299d15ae336d17fbc4c7234299f differ
diff --git a/_modules/bench-chain/_.git/objects/98/f6fa7a55d246afdc6e00e4848cb0e5cf54acbc b/_modules/bench-chain/_.git/objects/98/f6fa7a55d246afdc6e00e4848cb0e5cf54acbc
new file mode 100644
index 0000000..a9b1cde
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/98/f6fa7a55d246afdc6e00e4848cb0e5cf54acbc differ
diff --git a/_modules/bench-chain/_.git/objects/9c/a06c3e3751f3673822a3e0c52bca1c5fe6dd92 b/_modules/bench-chain/_.git/objects/9c/a06c3e3751f3673822a3e0c52bca1c5fe6dd92
new file mode 100644
index 0000000..5db8e24
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/9c/a06c3e3751f3673822a3e0c52bca1c5fe6dd92 differ
diff --git a/_modules/bench-chain/_.git/objects/9d/cae5b25f8a10c35369f6ea0ad887adae9012d1 b/_modules/bench-chain/_.git/objects/9d/cae5b25f8a10c35369f6ea0ad887adae9012d1
new file mode 100644
index 0000000..75c2b25
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/9d/cae5b25f8a10c35369f6ea0ad887adae9012d1 differ
diff --git a/_modules/bench-chain/_.git/objects/9e/26dfeeb6e641a33dae4961196235bdb965b21b b/_modules/bench-chain/_.git/objects/9e/26dfeeb6e641a33dae4961196235bdb965b21b
new file mode 100644
index 0000000..a70f72d
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/9e/26dfeeb6e641a33dae4961196235bdb965b21b differ
diff --git a/_modules/bench-chain/_.git/objects/a2/cea129985dd5bbeeaf240c13aa43b5483fbcdc b/_modules/bench-chain/_.git/objects/a2/cea129985dd5bbeeaf240c13aa43b5483fbcdc
new file mode 100644
index 0000000..4b879fd
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/a2/cea129985dd5bbeeaf240c13aa43b5483fbcdc differ
diff --git a/_modules/bench-chain/_.git/objects/a5/c728ef89d7f774f225d31eba08d79798c987ab b/_modules/bench-chain/_.git/objects/a5/c728ef89d7f774f225d31eba08d79798c987ab
new file mode 100644
index 0000000..42f0d63
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/a5/c728ef89d7f774f225d31eba08d79798c987ab differ
diff --git a/_modules/bench-chain/_.git/objects/a6/c29b91593e2bf779ba2cc2f44aecaf006839b0 b/_modules/bench-chain/_.git/objects/a6/c29b91593e2bf779ba2cc2f44aecaf006839b0
new file mode 100644
index 0000000..bc7c1a0
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/a6/c29b91593e2bf779ba2cc2f44aecaf006839b0 differ
diff --git a/_modules/bench-chain/_.git/objects/a8/6a7d5d211cf09bfb6a753329124d2aadd01f83 b/_modules/bench-chain/_.git/objects/a8/6a7d5d211cf09bfb6a753329124d2aadd01f83
new file mode 100644
index 0000000..7e355e3
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/a8/6a7d5d211cf09bfb6a753329124d2aadd01f83 differ
diff --git a/_modules/bench-chain/_.git/objects/ab/5c70649bc49d8998b12c9efc3b9277736a312e b/_modules/bench-chain/_.git/objects/ab/5c70649bc49d8998b12c9efc3b9277736a312e
new file mode 100644
index 0000000..c2a7a66
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/ab/5c70649bc49d8998b12c9efc3b9277736a312e differ
diff --git a/_modules/bench-chain/_.git/objects/ad/e727b18022e1ae5f7d4c7eba74699552cbefb3 b/_modules/bench-chain/_.git/objects/ad/e727b18022e1ae5f7d4c7eba74699552cbefb3
new file mode 100644
index 0000000..dad22a8
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/ad/e727b18022e1ae5f7d4c7eba74699552cbefb3 differ
diff --git a/_modules/bench-chain/_.git/objects/ae/2de0701fa258f90b4649695fa3e4891c33ca9b b/_modules/bench-chain/_.git/objects/ae/2de0701fa258f90b4649695fa3e4891c33ca9b
new file mode 100644
index 0000000..717e28b
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/ae/2de0701fa258f90b4649695fa3e4891c33ca9b differ
diff --git a/_modules/bench-chain/_.git/objects/ae/cda9db491d70a09326a7bf99aee60166d6a188 b/_modules/bench-chain/_.git/objects/ae/cda9db491d70a09326a7bf99aee60166d6a188
new file mode 100644
index 0000000..c6f58c4
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/ae/cda9db491d70a09326a7bf99aee60166d6a188 differ
diff --git a/_modules/bench-chain/_.git/objects/b3/6c4445792f9d0fa9c4c8029ef8d22ad3d18f27 b/_modules/bench-chain/_.git/objects/b3/6c4445792f9d0fa9c4c8029ef8d22ad3d18f27
new file mode 100644
index 0000000..c8ddaa9
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/b3/6c4445792f9d0fa9c4c8029ef8d22ad3d18f27 differ
diff --git a/_modules/bench-chain/_.git/objects/b3/f6844ad74b962bc3fa0e47e616237569b6f857 b/_modules/bench-chain/_.git/objects/b3/f6844ad74b962bc3fa0e47e616237569b6f857
new file mode 100644
index 0000000..7bc15b3
--- /dev/null
+++ b/_modules/bench-chain/_.git/objects/b3/f6844ad74b962bc3fa0e47e616237569b6f857
@@ -0,0 +1,2 @@
+xMO09Wt*i݆4@9[2M
+"qiٴf2<"U
,E*efIҧEM(Ru: U]砨 -CϾ .)
)Ԇ#|0@b\AHrP&(!X۴z nذ,a6Ƚa^_^K
\ No newline at end of file
diff --git a/_modules/bench-chain/_.git/objects/b4/829d42d6713d8d9542cae2bc920a5ae00e656b b/_modules/bench-chain/_.git/objects/b4/829d42d6713d8d9542cae2bc920a5ae00e656b
new file mode 100644
index 0000000..9e84477
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/b4/829d42d6713d8d9542cae2bc920a5ae00e656b differ
diff --git a/_modules/bench-chain/_.git/objects/b5/ecd0dca40335ff022ac4b3453b45ffa3267fbd b/_modules/bench-chain/_.git/objects/b5/ecd0dca40335ff022ac4b3453b45ffa3267fbd
new file mode 100644
index 0000000..bf751e1
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/b5/ecd0dca40335ff022ac4b3453b45ffa3267fbd differ
diff --git a/_modules/bench-chain/_.git/objects/b6/6b11f4c6953e18525e5cd35d329b1b09c41fc4 b/_modules/bench-chain/_.git/objects/b6/6b11f4c6953e18525e5cd35d329b1b09c41fc4
new file mode 100644
index 0000000..46799f4
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/b6/6b11f4c6953e18525e5cd35d329b1b09c41fc4 differ
diff --git a/_modules/bench-chain/_.git/objects/ba/140192fd956412e73a43f9d6adf3e8debba788 b/_modules/bench-chain/_.git/objects/ba/140192fd956412e73a43f9d6adf3e8debba788
new file mode 100644
index 0000000..41bcf9e
--- /dev/null
+++ b/_modules/bench-chain/_.git/objects/ba/140192fd956412e73a43f9d6adf3e8debba788
@@ -0,0 +1 @@
+xON WoҲ$h:/mr9K[5ۛ^ kxJ"IeV=_QR_i06Jڡ)pޅH̟Tx K p/oi@N-r?
lax-IM`hRt5W$lGٝ>3?Tg6w7J_CFZ)
o,}|$jxn
\ No newline at end of file
diff --git a/_modules/bench-chain/_.git/objects/bc/4f2ef5b97af8d8032f49b655c0d8cb8ef3b128 b/_modules/bench-chain/_.git/objects/bc/4f2ef5b97af8d8032f49b655c0d8cb8ef3b128
new file mode 100644
index 0000000..b7ae244
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/bc/4f2ef5b97af8d8032f49b655c0d8cb8ef3b128 differ
diff --git a/_modules/bench-chain/_.git/objects/bc/a2744cf4ae8792a7ffb643a8eb94580960f178 b/_modules/bench-chain/_.git/objects/bc/a2744cf4ae8792a7ffb643a8eb94580960f178
new file mode 100644
index 0000000..68f93ea
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/bc/a2744cf4ae8792a7ffb643a8eb94580960f178 differ
diff --git a/_modules/bench-chain/_.git/objects/bd/d8d13d5d9f2d85dc901f6b43d77ccc4e09c447 b/_modules/bench-chain/_.git/objects/bd/d8d13d5d9f2d85dc901f6b43d77ccc4e09c447
new file mode 100644
index 0000000..1ac0172
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/bd/d8d13d5d9f2d85dc901f6b43d77ccc4e09c447 differ
diff --git a/_modules/bench-chain/_.git/objects/be/ceacb17f65ae4da651e45fe5eebc66c79a07ca b/_modules/bench-chain/_.git/objects/be/ceacb17f65ae4da651e45fe5eebc66c79a07ca
new file mode 100644
index 0000000..9c4fdbb
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/be/ceacb17f65ae4da651e45fe5eebc66c79a07ca differ
diff --git a/_modules/bench-chain/_.git/objects/be/ddb4d2acd1a13b08dd2d4e4cd31caa2fe2ee4e b/_modules/bench-chain/_.git/objects/be/ddb4d2acd1a13b08dd2d4e4cd31caa2fe2ee4e
new file mode 100644
index 0000000..97fb6f4
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/be/ddb4d2acd1a13b08dd2d4e4cd31caa2fe2ee4e differ
diff --git a/_modules/bench-chain/_.git/objects/bf/4b399b7da59c7ffcefd6f2418bb215ce1d73b2 b/_modules/bench-chain/_.git/objects/bf/4b399b7da59c7ffcefd6f2418bb215ce1d73b2
new file mode 100644
index 0000000..ce70d53
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/bf/4b399b7da59c7ffcefd6f2418bb215ce1d73b2 differ
diff --git a/_modules/bench-chain/_.git/objects/bf/709a17edd2168735042b6437af4b7822cf8fae b/_modules/bench-chain/_.git/objects/bf/709a17edd2168735042b6437af4b7822cf8fae
new file mode 100644
index 0000000..88af40d
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/bf/709a17edd2168735042b6437af4b7822cf8fae differ
diff --git a/_modules/bench-chain/_.git/objects/bf/da96864f0d5305e1d6c9d05447d8e7cd25725f b/_modules/bench-chain/_.git/objects/bf/da96864f0d5305e1d6c9d05447d8e7cd25725f
new file mode 100644
index 0000000..7f089bc
--- /dev/null
+++ b/_modules/bench-chain/_.git/objects/bf/da96864f0d5305e1d6c9d05447d8e7cd25725f
@@ -0,0 +1,3 @@
+xeA
+0P9@[.HI)FډΤ=Q)
+îm6!d8!3DFۖmՇȄx+H'!2+rP%ף.GJti~?گ2V=B
\ No newline at end of file
diff --git a/_modules/bench-chain/_.git/objects/c0/bf74cc31af00a5a8183817b9fc0cde4bc6ea7e b/_modules/bench-chain/_.git/objects/c0/bf74cc31af00a5a8183817b9fc0cde4bc6ea7e
new file mode 100644
index 0000000..f224003
--- /dev/null
+++ b/_modules/bench-chain/_.git/objects/c0/bf74cc31af00a5a8183817b9fc0cde4bc6ea7e
@@ -0,0 +1 @@
+xeOKN1e=.ߊEY8@Ip3x3
L_[,g*
\ No newline at end of file
diff --git a/_modules/bench-chain/_.git/objects/c1/ce4ac2d3a3417cb362f7b9edb02055646698ad b/_modules/bench-chain/_.git/objects/c1/ce4ac2d3a3417cb362f7b9edb02055646698ad
new file mode 100644
index 0000000..9bd75f2
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/c1/ce4ac2d3a3417cb362f7b9edb02055646698ad differ
diff --git a/_modules/bench-chain/_.git/objects/c1/f7691b11420284150a4c55a340c19fc26e9a7c b/_modules/bench-chain/_.git/objects/c1/f7691b11420284150a4c55a340c19fc26e9a7c
new file mode 100644
index 0000000..b5d74cc
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/c1/f7691b11420284150a4c55a340c19fc26e9a7c differ
diff --git a/_modules/bench-chain/_.git/objects/c2/386d1d7503a49d602713cab19b8e9170b7a884 b/_modules/bench-chain/_.git/objects/c2/386d1d7503a49d602713cab19b8e9170b7a884
new file mode 100644
index 0000000..2cfe0a8
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/c2/386d1d7503a49d602713cab19b8e9170b7a884 differ
diff --git a/_modules/bench-chain/_.git/objects/c2/434867c44c9d08c4fcf11496ed7a5400c34acb b/_modules/bench-chain/_.git/objects/c2/434867c44c9d08c4fcf11496ed7a5400c34acb
new file mode 100644
index 0000000..adcf78d
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/c2/434867c44c9d08c4fcf11496ed7a5400c34acb differ
diff --git a/_modules/bench-chain/_.git/objects/c2/c80ffb65fcfc9ab24a6270c964e5a0825e1457 b/_modules/bench-chain/_.git/objects/c2/c80ffb65fcfc9ab24a6270c964e5a0825e1457
new file mode 100644
index 0000000..47755a0
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/c2/c80ffb65fcfc9ab24a6270c964e5a0825e1457 differ
diff --git a/_modules/bench-chain/_.git/objects/c3/692539dd439d3f7f311b0bd9d00dd09fb8724b b/_modules/bench-chain/_.git/objects/c3/692539dd439d3f7f311b0bd9d00dd09fb8724b
new file mode 100644
index 0000000..f20487f
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/c3/692539dd439d3f7f311b0bd9d00dd09fb8724b differ
diff --git a/_modules/bench-chain/_.git/objects/c3/9342cfe692907a077b0c6597b1bd1a64947eb3 b/_modules/bench-chain/_.git/objects/c3/9342cfe692907a077b0c6597b1bd1a64947eb3
new file mode 100644
index 0000000..c8f99d5
--- /dev/null
+++ b/_modules/bench-chain/_.git/objects/c3/9342cfe692907a077b0c6597b1bd1a64947eb3
@@ -0,0 +1 @@
+xQ;0)3J$?;="ZXؚ@aZ\{Yy ~4
}%)ˮnJU3l5 E$UkHq٘*]*EC]M%F<x(v3B"qvZk?@u+X-˂0-N߾>3Һ$c|йj\Du,no|4Ba!iZ|Ht ~a(KMG(+G&ó}Ł뇍&8G$,9',z~%b1PP2M^w0YwwI'ҙ
\ No newline at end of file
diff --git a/_modules/bench-chain/_.git/objects/c4/a24cb434f7c85dbd0f450262763f04fcf9e5d5 b/_modules/bench-chain/_.git/objects/c4/a24cb434f7c85dbd0f450262763f04fcf9e5d5
new file mode 100644
index 0000000..8d95fe3
--- /dev/null
+++ b/_modules/bench-chain/_.git/objects/c4/a24cb434f7c85dbd0f450262763f04fcf9e5d5
@@ -0,0 +1,2 @@
+xM0E9i`'v,ЁcOk;JB%0$b63-RdѵB7-'*%Zm˦l
+f` дuWZ[+xHٕD!YxZ0#C8!mPurF[0Xv|~
vDbLp!G01v lq7*Ӗ]#@Gd/1vid
\ No newline at end of file
diff --git a/_modules/bench-chain/_.git/objects/c7/544a8ff65960670a407af8ec0ccafd8cf174ea b/_modules/bench-chain/_.git/objects/c7/544a8ff65960670a407af8ec0ccafd8cf174ea
new file mode 100644
index 0000000..8bb04f2
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/c7/544a8ff65960670a407af8ec0ccafd8cf174ea differ
diff --git a/_modules/bench-chain/_.git/objects/c7/628b52b2a3e51138b9cb05ca74bf89bf82ec33 b/_modules/bench-chain/_.git/objects/c7/628b52b2a3e51138b9cb05ca74bf89bf82ec33
new file mode 100644
index 0000000..fd27150
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/c7/628b52b2a3e51138b9cb05ca74bf89bf82ec33 differ
diff --git a/_modules/bench-chain/_.git/objects/c7/cf3d01cd5e666734af9614caa0e4d263534dba b/_modules/bench-chain/_.git/objects/c7/cf3d01cd5e666734af9614caa0e4d263534dba
new file mode 100644
index 0000000..aa95696
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/c7/cf3d01cd5e666734af9614caa0e4d263534dba differ
diff --git a/_modules/bench-chain/_.git/objects/c7/dca206e7838da2147171a162337a3625b8aead b/_modules/bench-chain/_.git/objects/c7/dca206e7838da2147171a162337a3625b8aead
new file mode 100644
index 0000000..8d7b991
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/c7/dca206e7838da2147171a162337a3625b8aead differ
diff --git a/_modules/bench-chain/_.git/objects/c8/42847d04c24fa025448835a457af9f55ac1d1f b/_modules/bench-chain/_.git/objects/c8/42847d04c24fa025448835a457af9f55ac1d1f
new file mode 100644
index 0000000..6ed97b6
--- /dev/null
+++ b/_modules/bench-chain/_.git/objects/c8/42847d04c24fa025448835a457af9f55ac1d1f
@@ -0,0 +1 @@
+x+)JMU044d040031QJ-/**fh8COJD۴b TQRbIIjQ%HU=K[UixPUy) 5=w}?Ε8uֆ)ߝ;20{
\ No newline at end of file
diff --git a/_modules/bench-chain/_.git/objects/c9/5e414ea16e05f78bb56adb055bdf1ee585ff70 b/_modules/bench-chain/_.git/objects/c9/5e414ea16e05f78bb56adb055bdf1ee585ff70
new file mode 100644
index 0000000..27c04fb
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/c9/5e414ea16e05f78bb56adb055bdf1ee585ff70 differ
diff --git a/_modules/bench-chain/_.git/objects/c9/763e4008d0f5d3f256f34bfcbd1a16f25239ba b/_modules/bench-chain/_.git/objects/c9/763e4008d0f5d3f256f34bfcbd1a16f25239ba
new file mode 100644
index 0000000..e06d141
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/c9/763e4008d0f5d3f256f34bfcbd1a16f25239ba differ
diff --git a/_modules/bench-chain/_.git/objects/cc/2f293db032aee617ee3e49fffe6962f97c72be b/_modules/bench-chain/_.git/objects/cc/2f293db032aee617ee3e49fffe6962f97c72be
new file mode 100644
index 0000000..b35777a
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/cc/2f293db032aee617ee3e49fffe6962f97c72be differ
diff --git a/_modules/bench-chain/_.git/objects/cd/15d5423840f8cdc2804db6190875b6bd51dec3 b/_modules/bench-chain/_.git/objects/cd/15d5423840f8cdc2804db6190875b6bd51dec3
new file mode 100644
index 0000000..3ed9c17
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/cd/15d5423840f8cdc2804db6190875b6bd51dec3 differ
diff --git a/_modules/bench-chain/_.git/objects/cd/492be7305fcafc4be24c58b0bf787a1bf64219 b/_modules/bench-chain/_.git/objects/cd/492be7305fcafc4be24c58b0bf787a1bf64219
new file mode 100644
index 0000000..ade8bea
--- /dev/null
+++ b/_modules/bench-chain/_.git/objects/cd/492be7305fcafc4be24c58b0bf787a1bf64219
@@ -0,0 +1 @@
+xAJ0]TП4IDO2LkmB9ܸ=y=*(njf4$)lPYkdY3*7.a,)&{N-fAHcyã/+k-25l zrP#<+D';nis8gjpaȜba_S#PҊWu
q֤0XJjhٷ%жl8KG*GNSu?&|
\ No newline at end of file
diff --git a/_modules/bench-chain/_.git/objects/ce/2f31dbe3cc7fd583409164acc2ee42c3dc8522 b/_modules/bench-chain/_.git/objects/ce/2f31dbe3cc7fd583409164acc2ee42c3dc8522
new file mode 100644
index 0000000..e8dd1af
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/ce/2f31dbe3cc7fd583409164acc2ee42c3dc8522 differ
diff --git a/_modules/bench-chain/_.git/objects/ce/f91a384008340acb4f699821dc3e2beeab7dec b/_modules/bench-chain/_.git/objects/ce/f91a384008340acb4f699821dc3e2beeab7dec
new file mode 100644
index 0000000..03ee617
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/ce/f91a384008340acb4f699821dc3e2beeab7dec differ
diff --git a/_modules/bench-chain/_.git/objects/cf/b6bed24daaf929ef2e382001b154c9bf876921 b/_modules/bench-chain/_.git/objects/cf/b6bed24daaf929ef2e382001b154c9bf876921
new file mode 100644
index 0000000..57d648e
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/cf/b6bed24daaf929ef2e382001b154c9bf876921 differ
diff --git a/_modules/bench-chain/_.git/objects/d0/31a70113f323110aa2fea5bb90b1946c1c2e72 b/_modules/bench-chain/_.git/objects/d0/31a70113f323110aa2fea5bb90b1946c1c2e72
new file mode 100644
index 0000000..68ec631
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/d0/31a70113f323110aa2fea5bb90b1946c1c2e72 differ
diff --git a/_modules/bench-chain/_.git/objects/d1/9ac2d69fe221d4501e13f252ec29916989f1e9 b/_modules/bench-chain/_.git/objects/d1/9ac2d69fe221d4501e13f252ec29916989f1e9
new file mode 100644
index 0000000..c0e1efb
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/d1/9ac2d69fe221d4501e13f252ec29916989f1e9 differ
diff --git a/_modules/bench-chain/_.git/objects/d2/c3e04d1d22b1e2897bbef30d51285b6da52d27 b/_modules/bench-chain/_.git/objects/d2/c3e04d1d22b1e2897bbef30d51285b6da52d27
new file mode 100644
index 0000000..63ca2d0
--- /dev/null
+++ b/_modules/bench-chain/_.git/objects/d2/c3e04d1d22b1e2897bbef30d51285b6da52d27
@@ -0,0 +1,4 @@
+xAJ@E])
+ĝ:N:-""^SU t(KKs9̀K]Sy`\{jC-Pz]nCDڣNAxڑuMm;1zˍ'ӳc=IF83&b,
+jk{ZZfOVϏ]ws &2B4Ѳ\(U_0-9)
+Cˎ}; >0/f$
\ No newline at end of file
diff --git a/_modules/bench-chain/_.git/objects/d3/ac8bd007f8baea8ed235934e6c85546817825d b/_modules/bench-chain/_.git/objects/d3/ac8bd007f8baea8ed235934e6c85546817825d
new file mode 100644
index 0000000..9428615
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/d3/ac8bd007f8baea8ed235934e6c85546817825d differ
diff --git a/_modules/bench-chain/_.git/objects/d5/f85238044d6a760b503dcd3a793ff622904133 b/_modules/bench-chain/_.git/objects/d5/f85238044d6a760b503dcd3a793ff622904133
new file mode 100644
index 0000000..4e60415
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/d5/f85238044d6a760b503dcd3a793ff622904133 differ
diff --git a/_modules/bench-chain/_.git/objects/d6/4eec8d266e197926baf89465b556cfaff87846 b/_modules/bench-chain/_.git/objects/d6/4eec8d266e197926baf89465b556cfaff87846
new file mode 100644
index 0000000..ef2919d
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/d6/4eec8d266e197926baf89465b556cfaff87846 differ
diff --git a/_modules/bench-chain/_.git/objects/d6/b4836e8698f960e043ee8aaced7fb85448400c b/_modules/bench-chain/_.git/objects/d6/b4836e8698f960e043ee8aaced7fb85448400c
new file mode 100644
index 0000000..86f5f41
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/d6/b4836e8698f960e043ee8aaced7fb85448400c differ
diff --git a/_modules/bench-chain/_.git/objects/d7/a1de2b9586ec592b4ce78e186a295591fd93b8 b/_modules/bench-chain/_.git/objects/d7/a1de2b9586ec592b4ce78e186a295591fd93b8
new file mode 100644
index 0000000..ada11b5
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/d7/a1de2b9586ec592b4ce78e186a295591fd93b8 differ
diff --git a/_modules/bench-chain/_.git/objects/d7/e4f5cb233343d1f307fde774e21e81b32ff824 b/_modules/bench-chain/_.git/objects/d7/e4f5cb233343d1f307fde774e21e81b32ff824
new file mode 100644
index 0000000..d3bc5e4
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/d7/e4f5cb233343d1f307fde774e21e81b32ff824 differ
diff --git a/_modules/bench-chain/_.git/objects/d8/15394dd3606837c2717298d1a2a097deb5a614 b/_modules/bench-chain/_.git/objects/d8/15394dd3606837c2717298d1a2a097deb5a614
new file mode 100644
index 0000000..e5ace08
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/d8/15394dd3606837c2717298d1a2a097deb5a614 differ
diff --git a/_modules/bench-chain/_.git/objects/d8/85ca8c77a6388f7b0c083ce96c4961ffa4adba b/_modules/bench-chain/_.git/objects/d8/85ca8c77a6388f7b0c083ce96c4961ffa4adba
new file mode 100644
index 0000000..1a278e7
--- /dev/null
+++ b/_modules/bench-chain/_.git/objects/d8/85ca8c77a6388f7b0c083ce96c4961ffa4adba
@@ -0,0 +1,2 @@
+xKOR04`H+.Q(I
+EEe\9ԼdI==d<H^I~JzrbBQiBniNIfANBIfnj1PJ:,I鸅C}:Y
\ No newline at end of file
diff --git a/_modules/bench-chain/_.git/objects/db/f6a3b260a07d663339c08ab07ca6acb945ec98 b/_modules/bench-chain/_.git/objects/db/f6a3b260a07d663339c08ab07ca6acb945ec98
new file mode 100644
index 0000000..ef814d4
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/db/f6a3b260a07d663339c08ab07ca6acb945ec98 differ
diff --git a/_modules/bench-chain/_.git/objects/e0/7d47267445630eccf94e29af3464c9d38e7e0b b/_modules/bench-chain/_.git/objects/e0/7d47267445630eccf94e29af3464c9d38e7e0b
new file mode 100644
index 0000000..9e99d78
--- /dev/null
+++ b/_modules/bench-chain/_.git/objects/e0/7d47267445630eccf94e29af3464c9d38e7e0b
@@ -0,0 +1,2 @@
+xOm!7Ul8X^%J`9XǺB
h^*`_`oɛhΡZ:,d
+7gΥԝ Ґ8d(=Zm QCg \&|n7X0`l^SU_m^xl2`IO
\ No newline at end of file
diff --git a/_modules/bench-chain/_.git/objects/e1/5beb36dae46ec81eb4f66bd8bcbb8f50cbfa16 b/_modules/bench-chain/_.git/objects/e1/5beb36dae46ec81eb4f66bd8bcbb8f50cbfa16
new file mode 100644
index 0000000..91e80a2
--- /dev/null
+++ b/_modules/bench-chain/_.git/objects/e1/5beb36dae46ec81eb4f66bd8bcbb8f50cbfa16
@@ -0,0 +1,3 @@
+xiD!Em@h!
[OǍuyυLCZL ]M:84w`c
Cp^
+eG[dC)j]"QKX0p$Kj_Yſ"c!F-9ve
+Gx[)iӥF{m51<#!E)qJ\k}Z=0kqlTP8
\ No newline at end of file
diff --git a/_modules/bench-chain/_.git/objects/e5/87b2689510aa8dd8fe4d4c6d480dcbf67e5674 b/_modules/bench-chain/_.git/objects/e5/87b2689510aa8dd8fe4d4c6d480dcbf67e5674
new file mode 100644
index 0000000..205f258
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/e5/87b2689510aa8dd8fe4d4c6d480dcbf67e5674 differ
diff --git a/_modules/bench-chain/_.git/objects/e6/15b17f40089c32f46c0221fdf5df8682858fb7 b/_modules/bench-chain/_.git/objects/e6/15b17f40089c32f46c0221fdf5df8682858fb7
new file mode 100644
index 0000000..3811539
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/e6/15b17f40089c32f46c0221fdf5df8682858fb7 differ
diff --git a/_modules/bench-chain/_.git/objects/e7/f9f567e026f9ddbd0a70288ea97d0849a5e59b b/_modules/bench-chain/_.git/objects/e7/f9f567e026f9ddbd0a70288ea97d0849a5e59b
new file mode 100644
index 0000000..a17e48f
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/e7/f9f567e026f9ddbd0a70288ea97d0849a5e59b differ
diff --git a/_modules/bench-chain/_.git/objects/ea/a2d12b05cd102e647e2ba752ebe57fd00b483a b/_modules/bench-chain/_.git/objects/ea/a2d12b05cd102e647e2ba752ebe57fd00b483a
new file mode 100644
index 0000000..fb73631
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/ea/a2d12b05cd102e647e2ba752ebe57fd00b483a differ
diff --git a/_modules/bench-chain/_.git/objects/ea/a75fed9d8a9acd292c084b558c68f36eed4647 b/_modules/bench-chain/_.git/objects/ea/a75fed9d8a9acd292c084b558c68f36eed4647
new file mode 100644
index 0000000..aa9d444
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/ea/a75fed9d8a9acd292c084b558c68f36eed4647 differ
diff --git a/_modules/bench-chain/_.git/objects/ec/c206460eb65e19ee341975021c116a4502cf8a b/_modules/bench-chain/_.git/objects/ec/c206460eb65e19ee341975021c116a4502cf8a
new file mode 100644
index 0000000..9c172da
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/ec/c206460eb65e19ee341975021c116a4502cf8a differ
diff --git a/_modules/bench-chain/_.git/objects/ed/5523a824196c4da7ce6c366f0c3f80b218a890 b/_modules/bench-chain/_.git/objects/ed/5523a824196c4da7ce6c366f0c3f80b218a890
new file mode 100644
index 0000000..d1e7a9a
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/ed/5523a824196c4da7ce6c366f0c3f80b218a890 differ
diff --git a/_modules/bench-chain/_.git/objects/ed/d26e97d42667e0fdcc4811f4009a1072c60e32 b/_modules/bench-chain/_.git/objects/ed/d26e97d42667e0fdcc4811f4009a1072c60e32
new file mode 100644
index 0000000..fe17fc0
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/ed/d26e97d42667e0fdcc4811f4009a1072c60e32 differ
diff --git a/_modules/bench-chain/_.git/objects/ef/a440cd6bb5aff0d6bf803c17a04c076111d60b b/_modules/bench-chain/_.git/objects/ef/a440cd6bb5aff0d6bf803c17a04c076111d60b
new file mode 100644
index 0000000..08899b7
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/ef/a440cd6bb5aff0d6bf803c17a04c076111d60b differ
diff --git a/_modules/bench-chain/_.git/objects/f0/0691d5461fb398b051d347307096b4cb282813 b/_modules/bench-chain/_.git/objects/f0/0691d5461fb398b051d347307096b4cb282813
new file mode 100644
index 0000000..fe60c6d
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/f0/0691d5461fb398b051d347307096b4cb282813 differ
diff --git a/_modules/bench-chain/_.git/objects/f1/08b1debdb46c16ec4882c16fda750596b5c273 b/_modules/bench-chain/_.git/objects/f1/08b1debdb46c16ec4882c16fda750596b5c273
new file mode 100644
index 0000000..9d7422e
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/f1/08b1debdb46c16ec4882c16fda750596b5c273 differ
diff --git a/_modules/bench-chain/_.git/objects/f4/145aaf75206aff1e6b66dc387d5fec6f2acb21 b/_modules/bench-chain/_.git/objects/f4/145aaf75206aff1e6b66dc387d5fec6f2acb21
new file mode 100644
index 0000000..b797c37
--- /dev/null
+++ b/_modules/bench-chain/_.git/objects/f4/145aaf75206aff1e6b66dc387d5fec6f2acb21
@@ -0,0 +1,3 @@
+xM
+0F]K
+;=D/Pt&:MB+4ny3ߛ8;cx@
jQaסv4nR
pTg06~`B(|aoh+~4dyiFQKa_a$Vj(W*{
\ No newline at end of file
diff --git a/_modules/bench-chain/_.git/objects/f4/2b17c4f1e5620beeae0ab626ac171b34eca9b3 b/_modules/bench-chain/_.git/objects/f4/2b17c4f1e5620beeae0ab626ac171b34eca9b3
new file mode 100644
index 0000000..c939de9
--- /dev/null
+++ b/_modules/bench-chain/_.git/objects/f4/2b17c4f1e5620beeae0ab626ac171b34eca9b3
@@ -0,0 +1,3 @@
+x+)JMU00`040031QK,L/JeUc0wjҧ+Wͼ(,X27a,MYS{W(_U몗R7lZ*Y('3T5x^h[+e?ow%!D:"1 's
+7u+S{닡$&g'e1ȪU0wVZ7kJ
+7.2Ȗ0UxsP壯V]4u,
\ No newline at end of file
diff --git a/_modules/bench-chain/_.git/objects/f5/33caa50cece3f8b019f5751009a04314d11c05 b/_modules/bench-chain/_.git/objects/f5/33caa50cece3f8b019f5751009a04314d11c05
new file mode 100644
index 0000000..2384bab
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/f5/33caa50cece3f8b019f5751009a04314d11c05 differ
diff --git a/_modules/bench-chain/_.git/objects/f5/430df56a06ba865d70ba0e4c90371b3dd848ab b/_modules/bench-chain/_.git/objects/f5/430df56a06ba865d70ba0e4c90371b3dd848ab
new file mode 100644
index 0000000..3786b40
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/f5/430df56a06ba865d70ba0e4c90371b3dd848ab differ
diff --git a/_modules/bench-chain/_.git/objects/f6/368536bbf5aa3d326368b4b83f1d8cbb8a0eba b/_modules/bench-chain/_.git/objects/f6/368536bbf5aa3d326368b4b83f1d8cbb8a0eba
new file mode 100644
index 0000000..9093ac6
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/f6/368536bbf5aa3d326368b4b83f1d8cbb8a0eba differ
diff --git a/_modules/bench-chain/_.git/objects/f7/875930f132ce238276cd21f7eb96a0bc3b2117 b/_modules/bench-chain/_.git/objects/f7/875930f132ce238276cd21f7eb96a0bc3b2117
new file mode 100644
index 0000000..654abd8
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/f7/875930f132ce238276cd21f7eb96a0bc3b2117 differ
diff --git a/_modules/bench-chain/_.git/objects/f8/fff929d68aad57aed9f751f7d606dda5c24a62 b/_modules/bench-chain/_.git/objects/f8/fff929d68aad57aed9f751f7d606dda5c24a62
new file mode 100644
index 0000000..6133271
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/f8/fff929d68aad57aed9f751f7d606dda5c24a62 differ
diff --git a/_modules/bench-chain/_.git/objects/fa/7c3d52e16d956af975e56d1968a9aa99d0e887 b/_modules/bench-chain/_.git/objects/fa/7c3d52e16d956af975e56d1968a9aa99d0e887
new file mode 100644
index 0000000..e958f6d
--- /dev/null
+++ b/_modules/bench-chain/_.git/objects/fa/7c3d52e16d956af975e56d1968a9aa99d0e887
@@ -0,0 +1,3 @@
+x5n!;)E
+:eN:'|wF.ggozz8l9On;%z>MKf3"F b2)ݓ-SNNhʃR탷в?ꌙ*+n;?Fʨ`d1ŰYHُ5f
+F+pm7ü(7狄̠O"~dVfg,Qrd@!o_S{֮|,ZЀ^ؒl)bUuw%
Q*\
{ZQ
\ No newline at end of file
diff --git a/_modules/bench-chain/_.git/objects/fc/a1b55b0cf0097216dc027d52f86838b058adf9 b/_modules/bench-chain/_.git/objects/fc/a1b55b0cf0097216dc027d52f86838b058adf9
new file mode 100644
index 0000000..3819614
Binary files /dev/null and b/_modules/bench-chain/_.git/objects/fc/a1b55b0cf0097216dc027d52f86838b058adf9 differ
diff --git a/_modules/bench-chain/_.git/objects/fd/a8890cb4056543b1368cf736edd2aa27c6863e b/_modules/bench-chain/_.git/objects/fd/a8890cb4056543b1368cf736edd2aa27c6863e
new file mode 100644
index 0000000..dff44d0
--- /dev/null
+++ b/_modules/bench-chain/_.git/objects/fd/a8890cb4056543b1368cf736edd2aa27c6863e
@@ -0,0 +1 @@
+xQj0DSRdieJKO"V _~r:CayRV4f ?):MNq1OsaV.@RDRL:f4~Yc} Averages
+ * @ typedef {Object} Results
+ */
+
+class CLI extends AppCLI {
+ constructor() {
+ super()
+ this.dir = __dirname
+ this.setup()
+ }
+
+ /**
+ * @TODO remove `@TODO:` apparently doxdox sucks
+ */
+ docs() {
+ super.docs(['src/**/*.js'])
+ }
+
+ /**
+ * @desc writes pkg json
+ * @return {CLI} @chainable
+ */
+ pkg() {
+ pkg
+ .version('0.0.4')
+ .name('bench-chain')
+ .description('benchmark recording - averages & graphs.')
+ .main('src/index')
+ .script('test', `ava --verbose`)
+ .script('docs', `jsdoc`)
+ .dep('benchmark', '2.1.4')
+ .dep('flipfile', '*')
+ .dep('fliplog', '*')
+ .devDep('ava', '*')
+ .devDep('doxdox', '*')
+ .devDep('jsdoc', '3.4.3')
+ .devDep('jsdoc-api', '3.0.0')
+ .devDep('jsdoc-babel', '0.3.0')
+ .devDep('tui-jsdoc-template', '1.1.0')
+ .keywords(['benchmark', 'ui', 'average', 'graph', 'time', 'record'])
+ .author('James ')
+ .license('MIT')
+ .repo('aretecode/bench-chain')
+ .jsdocs({
+ source: {
+ include: ['readme.md', 'src', 'disted'],
+ includePattern: '.+\\.js(doc)?$',
+ },
+ opts: {
+ recurse: true,
+ destination: './jsdocs',
+ template: 'node_modules/tui-jsdoc-template',
+ package: 'package.json',
+ },
+ plugins: ['node_modules/jsdoc-babel', 'plugins/markdown'],
+ })
+ .dir(__dirname)
+ .save()
+ return this
+ }
+}
+
+/**
+ * @desc parses cli arguments to call methods
+ * @example
+ * `node cli --pkg --docs --npm=build,test`
+ */
+new CLI().handle()
diff --git a/_modules/bench-chain/docs/CHANGELOG.md b/_modules/bench-chain/docs/CHANGELOG.md
new file mode 100644
index 0000000..c1ce4ac
--- /dev/null
+++ b/_modules/bench-chain/docs/CHANGELOG.md
@@ -0,0 +1,78 @@
+# 0.5.1
+- ☮️ compatibility: update fliptime with microtime polyfil that prefers microtime dep when it is available and accepts flags when available
+- ℹ️️ add cli --help flag
+- 🚩 add --reasoning as a flag to show math calculations for showing
+- 🏛️% refactor percentage reporting part 3
+ - +- which is faster and slower,
+ - %x whether to use percent or times,
+ - <> whether to flip the values,
+ - .. the digits on the numbers
+- 📘 add examples to display all 4 of those possibilities (since it compares in groups of 2, async and sync)
+- 🔬📝 test todos
+
+# 0.5.0
+- ⛓ put suite in store - breaking
+- 📦⬇ optional deps
+
+# 0.4.4
+- 📊 added current results to not use every single result which can max things out
+- ℹ️️ jsdocs for data adding with Results
+- 🛁 some configstore cleaning in Results
+- ⚒🔢 temp fix for slower/faster numbers
+- 🎀 prettier name for suiteName when using path, prettier objformat
+- 🖼️📦⬇ use mozilla polyfil for padEnd inline, less deps
+- 📈 added reporting of ops, slicing only most recent messages
+- 📜 script running examples
+- %📊 pct report improvements & 🛁 clean!
+- 📘 example of using for just a single benchmark
+
+# 0.4.3
+- 📛 fix tag reporting with referencing parent instead of reporter
+
+# 0.4.2
+- 🌀 fix ending spinner missed timeout alongside the interval
+- ⚙ fix json parsing in obj-chain-plugin-config
+
+# 0.4.1
+
+- 📒🚚 move memory helpers and other data into deps file
+- 📦⬆ added deps (table, some lodash, script-chain for auto-progress, obj-chain for config)
+- 🔬 adding more tests
+- ⚙💽 adding config store
+- 🖼️ add screenshots
+- 🏛️🏰 refactor reporting from Reporter, into
+ - % PercentReporter
+ - 📊 GraphReporter
+ - # TagReporter
+- 🛁 take out avggraphsinone until it works
+- 🌀 add spinner, split into UI
+- 🤸 split BenchChain out of index into a file
+- 🆙📘 examples
+- 🔗 update docs links
+- 👂 add more subscribing methods
+- 👾 simplify some ops
+- ⛓ convert to more chainable store methods
+- 🚩 more cli options
+- ℹ️️ more jsdocs
+
+# 0.4.0
+- ⚒💍 fix async reporting some properties only being added to last cycle, just added to all now (bigger data but simpler code)
+- [...] auto-progress bars
+
+# 0.3.0
+- add name to suite
+- add more fluent
+- add docs for new stuff
+- added percent calc, likely needs improvements
+- more examples
+
+# 0.2.0 🔋⏱⛓📊👾
+- 🔋 battery parsing from plist when available
+- 🔋 battery in benchmark recordings
+- ⏱ microtime in recordings
+- ⛓ extend chainable
+- 📊 format microtime recordings
+- 👾 simplify async benchmarks
+- 🤸 split reports into another class
+- 🔬 fix test folder name and add another super simple basic instantiation test
+- 📈📉 more nice graphs
diff --git a/_modules/bench-chain/docs/docs.md b/_modules/bench-chain/docs/docs.md
new file mode 100644
index 0000000..686e64b
--- /dev/null
+++ b/_modules/bench-chain/docs/docs.md
@@ -0,0 +1,491 @@
+#
+
+
+
+### src/index.js
+
+
+#### flow(funcs)
+
+
+
+
+
+
+##### Parameters
+
+| Name | Type | Description | |
+| ---- | ---- | ----------- | -------- |
+| funcs | `Array.<Function>` | functions to flow left to right | |
+
+
+
+
+##### Returns
+
+
+- `Function` passes args through the functions, bound to this
+
+
+
+#### module.exports()
+
+
+
+
+
+
+
+
+##### Returns
+
+
+- `Void`
+
+
+
+#### formatNumber(number)
+
+Converts a number to a more readable comma-separated string representation.
+
+
+
+
+##### Parameters
+
+| Name | Type | Description | |
+| ---- | ---- | ----------- | -------- |
+| number | `number` | The number to convert. | |
+
+
+
+
+##### Returns
+
+
+- `string` The more readable string representation.
+
+
+
+#### constructor(dir)
+
+
+
+
+
+
+##### Parameters
+
+| Name | Type | Description | |
+| ---- | ---- | ----------- | -------- |
+| dir | `string` | directory for the file with the record | |
+
+
+
+
+##### Returns
+
+
+- `Void`
+
+
+
+#### cycle(event) *private method*
+
+
+
+
+
+
+##### Parameters
+
+| Name | Type | Description | |
+| ---- | ---- | ----------- | -------- |
+| event | `Benchmark.Event` | | |
+
+
+
+
+##### Returns
+
+
+- `Record` @chainable
+
+
+
+#### filename()
+
+
+
+
+
+
+##### Parameters
+
+| Name | Type | Description | |
+| ---- | ---- | ----------- | -------- |
+| filename='./results.json' | `String` | | *Optional* |
+
+
+
+
+##### Returns
+
+
+- `Record` @chainable
+
+
+
+#### load([force=false])
+
+
+
+
+
+
+##### Parameters
+
+| Name | Type | Description | |
+| ---- | ---- | ----------- | -------- |
+| force=false | `Boolean` | force reload | *Optional* |
+
+
+
+
+##### Returns
+
+
+- `Record` @chainable
+
+
+
+#### save()
+
+
+
+
+
+
+
+
+##### Returns
+
+
+- `Record` @chainable
+
+
+
+#### getDiv(max)
+
+
+
+
+
+
+##### Parameters
+
+| Name | Type | Description | |
+| ---- | ---- | ----------- | -------- |
+| max | `number` | | |
+
+
+
+
+##### Returns
+
+
+- `number`
+
+
+
+#### trend()
+
+
+
+
+
+
+
+
+##### Returns
+
+
+- `Object.<points, max, min>` trend graph data
+
+
+
+#### avgs(prop)
+
+
+
+
+
+
+##### Parameters
+
+| Name | Type | Description | |
+| ---- | ---- | ----------- | -------- |
+| prop | `string` | map to this property to average with that data | |
+
+
+
+
+##### Returns
+
+
+- `Averages` averages
+
+
+
+#### avg(data)
+
+
+
+
+
+
+##### Parameters
+
+| Name | Type | Description | |
+| ---- | ---- | ----------- | -------- |
+| data | `Array.<number>` | | |
+
+
+
+
+##### Returns
+
+
+- `number` average
+
+
+
+#### fastest()
+
+
+
+
+
+
+
+
+##### Returns
+
+
+- `Array.<string>` test case name
+
+
+
+#### echoAvgs()
+
+
+
+
+
+
+
+
+##### Returns
+
+
+- `Record` @chainable
+
+
+
+#### echoFastest()
+
+
+
+
+
+
+
+
+##### Returns
+
+
+- `Record` @chainable
+
+
+
+#### echoTrend()
+
+
+
+
+
+
+
+
+##### Returns
+
+
+- `Record` @chainable
+
+
+
+#### suite(dir[, auto=false])
+
+
+
+
+
+
+##### Parameters
+
+| Name | Type | Description | |
+| ---- | ---- | ----------- | -------- |
+| dir | `string` | | |
+| auto=false | `Boolean` | | *Optional* |
+
+
+
+
+##### Returns
+
+
+- `Object` {suite, record}
+
+
+
+#### suite([auto=false])
+
+
+
+
+
+
+##### Parameters
+
+| Name | Type | Description | |
+| ---- | ---- | ----------- | -------- |
+| auto=false | `Boolean` | | *Optional* |
+
+
+
+
+##### Returns
+
+
+- `Benchmark.Suite`
+
+
+
+#### setup([auto=true])
+
+
+
+
+
+
+##### Parameters
+
+| Name | Type | Description | |
+| ---- | ---- | ----------- | -------- |
+| auto=true | `Boolean` | automatically sets up echoing and saving | *Optional* |
+
+
+
+
+##### Returns
+
+
+- `Record` @chainable
+
+
+
+#### add(name, cb)
+
+
+
+
+
+
+##### Parameters
+
+| Name | Type | Description | |
+| ---- | ---- | ----------- | -------- |
+| name | `string` | | |
+| cb | `Function` | | |
+
+
+
+
+##### Returns
+
+
+- `Record` @chainable
+
+
+
+#### run(async)
+
+
+
+
+
+
+##### Parameters
+
+| Name | Type | Description | |
+| ---- | ---- | ----------- | -------- |
+| async | `boolean` | | |
+
+
+
+
+##### Returns
+
+
+- `Record` @chainable
+
+
+
+#### runAsync(async)
+
+
+
+
+
+
+##### Parameters
+
+| Name | Type | Description | |
+| ---- | ---- | ----------- | -------- |
+| async | `boolean` | | |
+
+
+
+
+##### Returns
+
+
+- `Record` @chainable
+
+
+
+#### runTimes([times=10])
+
+
+
+
+
+
+##### Parameters
+
+| Name | Type | Description | |
+| ---- | ---- | ----------- | -------- |
+| times=10 | `Number` | | *Optional* |
+
+
+
+
+##### Returns
+
+
+- `Record` @chainable
+
+
+
+
+*Documentation generated with [doxdox](https://github.com/neogeek/doxdox).*
diff --git a/_modules/bench-chain/docs/todo.md b/_modules/bench-chain/docs/todo.md
new file mode 100644
index 0000000..2ba3e52
--- /dev/null
+++ b/_modules/bench-chain/docs/todo.md
@@ -0,0 +1,10 @@
+## 📝 todo
+https://gist.github.com/springmeyer/a67d8d77057d30fc4bbe
+https://mathiasbynens.be/notes/javascript-benchmarking
+https://github.com/JamieMason/karma-benchmark/blob/master/src/run-benchmarks.js
+https://github.com/avajs/ava/issues/816
+https://github.com/avajs/ava/blob/master/bench/compare.js
+https://benchmarkjs.com/docs#prototype_compare
+https://github.com/ngryman/speedracer
+https://esbench.com/bench/5908b65d99634800a0347e7b
+https://github.com/logicalparadox/matcha
diff --git a/_modules/bench-chain/example/asyncs.js b/_modules/bench-chain/example/asyncs.js
new file mode 100644
index 0000000..591006a
--- /dev/null
+++ b/_modules/bench-chain/example/asyncs.js
@@ -0,0 +1,30 @@
+const Bench = require('../')
+
+const sleep = sleepDuration =>
+ new Promise(resolve => setTimeout(resolve, sleepDuration))
+
+/* prettier-ignore */
+
+Bench
+ .init().dir(__dirname).filename('asyncs4.json').setup()
+ .name('sleepy4')
+ .tags('fresh,MORETAGS,uniqd,4th')
+
+ // can also use .add, and then .runAsync()
+ .addAsync('sleep1', async done => {
+ await sleep(100)
+ done()
+ })
+ .addAsync('sleep2', async done => {
+ await sleep(200)
+ done()
+ })
+ .addAsync('sleep3', async done => {
+ await sleep(300)
+ done()
+ })
+ .addAsync('sleep200 4', async done => {
+ await sleep(200)
+ done()
+ })
+ .run()
diff --git a/_modules/bench-chain/example/asyncs4.json b/_modules/bench-chain/example/asyncs4.json
new file mode 100644
index 0000000..6dcefdd
--- /dev/null
+++ b/_modules/bench-chain/example/asyncs4.json
@@ -0,0 +1 @@
+{"sleepy4":{"sleep1":[{"msg":"sleep1 x 9.76 ops/sec ±0.47% (49 runs sampled)","name":"sleep1","num":9.76,"sampled":"49","variation":"0.47","tags":"fresh,MORETAGS,uniqd,4th","suite":["sleepy4"],"timesFor":[{"start":1494204471268098,"end":1494204471373603,"diff":105505},{"start":1494204471394560,"end":1494204471497737,"diff":103177},{"start":1494204471519708,"end":1494204471622557,"diff":102849},{"start":1494204471639938,"end":1494204471741405,"diff":101467},{"start":1494204471761198,"end":1494204471863776,"diff":102578},{"start":1494204471882745,"end":1494204471987578,"diff":104833},{"start":1494204472009888,"end":1494204472112742,"diff":102854},{"start":1494204472132133,"end":1494204472236077,"diff":103944},{"start":1494204472257969,"end":1494204472362478,"diff":104509},{"start":1494204472379027,"end":1494204472482899,"diff":103872},{"start":1494204472500432,"end":1494204472602118,"diff":101686},{"start":1494204472621015,"end":1494204472723893,"diff":102878},{"start":1494204472742762,"end":1494204472844426,"diff":101664},{"start":1494204472860617,"end":1494204472960844,"diff":100227},{"start":1494204472978809,"end":1494204473082129,"diff":103320},{"start":1494204473099885,"end":1494204473200841,"diff":100956},{"start":1494204473219106,"end":1494204473323673,"diff":104567},{"start":1494204473341339,"end":1494204473442081,"diff":100742},{"start":1494204473460727,"end":1494204473560987,"diff":100260},{"start":1494204473577889,"end":1494204473680150,"diff":102261},{"start":1494204473697091,"end":1494204473798058,"diff":100967},{"start":1494204473815775,"end":1494204473919003,"diff":103228},{"start":1494204473936805,"end":1494204474040003,"diff":103198},{"start":1494204474056410,"end":1494204474161911,"diff":105501},{"start":1494204474179661,"end":1494204474281934,"diff":102273},{"start":1494204474304933,"end":1494204474410164,"diff":105231},{"start":1494204474426639,"end":1494204474526232,"diff":99593},{"start":1494204474543893,"end":1494204474644914,"diff":101021},{"start":1494204474664872,"end":1494204474765522,"diff":100650},{"start":1494204474783946,"end":1494204474885494,"diff":101548},{"start":1494204474904359,"end":1494204475004794,"diff":100435},{"start":1494204475022485,"end":1494204475124911,"diff":102426},{"start":1494204475141172,"end":1494204475241651,"diff":100479},{"start":1494204475257140,"end":1494204475361367,"diff":104227},{"start":1494204475377407,"end":1494204475477392,"diff":99985},{"start":1494204475495939,"end":1494204475601396,"diff":105457},{"start":1494204475618999,"end":1494204475723246,"diff":104247},{"start":1494204475739899,"end":1494204475840541,"diff":100642},{"start":1494204475860856,"end":1494204475963032,"diff":102176},{"start":1494204475979928,"end":1494204476083363,"diff":103435},{"start":1494204476099031,"end":1494204476199519,"diff":100488},{"start":1494204476217073,"end":1494204476318768,"diff":101695},{"start":1494204476336202,"end":1494204476437015,"diff":100813},{"start":1494204476455491,"end":1494204476555185,"diff":99694},{"start":1494204476574805,"end":1494204476675349,"diff":100544},{"start":1494204476691964,"end":1494204476794062,"diff":102098},{"start":1494204476811075,"end":1494204476916414,"diff":105339},{"start":1494204476934807,"end":1494204477036934,"diff":102127},{"start":1494204477055173,"end":1494204477157122,"diff":101949}],"now":1494204477163,"mem":{"start":{"process":{"rss":51810304,"heapTotal":29458432,"heapUsed":22156664,"external":123168},"os":261259264},"end":{"process":{"rss":64020480,"heapTotal":41701376,"heapUsed":29454272,"external":25668},"os":330092544}},"stats":{"moe":0.00048409403721453404,"rme":0.472507761189545,"sem":0.0002469867536808847,"deviation":0.001728907275766193,"mean":0.10245208163265306,"sample":[0.105796,0.103367,0.102967,0.101604,0.102643,0.104901,0.102945,0.104009,0.104652,0.103982,0.101753,0.102974,0.101747,0.10035,0.103405,0.101031,0.104648,0.10083,0.100343,0.10233,0.101042,0.103293,0.103306,0.105618,0.102364,0.105317,0.099749,0.101125,0.100741,0.101639,0.100526,0.102513,0.100542,0.1043,0.100046,0.10552,0.104319,0.100728,0.102248,0.103516,0.100545,0.10176,0.100884,0.09978,0.100614,0.102177,0.105409,0.102226,0.102028],"variance":0.0000029891203681972796},"count":1,"hz":9.760660633383212,"time":102.45208163265306,"cycles":1,"battery":{"amperage":-2340,"currentCapacity":516,"percent":6,"charging":"","temp":3108}},{"msg":"sleep1 x 9.76 ops/sec ±0.47% (49 runs sampled)","name":"sleep1","num":9.76,"sampled":"49","variation":"0.47","tags":"fresh,MORETAGS,uniqd,4th","suite":["sleepy4"],"timesFor":[{"start":1494204471268098,"end":1494204471373603,"diff":105505},{"start":1494204471394560,"end":1494204471497737,"diff":103177},{"start":1494204471519708,"end":1494204471622557,"diff":102849},{"start":1494204471639938,"end":1494204471741405,"diff":101467},{"start":1494204471761198,"end":1494204471863776,"diff":102578},{"start":1494204471882745,"end":1494204471987578,"diff":104833},{"start":1494204472009888,"end":1494204472112742,"diff":102854},{"start":1494204472132133,"end":1494204472236077,"diff":103944},{"start":1494204472257969,"end":1494204472362478,"diff":104509},{"start":1494204472379027,"end":1494204472482899,"diff":103872},{"start":1494204472500432,"end":1494204472602118,"diff":101686},{"start":1494204472621015,"end":1494204472723893,"diff":102878},{"start":1494204472742762,"end":1494204472844426,"diff":101664},{"start":1494204472860617,"end":1494204472960844,"diff":100227},{"start":1494204472978809,"end":1494204473082129,"diff":103320},{"start":1494204473099885,"end":1494204473200841,"diff":100956},{"start":1494204473219106,"end":1494204473323673,"diff":104567},{"start":1494204473341339,"end":1494204473442081,"diff":100742},{"start":1494204473460727,"end":1494204473560987,"diff":100260},{"start":1494204473577889,"end":1494204473680150,"diff":102261},{"start":1494204473697091,"end":1494204473798058,"diff":100967},{"start":1494204473815775,"end":1494204473919003,"diff":103228},{"start":1494204473936805,"end":1494204474040003,"diff":103198},{"start":1494204474056410,"end":1494204474161911,"diff":105501},{"start":1494204474179661,"end":1494204474281934,"diff":102273},{"start":1494204474304933,"end":1494204474410164,"diff":105231},{"start":1494204474426639,"end":1494204474526232,"diff":99593},{"start":1494204474543893,"end":1494204474644914,"diff":101021},{"start":1494204474664872,"end":1494204474765522,"diff":100650},{"start":1494204474783946,"end":1494204474885494,"diff":101548},{"start":1494204474904359,"end":1494204475004794,"diff":100435},{"start":1494204475022485,"end":1494204475124911,"diff":102426},{"start":1494204475141172,"end":1494204475241651,"diff":100479},{"start":1494204475257140,"end":1494204475361367,"diff":104227},{"start":1494204475377407,"end":1494204475477392,"diff":99985},{"start":1494204475495939,"end":1494204475601396,"diff":105457},{"start":1494204475618999,"end":1494204475723246,"diff":104247},{"start":1494204475739899,"end":1494204475840541,"diff":100642},{"start":1494204475860856,"end":1494204475963032,"diff":102176},{"start":1494204475979928,"end":1494204476083363,"diff":103435},{"start":1494204476099031,"end":1494204476199519,"diff":100488},{"start":1494204476217073,"end":1494204476318768,"diff":101695},{"start":1494204476336202,"end":1494204476437015,"diff":100813},{"start":1494204476455491,"end":1494204476555185,"diff":99694},{"start":1494204476574805,"end":1494204476675349,"diff":100544},{"start":1494204476691964,"end":1494204476794062,"diff":102098},{"start":1494204476811075,"end":1494204476916414,"diff":105339},{"start":1494204476934807,"end":1494204477036934,"diff":102127},{"start":1494204477055173,"end":1494204477157122,"diff":101949}],"now":1494204477164,"mem":{"start":{"process":{"rss":51810304,"heapTotal":29458432,"heapUsed":22156664,"external":123168},"os":261259264},"end":{"process":{"rss":64045056,"heapTotal":41701376,"heapUsed":29482272,"external":25668},"os":330092544}},"stats":{"moe":0.00048409403721453404,"rme":0.472507761189545,"sem":0.0002469867536808847,"deviation":0.001728907275766193,"mean":0.10245208163265306,"sample":[0.105796,0.103367,0.102967,0.101604,0.102643,0.104901,0.102945,0.104009,0.104652,0.103982,0.101753,0.102974,0.101747,0.10035,0.103405,0.101031,0.104648,0.10083,0.100343,0.10233,0.101042,0.103293,0.103306,0.105618,0.102364,0.105317,0.099749,0.101125,0.100741,0.101639,0.100526,0.102513,0.100542,0.1043,0.100046,0.10552,0.104319,0.100728,0.102248,0.103516,0.100545,0.10176,0.100884,0.09978,0.100614,0.102177,0.105409,0.102226,0.102028],"variance":0.0000029891203681972796},"count":1,"hz":9.760660633383212,"time":102.45208163265306,"cycles":1,"battery":{"amperage":-2340,"currentCapacity":516,"percent":6,"charging":"","temp":3108}},{"msg":"sleep1 x 9.72 ops/sec ±0.46% (49 runs sampled)","name":"sleep1","num":9.72,"sampled":"49","variation":"0.46","tags":"fresh,MORETAGS,uniqd,4th","suite":["sleepy4"],"timesFor":[{"start":1494204494802418,"end":1494204494907165,"diff":104747},{"start":1494204494929686,"end":1494204495034123,"diff":104437},{"start":1494204495057248,"end":1494204495158266,"diff":101018},{"start":1494204495178864,"end":1494204495282184,"diff":103320},{"start":1494204495299738,"end":1494204495401533,"diff":101795},{"start":1494204495422651,"end":1494204495524000,"diff":101349},{"start":1494204495545319,"end":1494204495646582,"diff":101263},{"start":1494204495669410,"end":1494204495772939,"diff":103529},{"start":1494204495789960,"end":1494204495894298,"diff":104338},{"start":1494204495911144,"end":1494204496016511,"diff":105367},{"start":1494204496033358,"end":1494204496137536,"diff":104178},{"start":1494204496156452,"end":1494204496261357,"diff":104905},{"start":1494204496279402,"end":1494204496382783,"diff":103381},{"start":1494204496399199,"end":1494204496504624,"diff":105425},{"start":1494204496521080,"end":1494204496626357,"diff":105277},{"start":1494204496645415,"end":1494204496748215,"diff":102800},{"start":1494204496768483,"end":1494204496868689,"diff":100206},{"start":1494204496886603,"end":1494204496986320,"diff":99717},{"start":1494204497002688,"end":1494204497106061,"diff":103373},{"start":1494204497122638,"end":1494204497223885,"diff":101247},{"start":1494204497246158,"end":1494204497348173,"diff":102015},{"start":1494204497366935,"end":1494204497468330,"diff":101395},{"start":1494204497484030,"end":1494204497588213,"diff":104183},{"start":1494204497605542,"end":1494204497706329,"diff":100787},{"start":1494204497722225,"end":1494204497822361,"diff":100136},{"start":1494204497838846,"end":1494204497939122,"diff":100276},{"start":1494204497957508,"end":1494204498059463,"diff":101955},{"start":1494204498076836,"end":1494204498178592,"diff":101756},{"start":1494204498197673,"end":1494204498299180,"diff":101507},{"start":1494204498313878,"end":1494204498417382,"diff":103504},{"start":1494204498435961,"end":1494204498538201,"diff":102240},{"start":1494204498555344,"end":1494204498657907,"diff":102563},{"start":1494204498674527,"end":1494204498779070,"diff":104543},{"start":1494204498798874,"end":1494204498901195,"diff":102321},{"start":1494204498918730,"end":1494204499023716,"diff":104986},{"start":1494204499042302,"end":1494204499146409,"diff":104107},{"start":1494204499166617,"end":1494204499267615,"diff":100998},{"start":1494204499284243,"end":1494204499388773,"diff":104530},{"start":1494204499408782,"end":1494204499511410,"diff":102628},{"start":1494204499529983,"end":1494204499631393,"diff":101410},{"start":1494204499651231,"end":1494204499755124,"diff":103893},{"start":1494204499772408,"end":1494204499873978,"diff":101570},{"start":1494204499891095,"end":1494204499996432,"diff":105337},{"start":1494204500014571,"end":1494204500115196,"diff":100625},{"start":1494204500133782,"end":1494204500237065,"diff":103283},{"start":1494204500253537,"end":1494204500353250,"diff":99713},{"start":1494204500370007,"end":1494204500472552,"diff":102545},{"start":1494204500490419,"end":1494204500594978,"diff":104559},{"start":1494204500614923,"end":1494204500718722,"diff":103799}],"now":1494204500725,"mem":{"start":{"process":{"rss":52060160,"heapTotal":29458432,"heapUsed":22363008,"external":123168},"os":344244224},"end":{"process":{"rss":65359872,"heapTotal":42225664,"heapUsed":23294880,"external":25668},"os":338132992}},"stats":{"moe":0.0004732180863920675,"rme":0.46008554843848953,"sem":0.00024143779917962628,"deviation":0.001690064594257384,"mean":0.10285436871428569,"sample":[0.105062805,0.104602891,0.101143964,0.103456317,0.101867854,0.101488447,0.101347033,0.103605456,0.104491152,0.105455248,0.104276352,0.105024849,0.103447747,0.10550749,0.105360741,0.102926404,0.100301654,0.099791227,0.103470561,0.101313948,0.102117578,0.101490833,0.104255065,0.10086191,0.100205544,0.100394475,0.102104484,0.101853861,0.101581945,0.10360007,0.102322362,0.102656423,0.104637407,0.102423418,0.105066319,0.104229167,0.101076526,0.104635933,0.102710991,0.101498342,0.104027785,0.101733347,0.105418349,0.100693966,0.103373491,0.099786534,0.102625825,0.104643568,0.103896409],"variance":0.000002856318332762376},"count":1,"hz":9.722484445729796,"time":102.85436871428568,"cycles":1,"battery":{"amperage":-2451,"currentCapacity":475,"percent":6,"charging":"","temp":3108}},{"msg":"sleep1 x 9.72 ops/sec ±0.46% (49 runs sampled)","name":"sleep1","num":9.72,"sampled":"49","variation":"0.46","tags":"fresh,MORETAGS,uniqd,4th","suite":["sleepy4"],"timesFor":[{"start":1494204494802418,"end":1494204494907165,"diff":104747},{"start":1494204494929686,"end":1494204495034123,"diff":104437},{"start":1494204495057248,"end":1494204495158266,"diff":101018},{"start":1494204495178864,"end":1494204495282184,"diff":103320},{"start":1494204495299738,"end":1494204495401533,"diff":101795},{"start":1494204495422651,"end":1494204495524000,"diff":101349},{"start":1494204495545319,"end":1494204495646582,"diff":101263},{"start":1494204495669410,"end":1494204495772939,"diff":103529},{"start":1494204495789960,"end":1494204495894298,"diff":104338},{"start":1494204495911144,"end":1494204496016511,"diff":105367},{"start":1494204496033358,"end":1494204496137536,"diff":104178},{"start":1494204496156452,"end":1494204496261357,"diff":104905},{"start":1494204496279402,"end":1494204496382783,"diff":103381},{"start":1494204496399199,"end":1494204496504624,"diff":105425},{"start":1494204496521080,"end":1494204496626357,"diff":105277},{"start":1494204496645415,"end":1494204496748215,"diff":102800},{"start":1494204496768483,"end":1494204496868689,"diff":100206},{"start":1494204496886603,"end":1494204496986320,"diff":99717},{"start":1494204497002688,"end":1494204497106061,"diff":103373},{"start":1494204497122638,"end":1494204497223885,"diff":101247},{"start":1494204497246158,"end":1494204497348173,"diff":102015},{"start":1494204497366935,"end":1494204497468330,"diff":101395},{"start":1494204497484030,"end":1494204497588213,"diff":104183},{"start":1494204497605542,"end":1494204497706329,"diff":100787},{"start":1494204497722225,"end":1494204497822361,"diff":100136},{"start":1494204497838846,"end":1494204497939122,"diff":100276},{"start":1494204497957508,"end":1494204498059463,"diff":101955},{"start":1494204498076836,"end":1494204498178592,"diff":101756},{"start":1494204498197673,"end":1494204498299180,"diff":101507},{"start":1494204498313878,"end":1494204498417382,"diff":103504},{"start":1494204498435961,"end":1494204498538201,"diff":102240},{"start":1494204498555344,"end":1494204498657907,"diff":102563},{"start":1494204498674527,"end":1494204498779070,"diff":104543},{"start":1494204498798874,"end":1494204498901195,"diff":102321},{"start":1494204498918730,"end":1494204499023716,"diff":104986},{"start":1494204499042302,"end":1494204499146409,"diff":104107},{"start":1494204499166617,"end":1494204499267615,"diff":100998},{"start":1494204499284243,"end":1494204499388773,"diff":104530},{"start":1494204499408782,"end":1494204499511410,"diff":102628},{"start":1494204499529983,"end":1494204499631393,"diff":101410},{"start":1494204499651231,"end":1494204499755124,"diff":103893},{"start":1494204499772408,"end":1494204499873978,"diff":101570},{"start":1494204499891095,"end":1494204499996432,"diff":105337},{"start":1494204500014571,"end":1494204500115196,"diff":100625},{"start":1494204500133782,"end":1494204500237065,"diff":103283},{"start":1494204500253537,"end":1494204500353250,"diff":99713},{"start":1494204500370007,"end":1494204500472552,"diff":102545},{"start":1494204500490419,"end":1494204500594978,"diff":104559},{"start":1494204500614923,"end":1494204500718722,"diff":103799}],"now":1494204500725,"mem":{"start":{"process":{"rss":52060160,"heapTotal":29458432,"heapUsed":22363008,"external":123168},"os":344244224},"end":{"process":{"rss":65376256,"heapTotal":42225664,"heapUsed":23322936,"external":25668},"os":338132992}},"stats":{"moe":0.0004732180863920675,"rme":0.46008554843848953,"sem":0.00024143779917962628,"deviation":0.001690064594257384,"mean":0.10285436871428569,"sample":[0.105062805,0.104602891,0.101143964,0.103456317,0.101867854,0.101488447,0.101347033,0.103605456,0.104491152,0.105455248,0.104276352,0.105024849,0.103447747,0.10550749,0.105360741,0.102926404,0.100301654,0.099791227,0.103470561,0.101313948,0.102117578,0.101490833,0.104255065,0.10086191,0.100205544,0.100394475,0.102104484,0.101853861,0.101581945,0.10360007,0.102322362,0.102656423,0.104637407,0.102423418,0.105066319,0.104229167,0.101076526,0.104635933,0.102710991,0.101498342,0.104027785,0.101733347,0.105418349,0.100693966,0.103373491,0.099786534,0.102625825,0.104643568,0.103896409],"variance":0.000002856318332762376},"count":1,"hz":9.722484445729796,"time":102.85436871428568,"cycles":1,"battery":{"amperage":-2451,"currentCapacity":475,"percent":6,"charging":"","temp":3108}},{"msg":"sleep1 x 9.73 ops/sec ±0.50% (48 runs sampled)","name":"sleep1","num":9.73,"sampled":"48","variation":"0.50","tags":"fresh,MORETAGS,uniqd,4th","suite":["sleepy4"],"timesFor":[{"start":1494204658136021,"end":1494204658241665,"diff":105644},{"start":1494204658268862,"end":1494204658369271,"diff":100409},{"start":1494204658394525,"end":1494204658494792,"diff":100267},{"start":1494204658522146,"end":1494204658626531,"diff":104385},{"start":1494204658649670,"end":1494204658751656,"diff":101986},{"start":1494204658773960,"end":1494204658878568,"diff":104608},{"start":1494204658905482,"end":1494204659006619,"diff":101137},{"start":1494204659026340,"end":1494204659130661,"diff":104321},{"start":1494204659149458,"end":1494204659251003,"diff":101545},{"start":1494204659269322,"end":1494204659374193,"diff":104871},{"start":1494204659393407,"end":1494204659494937,"diff":101530},{"start":1494204659512632,"end":1494204659612177,"diff":99545},{"start":1494204659628150,"end":1494204659728750,"diff":100600},{"start":1494204659743894,"end":1494204659848160,"diff":104266},{"start":1494204659863761,"end":1494204659966736,"diff":102975},{"start":1494204659984065,"end":1494204660088553,"diff":104488},{"start":1494204660105407,"end":1494204660206080,"diff":100673},{"start":1494204660223633,"end":1494204660326682,"diff":103049},{"start":1494204660344213,"end":1494204660448456,"diff":104243},{"start":1494204660468846,"end":1494204660570279,"diff":101433},{"start":1494204660591852,"end":1494204660692663,"diff":100811},{"start":1494204660710594,"end":1494204660810791,"diff":100197},{"start":1494204660830574,"end":1494204660930427,"diff":99853},{"start":1494204660948540,"end":1494204661048004,"diff":99464},{"start":1494204661066437,"end":1494204661168250,"diff":101813},{"start":1494204661187620,"end":1494204661292588,"diff":104968},{"start":1494204661331510,"end":1494204661435152,"diff":103642},{"start":1494204661454259,"end":1494204661557059,"diff":102800},{"start":1494204661577405,"end":1494204661679047,"diff":101642},{"start":1494204661699233,"end":1494204661800998,"diff":101765},{"start":1494204661819200,"end":1494204661922772,"diff":103572},{"start":1494204661942075,"end":1494204662042633,"diff":100558},{"start":1494204662064961,"end":1494204662170454,"diff":105493},{"start":1494204662192737,"end":1494204662293103,"diff":100366},{"start":1494204662313368,"end":1494204662417698,"diff":104330},{"start":1494204662437880,"end":1494204662542638,"diff":104758},{"start":1494204662564676,"end":1494204662668766,"diff":104090},{"start":1494204662688578,"end":1494204662789394,"diff":100816},{"start":1494204662810444,"end":1494204662913072,"diff":102628},{"start":1494204662933061,"end":1494204663037600,"diff":104539},{"start":1494204663060407,"end":1494204663165009,"diff":104602},{"start":1494204663185301,"end":1494204663286857,"diff":101556},{"start":1494204663305489,"end":1494204663409091,"diff":103602},{"start":1494204663427382,"end":1494204663530765,"diff":103383},{"start":1494204663549838,"end":1494204663652920,"diff":103082},{"start":1494204663673866,"end":1494204663774625,"diff":100759},{"start":1494204663792490,"end":1494204663896534,"diff":104044},{"start":1494204663915452,"end":1494204664018264,"diff":102812}],"now":1494204664024,"mem":{"start":{"process":{"rss":51458048,"heapTotal":29982720,"heapUsed":22320128,"external":123168},"os":562667520},"end":{"process":{"rss":66228224,"heapTotal":41701376,"heapUsed":24614232,"external":25668},"os":489988096}},"stats":{"moe":0.0005138664910303965,"rme":0.5002177234292917,"sem":0.0002621767811379574,"deviation":0.0018164140219832316,"mean":0.10272856537499998,"sample":[0.106148468,0.100621313,0.100542061,0.104609159,0.102078686,0.104701639,0.101230642,0.104422198,0.101688888,0.104957871,0.101610069,0.099606952,0.100661388,0.104386423,0.103047251,0.104561699,0.100751721,0.103121506,0.104344757,0.10154,0.100930473,0.100304352,0.099959974,0.099609868,0.101916889,0.105081176,0.104199312,0.102920303,0.101748988,0.101929656,0.103728967,0.100745131,0.10568775,0.100546743,0.104479539,0.105200191,0.104203271,0.100918233,0.102778007,0.104665756,0.104707151,0.101708167,0.103704513,0.103496256,0.103195007,0.100876731,0.104163421,0.102932622],"variance":0.0000032993598992573},"count":1,"hz":9.734390783611195,"time":102.72856537499999,"cycles":1,"battery":{"amperage":-2112,"currentCapacity":417,"percent":5,"charging":"","temp":3108}},{"msg":"sleep1 x 9.73 ops/sec ±0.50% (48 runs sampled)","name":"sleep1","num":9.73,"sampled":"48","variation":"0.50","tags":"fresh,MORETAGS,uniqd,4th","suite":["sleepy4"],"timesFor":[{"start":1494204658136021,"end":1494204658241665,"diff":105644},{"start":1494204658268862,"end":1494204658369271,"diff":100409},{"start":1494204658394525,"end":1494204658494792,"diff":100267},{"start":1494204658522146,"end":1494204658626531,"diff":104385},{"start":1494204658649670,"end":1494204658751656,"diff":101986},{"start":1494204658773960,"end":1494204658878568,"diff":104608},{"start":1494204658905482,"end":1494204659006619,"diff":101137},{"start":1494204659026340,"end":1494204659130661,"diff":104321},{"start":1494204659149458,"end":1494204659251003,"diff":101545},{"start":1494204659269322,"end":1494204659374193,"diff":104871},{"start":1494204659393407,"end":1494204659494937,"diff":101530},{"start":1494204659512632,"end":1494204659612177,"diff":99545},{"start":1494204659628150,"end":1494204659728750,"diff":100600},{"start":1494204659743894,"end":1494204659848160,"diff":104266},{"start":1494204659863761,"end":1494204659966736,"diff":102975},{"start":1494204659984065,"end":1494204660088553,"diff":104488},{"start":1494204660105407,"end":1494204660206080,"diff":100673},{"start":1494204660223633,"end":1494204660326682,"diff":103049},{"start":1494204660344213,"end":1494204660448456,"diff":104243},{"start":1494204660468846,"end":1494204660570279,"diff":101433},{"start":1494204660591852,"end":1494204660692663,"diff":100811},{"start":1494204660710594,"end":1494204660810791,"diff":100197},{"start":1494204660830574,"end":1494204660930427,"diff":99853},{"start":1494204660948540,"end":1494204661048004,"diff":99464},{"start":1494204661066437,"end":1494204661168250,"diff":101813},{"start":1494204661187620,"end":1494204661292588,"diff":104968},{"start":1494204661331510,"end":1494204661435152,"diff":103642},{"start":1494204661454259,"end":1494204661557059,"diff":102800},{"start":1494204661577405,"end":1494204661679047,"diff":101642},{"start":1494204661699233,"end":1494204661800998,"diff":101765},{"start":1494204661819200,"end":1494204661922772,"diff":103572},{"start":1494204661942075,"end":1494204662042633,"diff":100558},{"start":1494204662064961,"end":1494204662170454,"diff":105493},{"start":1494204662192737,"end":1494204662293103,"diff":100366},{"start":1494204662313368,"end":1494204662417698,"diff":104330},{"start":1494204662437880,"end":1494204662542638,"diff":104758},{"start":1494204662564676,"end":1494204662668766,"diff":104090},{"start":1494204662688578,"end":1494204662789394,"diff":100816},{"start":1494204662810444,"end":1494204662913072,"diff":102628},{"start":1494204662933061,"end":1494204663037600,"diff":104539},{"start":1494204663060407,"end":1494204663165009,"diff":104602},{"start":1494204663185301,"end":1494204663286857,"diff":101556},{"start":1494204663305489,"end":1494204663409091,"diff":103602},{"start":1494204663427382,"end":1494204663530765,"diff":103383},{"start":1494204663549838,"end":1494204663652920,"diff":103082},{"start":1494204663673866,"end":1494204663774625,"diff":100759},{"start":1494204663792490,"end":1494204663896534,"diff":104044},{"start":1494204663915452,"end":1494204664018264,"diff":102812}],"now":1494204664025,"mem":{"start":{"process":{"rss":51458048,"heapTotal":29982720,"heapUsed":22320128,"external":123168},"os":562667520},"end":{"process":{"rss":66240512,"heapTotal":41701376,"heapUsed":24642312,"external":25668},"os":489988096}},"stats":{"moe":0.0005138664910303965,"rme":0.5002177234292917,"sem":0.0002621767811379574,"deviation":0.0018164140219832316,"mean":0.10272856537499998,"sample":[0.106148468,0.100621313,0.100542061,0.104609159,0.102078686,0.104701639,0.101230642,0.104422198,0.101688888,0.104957871,0.101610069,0.099606952,0.100661388,0.104386423,0.103047251,0.104561699,0.100751721,0.103121506,0.104344757,0.10154,0.100930473,0.100304352,0.099959974,0.099609868,0.101916889,0.105081176,0.104199312,0.102920303,0.101748988,0.101929656,0.103728967,0.100745131,0.10568775,0.100546743,0.104479539,0.105200191,0.104203271,0.100918233,0.102778007,0.104665756,0.104707151,0.101708167,0.103704513,0.103496256,0.103195007,0.100876731,0.104163421,0.102932622],"variance":0.0000032993598992573},"count":1,"hz":9.734390783611195,"time":102.72856537499999,"cycles":1,"battery":{"amperage":-2112,"currentCapacity":417,"percent":5,"charging":"","temp":3108}},{"msg":"sleep1 x 9.73 ops/sec ±0.45% (48 runs sampled)","name":"sleep1","num":9.73,"sampled":"48","variation":"0.45","tags":"fresh,MORETAGS,uniqd,4th","suite":["sleepy4"],"timesFor":[{"start":1494204776897252,"end":1494204776999957,"diff":102705},{"start":1494204777032008,"end":1494204777133390,"diff":101382},{"start":1494204777158156,"end":1494204777261484,"diff":103328},{"start":1494204777280882,"end":1494204777384939,"diff":104057},{"start":1494204777407877,"end":1494204777508189,"diff":100312},{"start":1494204777528257,"end":1494204777630806,"diff":102549},{"start":1494204777656166,"end":1494204777761291,"diff":105125},{"start":1494204777782727,"end":1494204777884836,"diff":102109},{"start":1494204777904964,"end":1494204778007835,"diff":102871},{"start":1494204778028408,"end":1494204778131992,"diff":103584},{"start":1494204778149608,"end":1494204778251185,"diff":101577},{"start":1494204778274989,"end":1494204778379016,"diff":104027},{"start":1494204778398829,"end":1494204778502517,"diff":103688},{"start":1494204778520396,"end":1494204778626054,"diff":105658},{"start":1494204778643633,"end":1494204778744336,"diff":100703},{"start":1494204778766275,"end":1494204778867219,"diff":100944},{"start":1494204778886962,"end":1494204778986890,"diff":99928},{"start":1494204779005869,"end":1494204779107860,"diff":101991},{"start":1494204779127640,"end":1494204779228544,"diff":100904},{"start":1494204779251099,"end":1494204779356116,"diff":105017},{"start":1494204779377026,"end":1494204779477456,"diff":100430},{"start":1494204779497410,"end":1494204779600678,"diff":103268},{"start":1494204779618698,"end":1494204779723976,"diff":105278},{"start":1494204779744603,"end":1494204779846107,"diff":101504},{"start":1494204779867051,"end":1494204779971486,"diff":104435},{"start":1494204779992983,"end":1494204780096035,"diff":103052},{"start":1494204780117878,"end":1494204780221632,"diff":103754},{"start":1494204780240141,"end":1494204780344785,"diff":104644},{"start":1494204780363404,"end":1494204780468050,"diff":104646},{"start":1494204780486734,"end":1494204780587511,"diff":100777},{"start":1494204780606419,"end":1494204780706552,"diff":100133},{"start":1494204780725119,"end":1494204780826497,"diff":101378},{"start":1494204780846084,"end":1494204780948822,"diff":102738},{"start":1494204780967826,"end":1494204781069892,"diff":102066},{"start":1494204781089678,"end":1494204781189569,"diff":99891},{"start":1494204781208833,"end":1494204781309673,"diff":100840},{"start":1494204781329118,"end":1494204781430651,"diff":101533},{"start":1494204781450009,"end":1494204781550508,"diff":100499},{"start":1494204781569051,"end":1494204781671657,"diff":102606},{"start":1494204781689976,"end":1494204781794878,"diff":104902},{"start":1494204781814317,"end":1494204781919166,"diff":104849},{"start":1494204781937983,"end":1494204782039073,"diff":101090},{"start":1494204782056914,"end":1494204782158714,"diff":101800},{"start":1494204782179646,"end":1494204782282724,"diff":103078},{"start":1494204782301950,"end":1494204782405998,"diff":104048},{"start":1494204782424279,"end":1494204782527289,"diff":103010},{"start":1494204782545482,"end":1494204782649221,"diff":103739},{"start":1494204782669588,"end":1494204782771479,"diff":101891}],"now":1494204782778,"mem":{"start":{"process":{"rss":51888128,"heapTotal":29458432,"heapUsed":22067936,"external":123168},"os":296493056},"end":{"process":{"rss":63365120,"heapTotal":41701376,"heapUsed":28459280,"external":25668},"os":259686400}},"stats":{"moe":0.0004669167367022014,"rme":0.4545105861832144,"sem":0.00023822282484806196,"deviation":0.0016504561446376996,"mean":0.10272956249999997,"sample":[0.103114,0.101644,0.103515,0.104857,0.100417,0.102655,0.105223,0.102209,0.103119,0.103681,0.101683,0.104152,0.103801,0.105764,0.100805,0.101042,0.10003,0.102122,0.101009,0.105119,0.100533,0.103382,0.105434,0.101648,0.104568,0.103207,0.103938,0.10475,0.104751,0.100877,0.100233,0.101491,0.102836,0.102163,0.099998,0.100936,0.101633,0.1006,0.102707,0.105016,0.104945,0.101184,0.101898,0.103185,0.104153,0.103147,0.103842,0.102003],"variance":0.000002724005485372339},"count":1,"hz":9.734296298594675,"time":102.72956249999997,"cycles":1,"battery":{"amperage":-1630,"currentCapacity":375,"percent":4,"charging":"","temp":3108}},{"msg":"sleep1 x 9.73 ops/sec ±0.45% (48 runs sampled)","name":"sleep1","num":9.73,"sampled":"48","variation":"0.45","tags":"fresh,MORETAGS,uniqd,4th","suite":["sleepy4"],"timesFor":[{"start":1494204776897252,"end":1494204776999957,"diff":102705},{"start":1494204777032008,"end":1494204777133390,"diff":101382},{"start":1494204777158156,"end":1494204777261484,"diff":103328},{"start":1494204777280882,"end":1494204777384939,"diff":104057},{"start":1494204777407877,"end":1494204777508189,"diff":100312},{"start":1494204777528257,"end":1494204777630806,"diff":102549},{"start":1494204777656166,"end":1494204777761291,"diff":105125},{"start":1494204777782727,"end":1494204777884836,"diff":102109},{"start":1494204777904964,"end":1494204778007835,"diff":102871},{"start":1494204778028408,"end":1494204778131992,"diff":103584},{"start":1494204778149608,"end":1494204778251185,"diff":101577},{"start":1494204778274989,"end":1494204778379016,"diff":104027},{"start":1494204778398829,"end":1494204778502517,"diff":103688},{"start":1494204778520396,"end":1494204778626054,"diff":105658},{"start":1494204778643633,"end":1494204778744336,"diff":100703},{"start":1494204778766275,"end":1494204778867219,"diff":100944},{"start":1494204778886962,"end":1494204778986890,"diff":99928},{"start":1494204779005869,"end":1494204779107860,"diff":101991},{"start":1494204779127640,"end":1494204779228544,"diff":100904},{"start":1494204779251099,"end":1494204779356116,"diff":105017},{"start":1494204779377026,"end":1494204779477456,"diff":100430},{"start":1494204779497410,"end":1494204779600678,"diff":103268},{"start":1494204779618698,"end":1494204779723976,"diff":105278},{"start":1494204779744603,"end":1494204779846107,"diff":101504},{"start":1494204779867051,"end":1494204779971486,"diff":104435},{"start":1494204779992983,"end":1494204780096035,"diff":103052},{"start":1494204780117878,"end":1494204780221632,"diff":103754},{"start":1494204780240141,"end":1494204780344785,"diff":104644},{"start":1494204780363404,"end":1494204780468050,"diff":104646},{"start":1494204780486734,"end":1494204780587511,"diff":100777},{"start":1494204780606419,"end":1494204780706552,"diff":100133},{"start":1494204780725119,"end":1494204780826497,"diff":101378},{"start":1494204780846084,"end":1494204780948822,"diff":102738},{"start":1494204780967826,"end":1494204781069892,"diff":102066},{"start":1494204781089678,"end":1494204781189569,"diff":99891},{"start":1494204781208833,"end":1494204781309673,"diff":100840},{"start":1494204781329118,"end":1494204781430651,"diff":101533},{"start":1494204781450009,"end":1494204781550508,"diff":100499},{"start":1494204781569051,"end":1494204781671657,"diff":102606},{"start":1494204781689976,"end":1494204781794878,"diff":104902},{"start":1494204781814317,"end":1494204781919166,"diff":104849},{"start":1494204781937983,"end":1494204782039073,"diff":101090},{"start":1494204782056914,"end":1494204782158714,"diff":101800},{"start":1494204782179646,"end":1494204782282724,"diff":103078},{"start":1494204782301950,"end":1494204782405998,"diff":104048},{"start":1494204782424279,"end":1494204782527289,"diff":103010},{"start":1494204782545482,"end":1494204782649221,"diff":103739},{"start":1494204782669588,"end":1494204782771479,"diff":101891}],"now":1494204782779,"mem":{"start":{"process":{"rss":51888128,"heapTotal":29458432,"heapUsed":22067936,"external":123168},"os":296493056},"end":{"process":{"rss":63385600,"heapTotal":41701376,"heapUsed":28487384,"external":25668},"os":259686400}},"stats":{"moe":0.0004669167367022014,"rme":0.4545105861832144,"sem":0.00023822282484806196,"deviation":0.0016504561446376996,"mean":0.10272956249999997,"sample":[0.103114,0.101644,0.103515,0.104857,0.100417,0.102655,0.105223,0.102209,0.103119,0.103681,0.101683,0.104152,0.103801,0.105764,0.100805,0.101042,0.10003,0.102122,0.101009,0.105119,0.100533,0.103382,0.105434,0.101648,0.104568,0.103207,0.103938,0.10475,0.104751,0.100877,0.100233,0.101491,0.102836,0.102163,0.099998,0.100936,0.101633,0.1006,0.102707,0.105016,0.104945,0.101184,0.101898,0.103185,0.104153,0.103147,0.103842,0.102003],"variance":0.000002724005485372339},"count":1,"hz":9.734296298594675,"time":102.72956249999997,"cycles":1,"battery":{"amperage":-1630,"currentCapacity":375,"percent":4,"charging":"","temp":3108}},{"msg":"sleep1 x 9.69 ops/sec ±0.43% (48 runs sampled)","name":"sleep1","num":9.69,"sampled":"48","variation":"0.43","tags":"fresh,MORETAGS,uniqd,4th","suite":["sleepy4"],"timesFor":[{"start":1494206416035272,"end":1494206416140900,"diff":105628},{"start":1494206416168363,"end":1494206416272668,"diff":104305},{"start":1494206416293474,"end":1494206416394386,"diff":100912},{"start":1494206416413282,"end":1494206416514335,"diff":101053},{"start":1494206416537160,"end":1494206416642197,"diff":105037},{"start":1494206416662075,"end":1494206416763428,"diff":101353},{"start":1494206416787838,"end":1494206416892523,"diff":104685},{"start":1494206416912705,"end":1494206417013351,"diff":100646},{"start":1494206417031515,"end":1494206417135647,"diff":104132},{"start":1494206417151992,"end":1494206417256003,"diff":104011},{"start":1494206417275623,"end":1494206417378211,"diff":102588},{"start":1494206417395417,"end":1494206417500064,"diff":104647},{"start":1494206417516397,"end":1494206417617623,"diff":101226},{"start":1494206417633212,"end":1494206417733512,"diff":100300},{"start":1494206417749757,"end":1494206417851499,"diff":101742},{"start":1494206417867713,"end":1494206417969341,"diff":101628},{"start":1494206417986846,"end":1494206418088097,"diff":101251},{"start":1494206418105587,"end":1494206418209746,"diff":104159},{"start":1494206418227316,"end":1494206418330616,"diff":103300},{"start":1494206418349575,"end":1494206418451780,"diff":102205},{"start":1494206418470355,"end":1494206418574359,"diff":104004},{"start":1494206418592032,"end":1494206418695897,"diff":103865},{"start":1494206418711752,"end":1494206418813441,"diff":101689},{"start":1494206418832069,"end":1494206418936739,"diff":104670},{"start":1494206418953417,"end":1494206419054552,"diff":101135},{"start":1494206419073260,"end":1494206419178214,"diff":104954},{"start":1494206419197522,"end":1494206419301778,"diff":104256},{"start":1494206419317980,"end":1494206419420510,"diff":102530},{"start":1494206419439884,"end":1494206419543427,"diff":103543},{"start":1494206419560812,"end":1494206419665343,"diff":104531},{"start":1494206419682920,"end":1494206419786398,"diff":103478},{"start":1494206419805559,"end":1494206419909577,"diff":104018},{"start":1494206419929541,"end":1494206420030331,"diff":100790},{"start":1494206420046066,"end":1494206420147320,"diff":101254},{"start":1494206420164559,"end":1494206420267983,"diff":103424},{"start":1494206420285354,"end":1494206420385716,"diff":100362},{"start":1494206420403276,"end":1494206420507963,"diff":104687},{"start":1494206420527234,"end":1494206420630508,"diff":103274},{"start":1494206420647769,"end":1494206420751651,"diff":103882},{"start":1494206420771522,"end":1494206420875031,"diff":103509},{"start":1494206420891318,"end":1494206420995567,"diff":104249},{"start":1494206421014045,"end":1494206421119364,"diff":105319},{"start":1494206421137965,"end":1494206421241511,"diff":103546},{"start":1494206421260633,"end":1494206421365570,"diff":104937},{"start":1494206421380152,"end":1494206421485532,"diff":105380},{"start":1494206421503101,"end":1494206421607605,"diff":104504},{"start":1494206421624626,"end":1494206421728261,"diff":103635},{"start":1494206421747180,"end":1494206421848246,"diff":101066}],"now":1494206421855,"mem":{"start":{"process":{"rss":51400704,"heapTotal":29458432,"heapUsed":22338544,"external":123168},"os":290770944},"end":{"process":{"rss":65277952,"heapTotal":41701376,"heapUsed":24579800,"external":33860},"os":286253056}},"stats":{"moe":0.0004469790161827981,"rme":0.4329463238551448,"sem":0.0002280505184606113,"deviation":0.0015799803386648116,"mean":0.10324120833333333,"sample":[0.105934,0.104478,0.101051,0.10119,0.105108,0.10143,0.104755,0.100731,0.104212,0.104082,0.102695,0.104718,0.101286,0.10036,0.101832,0.101688,0.10144,0.104219,0.103361,0.102276,0.104073,0.103933,0.101755,0.104751,0.101199,0.105036,0.104399,0.102603,0.103629,0.104595,0.103553,0.104114,0.100871,0.101326,0.103508,0.100428,0.104754,0.103355,0.10395,0.103616,0.104335,0.10539,0.10362,0.105047,0.105463,0.104569,0.103714,0.101146],"variance":0.000002496337870567373},"count":1,"hz":9.686054785133036,"time":103.24120833333333,"cycles":1,"battery":{"amperage":4335,"currentCapacity":1421,"percent":18,"charging":"","temp":3104}},{"msg":"sleep1 x 9.69 ops/sec ±0.43% (48 runs sampled)","name":"sleep1","num":9.69,"sampled":"48","variation":"0.43","tags":"fresh,MORETAGS,uniqd,4th","suite":["sleepy4"],"timesFor":[{"start":1494206416035272,"end":1494206416140900,"diff":105628},{"start":1494206416168363,"end":1494206416272668,"diff":104305},{"start":1494206416293474,"end":1494206416394386,"diff":100912},{"start":1494206416413282,"end":1494206416514335,"diff":101053},{"start":1494206416537160,"end":1494206416642197,"diff":105037},{"start":1494206416662075,"end":1494206416763428,"diff":101353},{"start":1494206416787838,"end":1494206416892523,"diff":104685},{"start":1494206416912705,"end":1494206417013351,"diff":100646},{"start":1494206417031515,"end":1494206417135647,"diff":104132},{"start":1494206417151992,"end":1494206417256003,"diff":104011},{"start":1494206417275623,"end":1494206417378211,"diff":102588},{"start":1494206417395417,"end":1494206417500064,"diff":104647},{"start":1494206417516397,"end":1494206417617623,"diff":101226},{"start":1494206417633212,"end":1494206417733512,"diff":100300},{"start":1494206417749757,"end":1494206417851499,"diff":101742},{"start":1494206417867713,"end":1494206417969341,"diff":101628},{"start":1494206417986846,"end":1494206418088097,"diff":101251},{"start":1494206418105587,"end":1494206418209746,"diff":104159},{"start":1494206418227316,"end":1494206418330616,"diff":103300},{"start":1494206418349575,"end":1494206418451780,"diff":102205},{"start":1494206418470355,"end":1494206418574359,"diff":104004},{"start":1494206418592032,"end":1494206418695897,"diff":103865},{"start":1494206418711752,"end":1494206418813441,"diff":101689},{"start":1494206418832069,"end":1494206418936739,"diff":104670},{"start":1494206418953417,"end":1494206419054552,"diff":101135},{"start":1494206419073260,"end":1494206419178214,"diff":104954},{"start":1494206419197522,"end":1494206419301778,"diff":104256},{"start":1494206419317980,"end":1494206419420510,"diff":102530},{"start":1494206419439884,"end":1494206419543427,"diff":103543},{"start":1494206419560812,"end":1494206419665343,"diff":104531},{"start":1494206419682920,"end":1494206419786398,"diff":103478},{"start":1494206419805559,"end":1494206419909577,"diff":104018},{"start":1494206419929541,"end":1494206420030331,"diff":100790},{"start":1494206420046066,"end":1494206420147320,"diff":101254},{"start":1494206420164559,"end":1494206420267983,"diff":103424},{"start":1494206420285354,"end":1494206420385716,"diff":100362},{"start":1494206420403276,"end":1494206420507963,"diff":104687},{"start":1494206420527234,"end":1494206420630508,"diff":103274},{"start":1494206420647769,"end":1494206420751651,"diff":103882},{"start":1494206420771522,"end":1494206420875031,"diff":103509},{"start":1494206420891318,"end":1494206420995567,"diff":104249},{"start":1494206421014045,"end":1494206421119364,"diff":105319},{"start":1494206421137965,"end":1494206421241511,"diff":103546},{"start":1494206421260633,"end":1494206421365570,"diff":104937},{"start":1494206421380152,"end":1494206421485532,"diff":105380},{"start":1494206421503101,"end":1494206421607605,"diff":104504},{"start":1494206421624626,"end":1494206421728261,"diff":103635},{"start":1494206421747180,"end":1494206421848246,"diff":101066}],"now":1494206421855,"mem":{"start":{"process":{"rss":51400704,"heapTotal":29458432,"heapUsed":22338544,"external":123168},"os":290770944},"end":{"process":{"rss":65282048,"heapTotal":41701376,"heapUsed":24607928,"external":33860},"os":286253056}},"stats":{"moe":0.0004469790161827981,"rme":0.4329463238551448,"sem":0.0002280505184606113,"deviation":0.0015799803386648116,"mean":0.10324120833333333,"sample":[0.105934,0.104478,0.101051,0.10119,0.105108,0.10143,0.104755,0.100731,0.104212,0.104082,0.102695,0.104718,0.101286,0.10036,0.101832,0.101688,0.10144,0.104219,0.103361,0.102276,0.104073,0.103933,0.101755,0.104751,0.101199,0.105036,0.104399,0.102603,0.103629,0.104595,0.103553,0.104114,0.100871,0.101326,0.103508,0.100428,0.104754,0.103355,0.10395,0.103616,0.104335,0.10539,0.10362,0.105047,0.105463,0.104569,0.103714,0.101146],"variance":0.000002496337870567373},"count":1,"hz":9.686054785133036,"time":103.24120833333333,"cycles":1,"battery":{"amperage":4335,"currentCapacity":1421,"percent":18,"charging":"","temp":3104}},{"msg":"sleep1 x 9.70 ops/sec ±0.60% (48 runs sampled)","name":"sleep1","num":9.7,"sampled":"48","variation":"0.60","tags":"fresh,MORETAGS,uniqd,4th","suite":["sleepy4"],"timesFor":[{"start":1494206698459151,"end":1494206698562820,"diff":103669},{"start":1494206698588551,"end":1494206698692528,"diff":103977},{"start":1494206698715184,"end":1494206698814982,"diff":99798},{"start":1494206698840488,"end":1494206698943025,"diff":102537},{"start":1494206698962834,"end":1494206699063103,"diff":100269},{"start":1494206699080443,"end":1494206699184735,"diff":104292},{"start":1494206699211805,"end":1494206699312121,"diff":100316},{"start":1494206699329955,"end":1494206699434339,"diff":104384},{"start":1494206699452114,"end":1494206699556740,"diff":104626},{"start":1494206699575469,"end":1494206699678489,"diff":103020},{"start":1494206699694204,"end":1494206699798067,"diff":103863},{"start":1494206699816851,"end":1494206699921955,"diff":105104},{"start":1494206699940077,"end":1494206700040440,"diff":100363},{"start":1494206700056039,"end":1494206700160026,"diff":103987},{"start":1494206700176321,"end":1494206700278110,"diff":101789},{"start":1494206700294712,"end":1494206700399769,"diff":105057},{"start":1494206700418254,"end":1494206700522672,"diff":104418},{"start":1494206700540435,"end":1494206700644463,"diff":104028},{"start":1494206700661546,"end":1494206700762828,"diff":101282},{"start":1494206700783653,"end":1494206700884836,"diff":101183},{"start":1494206700904506,"end":1494206701005144,"diff":100638},{"start":1494206701024054,"end":1494206701125385,"diff":101331},{"start":1494206701144174,"end":1494206701247979,"diff":103805},{"start":1494206701266070,"end":1494206701366428,"diff":100358},{"start":1494206701384435,"end":1494206701488776,"diff":104341},{"start":1494206701505177,"end":1494206701607128,"diff":101951},{"start":1494206701625276,"end":1494206701729361,"diff":104085},{"start":1494206701746795,"end":1494206701851758,"diff":104963},{"start":1494206701869933,"end":1494206701974148,"diff":104215},{"start":1494206701992051,"end":1494206702093221,"diff":101170},{"start":1494206702110812,"end":1494206702214811,"diff":103999},{"start":1494206702230077,"end":1494206702333938,"diff":103861},{"start":1494206702350739,"end":1494206702452839,"diff":102100},{"start":1494206702469398,"end":1494206702582868,"diff":113470},{"start":1494206702599360,"end":1494206702701722,"diff":102362},{"start":1494206702719647,"end":1494206702823513,"diff":103866},{"start":1494206702841251,"end":1494206702943533,"diff":102282},{"start":1494206702960211,"end":1494206703062997,"diff":102786},{"start":1494206703080200,"end":1494206703181506,"diff":101306},{"start":1494206703199369,"end":1494206703302323,"diff":102954},{"start":1494206703318204,"end":1494206703418929,"diff":100725},{"start":1494206703438981,"end":1494206703543792,"diff":104811},{"start":1494206703559435,"end":1494206703663342,"diff":103907},{"start":1494206703683053,"end":1494206703783525,"diff":100472},{"start":1494206703802365,"end":1494206703905559,"diff":103194},{"start":1494206703922663,"end":1494206704024756,"diff":102093},{"start":1494206704043519,"end":1494206704147211,"diff":103692},{"start":1494206704165222,"end":1494206704268292,"diff":103070}],"now":1494206704274,"mem":{"start":{"process":{"rss":46014464,"heapTotal":27852800,"heapUsed":15498304,"external":1547286},"os":375263232},"end":{"process":{"rss":57643008,"heapTotal":42020864,"heapUsed":26188728,"external":17476},"os":19111936}},"stats":{"moe":0.0006170455096712378,"rme":0.5983186349947642,"sem":0.00031481913758736623,"deviation":0.0021811309659853406,"mean":0.10312991666666665,"sample":[0.103953,0.104181,0.099941,0.10273,0.100336,0.104363,0.100377,0.104459,0.104706,0.103092,0.103929,0.105187,0.100449,0.104067,0.101861,0.105127,0.104495,0.104117,0.101365,0.101266,0.100752,0.101415,0.103882,0.100436,0.104441,0.10201,0.104272,0.105062,0.104292,0.101251,0.104086,0.103925,0.102172,0.11355,0.102426,0.103939,0.102357,0.102852,0.101377,0.103045,0.100803,0.104888,0.103968,0.100576,0.103289,0.10218,0.103799,0.10319],"variance":0.0000047573322907801455},"count":1,"hz":9.696507398839168,"time":103.12991666666666,"cycles":1,"battery":{"amperage":3598,"currentCapacity":1670,"percent":22,"charging":"","temp":3108}},{"msg":"sleep1 x 9.70 ops/sec ±0.60% (48 runs sampled)","name":"sleep1","num":9.7,"sampled":"48","variation":"0.60","tags":"fresh,MORETAGS,uniqd,4th","suite":["sleepy4"],"timesFor":[{"start":1494206698459151,"end":1494206698562820,"diff":103669},{"start":1494206698588551,"end":1494206698692528,"diff":103977},{"start":1494206698715184,"end":1494206698814982,"diff":99798},{"start":1494206698840488,"end":1494206698943025,"diff":102537},{"start":1494206698962834,"end":1494206699063103,"diff":100269},{"start":1494206699080443,"end":1494206699184735,"diff":104292},{"start":1494206699211805,"end":1494206699312121,"diff":100316},{"start":1494206699329955,"end":1494206699434339,"diff":104384},{"start":1494206699452114,"end":1494206699556740,"diff":104626},{"start":1494206699575469,"end":1494206699678489,"diff":103020},{"start":1494206699694204,"end":1494206699798067,"diff":103863},{"start":1494206699816851,"end":1494206699921955,"diff":105104},{"start":1494206699940077,"end":1494206700040440,"diff":100363},{"start":1494206700056039,"end":1494206700160026,"diff":103987},{"start":1494206700176321,"end":1494206700278110,"diff":101789},{"start":1494206700294712,"end":1494206700399769,"diff":105057},{"start":1494206700418254,"end":1494206700522672,"diff":104418},{"start":1494206700540435,"end":1494206700644463,"diff":104028},{"start":1494206700661546,"end":1494206700762828,"diff":101282},{"start":1494206700783653,"end":1494206700884836,"diff":101183},{"start":1494206700904506,"end":1494206701005144,"diff":100638},{"start":1494206701024054,"end":1494206701125385,"diff":101331},{"start":1494206701144174,"end":1494206701247979,"diff":103805},{"start":1494206701266070,"end":1494206701366428,"diff":100358},{"start":1494206701384435,"end":1494206701488776,"diff":104341},{"start":1494206701505177,"end":1494206701607128,"diff":101951},{"start":1494206701625276,"end":1494206701729361,"diff":104085},{"start":1494206701746795,"end":1494206701851758,"diff":104963},{"start":1494206701869933,"end":1494206701974148,"diff":104215},{"start":1494206701992051,"end":1494206702093221,"diff":101170},{"start":1494206702110812,"end":1494206702214811,"diff":103999},{"start":1494206702230077,"end":1494206702333938,"diff":103861},{"start":1494206702350739,"end":1494206702452839,"diff":102100},{"start":1494206702469398,"end":1494206702582868,"diff":113470},{"start":1494206702599360,"end":1494206702701722,"diff":102362},{"start":1494206702719647,"end":1494206702823513,"diff":103866},{"start":1494206702841251,"end":1494206702943533,"diff":102282},{"start":1494206702960211,"end":1494206703062997,"diff":102786},{"start":1494206703080200,"end":1494206703181506,"diff":101306},{"start":1494206703199369,"end":1494206703302323,"diff":102954},{"start":1494206703318204,"end":1494206703418929,"diff":100725},{"start":1494206703438981,"end":1494206703543792,"diff":104811},{"start":1494206703559435,"end":1494206703663342,"diff":103907},{"start":1494206703683053,"end":1494206703783525,"diff":100472},{"start":1494206703802365,"end":1494206703905559,"diff":103194},{"start":1494206703922663,"end":1494206704024756,"diff":102093},{"start":1494206704043519,"end":1494206704147211,"diff":103692},{"start":1494206704165222,"end":1494206704268292,"diff":103070}],"now":1494206704275,"mem":{"start":{"process":{"rss":46014464,"heapTotal":27852800,"heapUsed":15498304,"external":1547286},"os":375263232},"end":{"process":{"rss":57659392,"heapTotal":42020864,"heapUsed":26216816,"external":17476},"os":19111936}},"stats":{"moe":0.0006170455096712378,"rme":0.5983186349947642,"sem":0.00031481913758736623,"deviation":0.0021811309659853406,"mean":0.10312991666666665,"sample":[0.103953,0.104181,0.099941,0.10273,0.100336,0.104363,0.100377,0.104459,0.104706,0.103092,0.103929,0.105187,0.100449,0.104067,0.101861,0.105127,0.104495,0.104117,0.101365,0.101266,0.100752,0.101415,0.103882,0.100436,0.104441,0.10201,0.104272,0.105062,0.104292,0.101251,0.104086,0.103925,0.102172,0.11355,0.102426,0.103939,0.102357,0.102852,0.101377,0.103045,0.100803,0.104888,0.103968,0.100576,0.103289,0.10218,0.103799,0.10319],"variance":0.0000047573322907801455},"count":1,"hz":9.696507398839168,"time":103.12991666666666,"cycles":1,"battery":{"amperage":3598,"currentCapacity":1670,"percent":22,"charging":"","temp":3108}}],"sleep2":[{"msg":"sleep2 x 4.93 ops/sec ±0.30% (28 runs sampled)","name":"sleep2","num":4.93,"sampled":"28","variation":"0.30","tags":"fresh,MORETAGS,uniqd,4th","suite":["sleepy4"],"timesFor":[{"start":1494204477182331,"end":1494204477382439,"diff":200108},{"start":1494204477401943,"end":1494204477603876,"diff":201933},{"start":1494204477622704,"end":1494204477826395,"diff":203691},{"start":1494204477850637,"end":1494204478051872,"diff":201235},{"start":1494204478066384,"end":1494204478266442,"diff":200058},{"start":1494204478284587,"end":1494204478488118,"diff":203531},{"start":1494204478505031,"end":1494204478707278,"diff":202247},{"start":1494204478723526,"end":1494204478927493,"diff":203967},{"start":1494204478943736,"end":1494204479146092,"diff":202356},{"start":1494204479164002,"end":1494204479368673,"diff":204671},{"start":1494204479385072,"end":1494204479589295,"diff":204223},{"start":1494204479607085,"end":1494204479810881,"diff":203796},{"start":1494204479828887,"end":1494204480030853,"diff":201966},{"start":1494204480049365,"end":1494204480251413,"diff":202048},{"start":1494204480268405,"end":1494204480468331,"diff":199926},{"start":1494204480487450,"end":1494204480689719,"diff":202269},{"start":1494204480709499,"end":1494204480913014,"diff":203515},{"start":1494204480927818,"end":1494204481130488,"diff":202670},{"start":1494204481149172,"end":1494204481354167,"diff":204995},{"start":1494204481371857,"end":1494204481576012,"diff":204155},{"start":1494204481593950,"end":1494204481796847,"diff":202897},{"start":1494204481813150,"end":1494204482013752,"diff":200602},{"start":1494204482032181,"end":1494204482236313,"diff":204132},{"start":1494204482251580,"end":1494204482454262,"diff":202682},{"start":1494204482470959,"end":1494204482675732,"diff":204773},{"start":1494204482692990,"end":1494204482898076,"diff":205086},{"start":1494204482914545,"end":1494204483119550,"diff":205005},{"start":1494204483138885,"end":1494204483342400,"diff":203515}],"now":1494204483348,"mem":{"start":{"process":{"rss":51810304,"heapTotal":29458432,"heapUsed":22156664,"external":123168},"os":261259264},"end":{"process":{"rss":69890048,"heapTotal":46419968,"heapUsed":27688552,"external":33860},"os":215224320}},"stats":{"moe":0.0006034942970980746,"rme":0.29725974725375326,"sem":0.0002941005346481845,"deviation":0.0015562337502604624,"mean":0.2030191785714286,"sample":[0.200208,0.202035,0.203756,0.201328,0.200123,0.20361,0.20233,0.204069,0.202438,0.204803,0.2043,0.20387,0.202045,0.202256,0.200005,0.202343,0.203593,0.202745,0.205068,0.204233,0.202988,0.200677,0.20421,0.202746,0.204874,0.205189,0.205093,0.203602],"variance":0.0000024218634854497436},"count":1,"hz":4.925643020706875,"time":203.0191785714286,"cycles":1,"battery":{"amperage":-2340,"currentCapacity":516,"percent":6,"charging":"","temp":3108}},{"msg":"sleep2 x 4.93 ops/sec ±0.30% (28 runs sampled)","name":"sleep2","num":4.93,"sampled":"28","variation":"0.30","tags":"fresh,MORETAGS,uniqd,4th","suite":["sleepy4"],"timesFor":[{"start":1494204477182331,"end":1494204477382439,"diff":200108},{"start":1494204477401943,"end":1494204477603876,"diff":201933},{"start":1494204477622704,"end":1494204477826395,"diff":203691},{"start":1494204477850637,"end":1494204478051872,"diff":201235},{"start":1494204478066384,"end":1494204478266442,"diff":200058},{"start":1494204478284587,"end":1494204478488118,"diff":203531},{"start":1494204478505031,"end":1494204478707278,"diff":202247},{"start":1494204478723526,"end":1494204478927493,"diff":203967},{"start":1494204478943736,"end":1494204479146092,"diff":202356},{"start":1494204479164002,"end":1494204479368673,"diff":204671},{"start":1494204479385072,"end":1494204479589295,"diff":204223},{"start":1494204479607085,"end":1494204479810881,"diff":203796},{"start":1494204479828887,"end":1494204480030853,"diff":201966},{"start":1494204480049365,"end":1494204480251413,"diff":202048},{"start":1494204480268405,"end":1494204480468331,"diff":199926},{"start":1494204480487450,"end":1494204480689719,"diff":202269},{"start":1494204480709499,"end":1494204480913014,"diff":203515},{"start":1494204480927818,"end":1494204481130488,"diff":202670},{"start":1494204481149172,"end":1494204481354167,"diff":204995},{"start":1494204481371857,"end":1494204481576012,"diff":204155},{"start":1494204481593950,"end":1494204481796847,"diff":202897},{"start":1494204481813150,"end":1494204482013752,"diff":200602},{"start":1494204482032181,"end":1494204482236313,"diff":204132},{"start":1494204482251580,"end":1494204482454262,"diff":202682},{"start":1494204482470959,"end":1494204482675732,"diff":204773},{"start":1494204482692990,"end":1494204482898076,"diff":205086},{"start":1494204482914545,"end":1494204483119550,"diff":205005},{"start":1494204483138885,"end":1494204483342400,"diff":203515}],"now":1494204483349,"mem":{"start":{"process":{"rss":51810304,"heapTotal":29458432,"heapUsed":22156664,"external":123168},"os":261259264},"end":{"process":{"rss":69890048,"heapTotal":46419968,"heapUsed":27692800,"external":33860},"os":215228416}},"stats":{"moe":0.0006034942970980746,"rme":0.29725974725375326,"sem":0.0002941005346481845,"deviation":0.0015562337502604624,"mean":0.2030191785714286,"sample":[0.200208,0.202035,0.203756,0.201328,0.200123,0.20361,0.20233,0.204069,0.202438,0.204803,0.2043,0.20387,0.202045,0.202256,0.200005,0.202343,0.203593,0.202745,0.205068,0.204233,0.202988,0.200677,0.20421,0.202746,0.204874,0.205189,0.205093,0.203602],"variance":0.0000024218634854497436},"count":1,"hz":4.925643020706875,"time":203.0191785714286,"cycles":1,"battery":{"amperage":-2340,"currentCapacity":516,"percent":6,"charging":"","temp":3108}},{"msg":"sleep2 x 4.93 ops/sec ±0.35% (28 runs sampled)","name":"sleep2","num":4.93,"sampled":"28","variation":"0.35","tags":"fresh,MORETAGS,uniqd,4th","suite":["sleepy4"],"timesFor":[{"start":1494204500746273,"end":1494204500950981,"diff":204708},{"start":1494204500969072,"end":1494204501171654,"diff":202582},{"start":1494204501191581,"end":1494204501396479,"diff":204898},{"start":1494204501414041,"end":1494204501618416,"diff":204375},{"start":1494204501634893,"end":1494204501835553,"diff":200660},{"start":1494204501853515,"end":1494204502058168,"diff":204653},{"start":1494204502075169,"end":1494204502275831,"diff":200662},{"start":1494204502297217,"end":1494204502500790,"diff":203573},{"start":1494204502516559,"end":1494204502716102,"diff":199543},{"start":1494204502738397,"end":1494204502941878,"diff":203481},{"start":1494204502958518,"end":1494204503158056,"diff":199538},{"start":1494204503176929,"end":1494204503377225,"diff":200296},{"start":1494204503395807,"end":1494204503597888,"diff":202081},{"start":1494204503614149,"end":1494204503816872,"diff":202723},{"start":1494204503834770,"end":1494204504035503,"diff":200733},{"start":1494204504053417,"end":1494204504253916,"diff":200499},{"start":1494204504275800,"end":1494204504480175,"diff":204375},{"start":1494204504500176,"end":1494204504700987,"diff":200811},{"start":1494204504716062,"end":1494204504921312,"diff":205250},{"start":1494204504936208,"end":1494204505140761,"diff":204553},{"start":1494204505155056,"end":1494204505356724,"diff":201668},{"start":1494204505372811,"end":1494204505573794,"diff":200983},{"start":1494204505592760,"end":1494204505797893,"diff":205133},{"start":1494204505817017,"end":1494204506018492,"diff":201475},{"start":1494204506035106,"end":1494204506239096,"diff":203990},{"start":1494204506256727,"end":1494204506459821,"diff":203094},{"start":1494204506476078,"end":1494204506680095,"diff":204017},{"start":1494204506695456,"end":1494204506898167,"diff":202711}],"now":1494204506903,"mem":{"start":{"process":{"rss":52060160,"heapTotal":29458432,"heapUsed":22363008,"external":123168},"os":344244224},"end":{"process":{"rss":70139904,"heapTotal":46419968,"heapUsed":28788928,"external":33860},"os":319455232}},"stats":{"moe":0.0007145856501561315,"rme":0.35253271992166507,"sem":0.0003482386209337873,"deviation":0.0018427055757977856,"mean":0.20270051821428572,"sample":[0.204843284,0.202688544,0.204979632,0.204504716,0.200737902,0.2047412,0.20073729,0.203663778,0.199667406,0.203588046,0.199614177,0.200377603,0.202165498,0.202801801,0.200808857,0.200600002,0.2044717,0.200887862,0.205326288,0.204663654,0.201735743,0.201060675,0.205214508,0.201547954,0.204114815,0.203184036,0.204101845,0.202785694],"variance":0.0000033955638390762486},"count":1,"hz":4.933386499499946,"time":202.70051821428572,"cycles":1,"battery":{"amperage":-2451,"currentCapacity":475,"percent":6,"charging":"","temp":3108}},{"msg":"sleep2 x 4.93 ops/sec ±0.35% (28 runs sampled)","name":"sleep2","num":4.93,"sampled":"28","variation":"0.35","tags":"fresh,MORETAGS,uniqd,4th","suite":["sleepy4"],"timesFor":[{"start":1494204500746273,"end":1494204500950981,"diff":204708},{"start":1494204500969072,"end":1494204501171654,"diff":202582},{"start":1494204501191581,"end":1494204501396479,"diff":204898},{"start":1494204501414041,"end":1494204501618416,"diff":204375},{"start":1494204501634893,"end":1494204501835553,"diff":200660},{"start":1494204501853515,"end":1494204502058168,"diff":204653},{"start":1494204502075169,"end":1494204502275831,"diff":200662},{"start":1494204502297217,"end":1494204502500790,"diff":203573},{"start":1494204502516559,"end":1494204502716102,"diff":199543},{"start":1494204502738397,"end":1494204502941878,"diff":203481},{"start":1494204502958518,"end":1494204503158056,"diff":199538},{"start":1494204503176929,"end":1494204503377225,"diff":200296},{"start":1494204503395807,"end":1494204503597888,"diff":202081},{"start":1494204503614149,"end":1494204503816872,"diff":202723},{"start":1494204503834770,"end":1494204504035503,"diff":200733},{"start":1494204504053417,"end":1494204504253916,"diff":200499},{"start":1494204504275800,"end":1494204504480175,"diff":204375},{"start":1494204504500176,"end":1494204504700987,"diff":200811},{"start":1494204504716062,"end":1494204504921312,"diff":205250},{"start":1494204504936208,"end":1494204505140761,"diff":204553},{"start":1494204505155056,"end":1494204505356724,"diff":201668},{"start":1494204505372811,"end":1494204505573794,"diff":200983},{"start":1494204505592760,"end":1494204505797893,"diff":205133},{"start":1494204505817017,"end":1494204506018492,"diff":201475},{"start":1494204506035106,"end":1494204506239096,"diff":203990},{"start":1494204506256727,"end":1494204506459821,"diff":203094},{"start":1494204506476078,"end":1494204506680095,"diff":204017},{"start":1494204506695456,"end":1494204506898167,"diff":202711}],"now":1494204506904,"mem":{"start":{"process":{"rss":52060160,"heapTotal":29458432,"heapUsed":22363008,"external":123168},"os":344244224},"end":{"process":{"rss":70139904,"heapTotal":46419968,"heapUsed":28793184,"external":33860},"os":319455232}},"stats":{"moe":0.0007145856501561315,"rme":0.35253271992166507,"sem":0.0003482386209337873,"deviation":0.0018427055757977856,"mean":0.20270051821428572,"sample":[0.204843284,0.202688544,0.204979632,0.204504716,0.200737902,0.2047412,0.20073729,0.203663778,0.199667406,0.203588046,0.199614177,0.200377603,0.202165498,0.202801801,0.200808857,0.200600002,0.2044717,0.200887862,0.205326288,0.204663654,0.201735743,0.201060675,0.205214508,0.201547954,0.204114815,0.203184036,0.204101845,0.202785694],"variance":0.0000033955638390762486},"count":1,"hz":4.933386499499946,"time":202.70051821428572,"cycles":1,"battery":{"amperage":-2451,"currentCapacity":475,"percent":6,"charging":"","temp":3108}},{"msg":"sleep2 x 4.93 ops/sec ±0.26% (28 runs sampled)","name":"sleep2","num":4.93,"sampled":"28","variation":"0.26","tags":"fresh,MORETAGS,uniqd,4th","suite":["sleepy4"],"timesFor":[{"start":1494204664046405,"end":1494204664248856,"diff":202451},{"start":1494204664269007,"end":1494204664472779,"diff":203772},{"start":1494204664493824,"end":1494204664695056,"diff":201232},{"start":1494204664717430,"end":1494204664918564,"diff":201134},{"start":1494204664938362,"end":1494204665141726,"diff":203364},{"start":1494204665161660,"end":1494204665363127,"diff":201467},{"start":1494204665383433,"end":1494204665583744,"diff":200311},{"start":1494204665607500,"end":1494204665811968,"diff":204468},{"start":1494204665830077,"end":1494204666030996,"diff":200919},{"start":1494204666049729,"end":1494204666252904,"diff":203175},{"start":1494204666271303,"end":1494204666473764,"diff":202461},{"start":1494204666491464,"end":1494204666693320,"diff":201856},{"start":1494204666715736,"end":1494204666918139,"diff":202403},{"start":1494204666941743,"end":1494204667144003,"diff":202260},{"start":1494204667168448,"end":1494204667371940,"diff":203492},{"start":1494204667394518,"end":1494204667599947,"diff":205429},{"start":1494204667628262,"end":1494204667830908,"diff":202646},{"start":1494204667863427,"end":1494204668067920,"diff":204493},{"start":1494204668215258,"end":1494204668418782,"diff":203524},{"start":1494204668441079,"end":1494204668644675,"diff":203596},{"start":1494204668667325,"end":1494204668869855,"diff":202530},{"start":1494204668889008,"end":1494204669092384,"diff":203376},{"start":1494204669111339,"end":1494204669312478,"diff":201139},{"start":1494204669330320,"end":1494204669532813,"diff":202493},{"start":1494204669550898,"end":1494204669752153,"diff":201255},{"start":1494204669774712,"end":1494204669976996,"diff":202284},{"start":1494204669998008,"end":1494204670202698,"diff":204690},{"start":1494204670222891,"end":1494204670426965,"diff":204074}],"now":1494204670432,"mem":{"start":{"process":{"rss":51458048,"heapTotal":29982720,"heapUsed":22320128,"external":123168},"os":562667520},"end":{"process":{"rss":70758400,"heapTotal":46419968,"heapUsed":30303632,"external":50244},"os":516837376}},"stats":{"moe":0.0005174109576310076,"rme":0.25500871164827577,"sem":0.00025214958948879514,"deviation":0.0013342502139487562,"mean":0.2028993261785714,"sample":[0.202616432,0.204446044,0.201342998,0.201239519,0.20347953,0.201571438,0.200416294,0.204617911,0.201022535,0.203290842,0.202577344,0.201999359,0.20257082,0.202467568,0.203942795,0.205661298,0.202823452,0.204721344,0.203680949,0.203760291,0.202652021,0.20353033,0.201249088,0.202601625,0.201421481,0.202484617,0.20480419,0.204189018],"variance":0.0000017802236334223018},"count":1,"hz":4.928552592234345,"time":202.89932617857139,"cycles":1,"battery":{"amperage":-2112,"currentCapacity":417,"percent":5,"charging":"","temp":3108}},{"msg":"sleep2 x 4.93 ops/sec ±0.26% (28 runs sampled)","name":"sleep2","num":4.93,"sampled":"28","variation":"0.26","tags":"fresh,MORETAGS,uniqd,4th","suite":["sleepy4"],"timesFor":[{"start":1494204664046405,"end":1494204664248856,"diff":202451},{"start":1494204664269007,"end":1494204664472779,"diff":203772},{"start":1494204664493824,"end":1494204664695056,"diff":201232},{"start":1494204664717430,"end":1494204664918564,"diff":201134},{"start":1494204664938362,"end":1494204665141726,"diff":203364},{"start":1494204665161660,"end":1494204665363127,"diff":201467},{"start":1494204665383433,"end":1494204665583744,"diff":200311},{"start":1494204665607500,"end":1494204665811968,"diff":204468},{"start":1494204665830077,"end":1494204666030996,"diff":200919},{"start":1494204666049729,"end":1494204666252904,"diff":203175},{"start":1494204666271303,"end":1494204666473764,"diff":202461},{"start":1494204666491464,"end":1494204666693320,"diff":201856},{"start":1494204666715736,"end":1494204666918139,"diff":202403},{"start":1494204666941743,"end":1494204667144003,"diff":202260},{"start":1494204667168448,"end":1494204667371940,"diff":203492},{"start":1494204667394518,"end":1494204667599947,"diff":205429},{"start":1494204667628262,"end":1494204667830908,"diff":202646},{"start":1494204667863427,"end":1494204668067920,"diff":204493},{"start":1494204668215258,"end":1494204668418782,"diff":203524},{"start":1494204668441079,"end":1494204668644675,"diff":203596},{"start":1494204668667325,"end":1494204668869855,"diff":202530},{"start":1494204668889008,"end":1494204669092384,"diff":203376},{"start":1494204669111339,"end":1494204669312478,"diff":201139},{"start":1494204669330320,"end":1494204669532813,"diff":202493},{"start":1494204669550898,"end":1494204669752153,"diff":201255},{"start":1494204669774712,"end":1494204669976996,"diff":202284},{"start":1494204669998008,"end":1494204670202698,"diff":204690},{"start":1494204670222891,"end":1494204670426965,"diff":204074}],"now":1494204670433,"mem":{"start":{"process":{"rss":51458048,"heapTotal":29982720,"heapUsed":22320128,"external":123168},"os":562667520},"end":{"process":{"rss":70758400,"heapTotal":46419968,"heapUsed":30307912,"external":50244},"os":516837376}},"stats":{"moe":0.0005174109576310076,"rme":0.25500871164827577,"sem":0.00025214958948879514,"deviation":0.0013342502139487562,"mean":0.2028993261785714,"sample":[0.202616432,0.204446044,0.201342998,0.201239519,0.20347953,0.201571438,0.200416294,0.204617911,0.201022535,0.203290842,0.202577344,0.201999359,0.20257082,0.202467568,0.203942795,0.205661298,0.202823452,0.204721344,0.203680949,0.203760291,0.202652021,0.20353033,0.201249088,0.202601625,0.201421481,0.202484617,0.20480419,0.204189018],"variance":0.0000017802236334223018},"count":1,"hz":4.928552592234345,"time":202.89932617857139,"cycles":1,"battery":{"amperage":-2112,"currentCapacity":417,"percent":5,"charging":"","temp":3108}},{"msg":"sleep2 x 4.87 ops/sec ±2.49% (27 runs sampled)","name":"sleep2","num":4.87,"sampled":"27","variation":"2.49","tags":"fresh,MORETAGS,uniqd,4th","suite":["sleepy4"],"timesFor":[{"start":1494204782800497,"end":1494204783001100,"diff":200603},{"start":1494204783021435,"end":1494204783221210,"diff":199775},{"start":1494204783240996,"end":1494204783441699,"diff":200703},{"start":1494204783461484,"end":1494204783666000,"diff":204516},{"start":1494204783687375,"end":1494204783894429,"diff":207054},{"start":1494204783915336,"end":1494204784118986,"diff":203650},{"start":1494204784147771,"end":1494204784350777,"diff":203006},{"start":1494204784377758,"end":1494204784578664,"diff":200906},{"start":1494204784608003,"end":1494204784813233,"diff":205230},{"start":1494204784835364,"end":1494204785040319,"diff":204955},{"start":1494204785063730,"end":1494204785264507,"diff":200777},{"start":1494204785294140,"end":1494204785496838,"diff":202698},{"start":1494204785522676,"end":1494204785722869,"diff":200193},{"start":1494204785741821,"end":1494204785944139,"diff":202318},{"start":1494204785962623,"end":1494204786164602,"diff":201979},{"start":1494204786200211,"end":1494204786402527,"diff":202316},{"start":1494204786432297,"end":1494204786635406,"diff":203109},{"start":1494204786675735,"end":1494204786945140,"diff":269405},{"start":1494204786982720,"end":1494204787185834,"diff":203114},{"start":1494204787207216,"end":1494204787409791,"diff":202575},{"start":1494204787431563,"end":1494204787633132,"diff":201569},{"start":1494204787657913,"end":1494204787863064,"diff":205151},{"start":1494204787882275,"end":1494204788086130,"diff":203855},{"start":1494204788103512,"end":1494204788307855,"diff":204343},{"start":1494204788326571,"end":1494204788531028,"diff":204457},{"start":1494204788549299,"end":1494204788754224,"diff":204925},{"start":1494204788772968,"end":1494204788975429,"diff":202461}],"now":1494204788981,"mem":{"start":{"process":{"rss":51888128,"heapTotal":29458432,"heapUsed":22067936,"external":123168},"os":296493056},"end":{"process":{"rss":69513216,"heapTotal":45371392,"heapUsed":33652368,"external":79760},"os":465141760}},"stats":{"moe":0.0051132724832223244,"rme":2.4876428492120706,"sem":0.0024870002350303134,"deviation":0.012922832296524727,"mean":0.2055468888888889,"sample":[0.200768,0.199897,0.200805,0.204623,0.207179,0.203775,0.203148,0.201078,0.205418,0.205116,0.200933,0.202989,0.200368,0.202428,0.202155,0.202528,0.203261,0.269584,0.203328,0.202718,0.201723,0.205302,0.203971,0.204444,0.204571,0.205056,0.2026],"variance":0.00016699959456410255},"count":1,"hz":4.865069986734576,"time":205.5468888888889,"cycles":1,"battery":{"amperage":-1630,"currentCapacity":375,"percent":4,"charging":"","temp":3108}},{"msg":"sleep2 x 4.87 ops/sec ±2.49% (27 runs sampled)","name":"sleep2","num":4.87,"sampled":"27","variation":"2.49","tags":"fresh,MORETAGS,uniqd,4th","suite":["sleepy4"],"timesFor":[{"start":1494204782800497,"end":1494204783001100,"diff":200603},{"start":1494204783021435,"end":1494204783221210,"diff":199775},{"start":1494204783240996,"end":1494204783441699,"diff":200703},{"start":1494204783461484,"end":1494204783666000,"diff":204516},{"start":1494204783687375,"end":1494204783894429,"diff":207054},{"start":1494204783915336,"end":1494204784118986,"diff":203650},{"start":1494204784147771,"end":1494204784350777,"diff":203006},{"start":1494204784377758,"end":1494204784578664,"diff":200906},{"start":1494204784608003,"end":1494204784813233,"diff":205230},{"start":1494204784835364,"end":1494204785040319,"diff":204955},{"start":1494204785063730,"end":1494204785264507,"diff":200777},{"start":1494204785294140,"end":1494204785496838,"diff":202698},{"start":1494204785522676,"end":1494204785722869,"diff":200193},{"start":1494204785741821,"end":1494204785944139,"diff":202318},{"start":1494204785962623,"end":1494204786164602,"diff":201979},{"start":1494204786200211,"end":1494204786402527,"diff":202316},{"start":1494204786432297,"end":1494204786635406,"diff":203109},{"start":1494204786675735,"end":1494204786945140,"diff":269405},{"start":1494204786982720,"end":1494204787185834,"diff":203114},{"start":1494204787207216,"end":1494204787409791,"diff":202575},{"start":1494204787431563,"end":1494204787633132,"diff":201569},{"start":1494204787657913,"end":1494204787863064,"diff":205151},{"start":1494204787882275,"end":1494204788086130,"diff":203855},{"start":1494204788103512,"end":1494204788307855,"diff":204343},{"start":1494204788326571,"end":1494204788531028,"diff":204457},{"start":1494204788549299,"end":1494204788754224,"diff":204925},{"start":1494204788772968,"end":1494204788975429,"diff":202461}],"now":1494204788981,"mem":{"start":{"process":{"rss":51888128,"heapTotal":29458432,"heapUsed":22067936,"external":123168},"os":296493056},"end":{"process":{"rss":69529600,"heapTotal":45895680,"heapUsed":33656752,"external":79760},"os":465141760}},"stats":{"moe":0.0051132724832223244,"rme":2.4876428492120706,"sem":0.0024870002350303134,"deviation":0.012922832296524727,"mean":0.2055468888888889,"sample":[0.200768,0.199897,0.200805,0.204623,0.207179,0.203775,0.203148,0.201078,0.205418,0.205116,0.200933,0.202989,0.200368,0.202428,0.202155,0.202528,0.203261,0.269584,0.203328,0.202718,0.201723,0.205302,0.203971,0.204444,0.204571,0.205056,0.2026],"variance":0.00016699959456410255},"count":1,"hz":4.865069986734576,"time":205.5468888888889,"cycles":1,"battery":{"amperage":-1630,"currentCapacity":375,"percent":4,"charging":"","temp":3108}},{"msg":"sleep2 x 4.92 ops/sec ±0.32% (28 runs sampled)","name":"sleep2","num":4.92,"sampled":"28","variation":"0.32","tags":"fresh,MORETAGS,uniqd,4th","suite":["sleepy4"],"timesFor":[{"start":1494206421875923,"end":1494206422081797,"diff":205874},{"start":1494206422100868,"end":1494206422301720,"diff":200852},{"start":1494206422319796,"end":1494206422521375,"diff":201579},{"start":1494206422541676,"end":1494206422745650,"diff":203974},{"start":1494206422762508,"end":1494206422963268,"diff":200760},{"start":1494206422980698,"end":1494206423185376,"diff":204678},{"start":1494206423202696,"end":1494206423402499,"diff":199803},{"start":1494206423422061,"end":1494206423628081,"diff":206020},{"start":1494206423644359,"end":1494206423848003,"diff":203644},{"start":1494206423864298,"end":1494206424069273,"diff":204975},{"start":1494206424085002,"end":1494206424287037,"diff":202035},{"start":1494206424304250,"end":1494206424509512,"diff":205262},{"start":1494206424527999,"end":1494206424729607,"diff":201608},{"start":1494206424747843,"end":1494206424951339,"diff":203496},{"start":1494206424968373,"end":1494206425172359,"diff":203986},{"start":1494206425191187,"end":1494206425395387,"diff":204200},{"start":1494206425413964,"end":1494206425618771,"diff":204807},{"start":1494206425651463,"end":1494206425853266,"diff":201803},{"start":1494206425874223,"end":1494206426075771,"diff":201548},{"start":1494206426095462,"end":1494206426299279,"diff":203817},{"start":1494206426318298,"end":1494206426523232,"diff":204934},{"start":1494206426540678,"end":1494206426744903,"diff":204225},{"start":1494206426759684,"end":1494206426964293,"diff":204609},{"start":1494206426983092,"end":1494206427187449,"diff":204357},{"start":1494206427204032,"end":1494206427406905,"diff":202873},{"start":1494206427423046,"end":1494206427625427,"diff":202381},{"start":1494206427640841,"end":1494206427843659,"diff":202818},{"start":1494206427860743,"end":1494206428062644,"diff":201901}],"now":1494206428068,"mem":{"start":{"process":{"rss":51400704,"heapTotal":29458432,"heapUsed":22338544,"external":123168},"os":290770944},"end":{"process":{"rss":70279168,"heapTotal":46419968,"heapUsed":30214360,"external":58436},"os":286081024}},"stats":{"moe":0.0006438969450492487,"rme":0.31655194026863054,"sem":0.0003137899342345267,"deviation":0.0016604202597997413,"mean":0.20340957142857138,"sample":[0.206004,0.20096,0.201665,0.204091,0.200836,0.204764,0.199873,0.206113,0.203715,0.205044,0.202108,0.205342,0.201696,0.203629,0.204066,0.204327,0.204886,0.201969,0.201653,0.203919,0.205107,0.204326,0.204676,0.204445,0.202938,0.202457,0.202892,0.201967],"variance":0.0000027569954391534406},"count":1,"hz":4.916189503654485,"time":203.40957142857138,"cycles":1,"battery":{"amperage":4335,"currentCapacity":1421,"percent":18,"charging":"","temp":3104}},{"msg":"sleep2 x 4.92 ops/sec ±0.32% (28 runs sampled)","name":"sleep2","num":4.92,"sampled":"28","variation":"0.32","tags":"fresh,MORETAGS,uniqd,4th","suite":["sleepy4"],"timesFor":[{"start":1494206421875923,"end":1494206422081797,"diff":205874},{"start":1494206422100868,"end":1494206422301720,"diff":200852},{"start":1494206422319796,"end":1494206422521375,"diff":201579},{"start":1494206422541676,"end":1494206422745650,"diff":203974},{"start":1494206422762508,"end":1494206422963268,"diff":200760},{"start":1494206422980698,"end":1494206423185376,"diff":204678},{"start":1494206423202696,"end":1494206423402499,"diff":199803},{"start":1494206423422061,"end":1494206423628081,"diff":206020},{"start":1494206423644359,"end":1494206423848003,"diff":203644},{"start":1494206423864298,"end":1494206424069273,"diff":204975},{"start":1494206424085002,"end":1494206424287037,"diff":202035},{"start":1494206424304250,"end":1494206424509512,"diff":205262},{"start":1494206424527999,"end":1494206424729607,"diff":201608},{"start":1494206424747843,"end":1494206424951339,"diff":203496},{"start":1494206424968373,"end":1494206425172359,"diff":203986},{"start":1494206425191187,"end":1494206425395387,"diff":204200},{"start":1494206425413964,"end":1494206425618771,"diff":204807},{"start":1494206425651463,"end":1494206425853266,"diff":201803},{"start":1494206425874223,"end":1494206426075771,"diff":201548},{"start":1494206426095462,"end":1494206426299279,"diff":203817},{"start":1494206426318298,"end":1494206426523232,"diff":204934},{"start":1494206426540678,"end":1494206426744903,"diff":204225},{"start":1494206426759684,"end":1494206426964293,"diff":204609},{"start":1494206426983092,"end":1494206427187449,"diff":204357},{"start":1494206427204032,"end":1494206427406905,"diff":202873},{"start":1494206427423046,"end":1494206427625427,"diff":202381},{"start":1494206427640841,"end":1494206427843659,"diff":202818},{"start":1494206427860743,"end":1494206428062644,"diff":201901}],"now":1494206428068,"mem":{"start":{"process":{"rss":51400704,"heapTotal":29458432,"heapUsed":22338544,"external":123168},"os":290770944},"end":{"process":{"rss":70279168,"heapTotal":46419968,"heapUsed":30218688,"external":58436},"os":286081024}},"stats":{"moe":0.0006438969450492487,"rme":0.31655194026863054,"sem":0.0003137899342345267,"deviation":0.0016604202597997413,"mean":0.20340957142857138,"sample":[0.206004,0.20096,0.201665,0.204091,0.200836,0.204764,0.199873,0.206113,0.203715,0.205044,0.202108,0.205342,0.201696,0.203629,0.204066,0.204327,0.204886,0.201969,0.201653,0.203919,0.205107,0.204326,0.204676,0.204445,0.202938,0.202457,0.202892,0.201967],"variance":0.0000027569954391534406},"count":1,"hz":4.916189503654485,"time":203.40957142857138,"cycles":1,"battery":{"amperage":4335,"currentCapacity":1421,"percent":18,"charging":"","temp":3104}},{"msg":"sleep2 x 4.94 ops/sec ±0.34% (28 runs sampled)","name":"sleep2","num":4.94,"sampled":"28","variation":"0.34","tags":"fresh,MORETAGS,uniqd,4th","suite":["sleepy4"],"timesFor":[{"start":1494206704294685,"end":1494206704496081,"diff":201396},{"start":1494206704512943,"end":1494206704716730,"diff":203787},{"start":1494206704734028,"end":1494206704937291,"diff":203263},{"start":1494206704955927,"end":1494206705157919,"diff":201992},{"start":1494206705173439,"end":1494206705378550,"diff":205111},{"start":1494206705393955,"end":1494206705597797,"diff":203842},{"start":1494206705617218,"end":1494206705818062,"diff":200844},{"start":1494206705839007,"end":1494206706040128,"diff":201121},{"start":1494206706056613,"end":1494206706260743,"diff":204130},{"start":1494206706277838,"end":1494206706478474,"diff":200636},{"start":1494206706495020,"end":1494206706697752,"diff":202732},{"start":1494206706714535,"end":1494206706916807,"diff":202272},{"start":1494206706938663,"end":1494206707138828,"diff":200165},{"start":1494206707158907,"end":1494206707361052,"diff":202145},{"start":1494206707378973,"end":1494206707582611,"diff":203638},{"start":1494206707601240,"end":1494206707801639,"diff":200399},{"start":1494206707818914,"end":1494206708023909,"diff":204995},{"start":1494206708046466,"end":1494206708251981,"diff":205515},{"start":1494206708270999,"end":1494206708472418,"diff":201419},{"start":1494206708489946,"end":1494206708693389,"diff":203443},{"start":1494206708710546,"end":1494206708914775,"diff":204229},{"start":1494206708932910,"end":1494206709133373,"diff":200463},{"start":1494206709150911,"end":1494206709351594,"diff":200683},{"start":1494206709371007,"end":1494206709571162,"diff":200155},{"start":1494206709591317,"end":1494206709791751,"diff":200434},{"start":1494206709820672,"end":1494206710020930,"diff":200258},{"start":1494206710039702,"end":1494206710244893,"diff":205191},{"start":1494206710264049,"end":1494206710468251,"diff":204202}],"now":1494206710473,"mem":{"start":{"process":{"rss":46014464,"heapTotal":27852800,"heapUsed":15498304,"external":1547286},"os":375263232},"end":{"process":{"rss":62287872,"heapTotal":29642752,"heapUsed":17926616,"external":17476},"os":176971776}},"stats":{"moe":0.0006954143541643329,"rme":0.34334885388051595,"sem":0.0003388958840956788,"deviation":0.0017932684593210716,"mean":0.20253871428571432,"sample":[0.201549,0.203866,0.203339,0.202059,0.205178,0.203913,0.200983,0.201197,0.204214,0.200702,0.202802,0.202344,0.200276,0.202215,0.203711,0.200471,0.205054,0.205606,0.201498,0.203508,0.204486,0.20054,0.200758,0.200245,0.200509,0.20048,0.205292,0.204289],"variance":0.0000032158117671957703},"count":1,"hz":4.937327678447365,"time":202.53871428571432,"cycles":1,"battery":{"amperage":3598,"currentCapacity":1670,"percent":22,"charging":"","temp":3108}},{"msg":"sleep2 x 4.94 ops/sec ±0.34% (28 runs sampled)","name":"sleep2","num":4.94,"sampled":"28","variation":"0.34","tags":"fresh,MORETAGS,uniqd,4th","suite":["sleepy4"],"timesFor":[{"start":1494206704294685,"end":1494206704496081,"diff":201396},{"start":1494206704512943,"end":1494206704716730,"diff":203787},{"start":1494206704734028,"end":1494206704937291,"diff":203263},{"start":1494206704955927,"end":1494206705157919,"diff":201992},{"start":1494206705173439,"end":1494206705378550,"diff":205111},{"start":1494206705393955,"end":1494206705597797,"diff":203842},{"start":1494206705617218,"end":1494206705818062,"diff":200844},{"start":1494206705839007,"end":1494206706040128,"diff":201121},{"start":1494206706056613,"end":1494206706260743,"diff":204130},{"start":1494206706277838,"end":1494206706478474,"diff":200636},{"start":1494206706495020,"end":1494206706697752,"diff":202732},{"start":1494206706714535,"end":1494206706916807,"diff":202272},{"start":1494206706938663,"end":1494206707138828,"diff":200165},{"start":1494206707158907,"end":1494206707361052,"diff":202145},{"start":1494206707378973,"end":1494206707582611,"diff":203638},{"start":1494206707601240,"end":1494206707801639,"diff":200399},{"start":1494206707818914,"end":1494206708023909,"diff":204995},{"start":1494206708046466,"end":1494206708251981,"diff":205515},{"start":1494206708270999,"end":1494206708472418,"diff":201419},{"start":1494206708489946,"end":1494206708693389,"diff":203443},{"start":1494206708710546,"end":1494206708914775,"diff":204229},{"start":1494206708932910,"end":1494206709133373,"diff":200463},{"start":1494206709150911,"end":1494206709351594,"diff":200683},{"start":1494206709371007,"end":1494206709571162,"diff":200155},{"start":1494206709591317,"end":1494206709791751,"diff":200434},{"start":1494206709820672,"end":1494206710020930,"diff":200258},{"start":1494206710039702,"end":1494206710244893,"diff":205191},{"start":1494206710264049,"end":1494206710468251,"diff":204202}],"now":1494206710474,"mem":{"start":{"process":{"rss":46014464,"heapTotal":27852800,"heapUsed":15498304,"external":1547286},"os":375263232},"end":{"process":{"rss":62287872,"heapTotal":29642752,"heapUsed":17931608,"external":17476},"os":176971776}},"stats":{"moe":0.0006954143541643329,"rme":0.34334885388051595,"sem":0.0003388958840956788,"deviation":0.0017932684593210716,"mean":0.20253871428571432,"sample":[0.201549,0.203866,0.203339,0.202059,0.205178,0.203913,0.200983,0.201197,0.204214,0.200702,0.202802,0.202344,0.200276,0.202215,0.203711,0.200471,0.205054,0.205606,0.201498,0.203508,0.204486,0.20054,0.200758,0.200245,0.200509,0.20048,0.205292,0.204289],"variance":0.0000032158117671957703},"count":1,"hz":4.937327678447365,"time":202.53871428571432,"cycles":1,"battery":{"amperage":3598,"currentCapacity":1670,"percent":22,"charging":"","temp":3108}}],"sleep200 4":[{"msg":"sleep200 4 x 4.92 ops/sec ±0.25% (28 runs sampled)","name":"sleep200 4","num":4.92,"sampled":"28","variation":"0.25","tags":"fresh,MORETAGS,uniqd,4th","suite":["sleepy4"],"timesFor":[{"start":1494204483368169,"end":1494204483571331,"diff":203162},{"start":1494204483589480,"end":1494204483792080,"diff":202600},{"start":1494204483810297,"end":1494204484012487,"diff":202190},{"start":1494204484028633,"end":1494204484233103,"diff":204470},{"start":1494204484251025,"end":1494204484453668,"diff":202643},{"start":1494204484471017,"end":1494204484674359,"diff":203342},{"start":1494204484691428,"end":1494204484894963,"diff":203535},{"start":1494204484912155,"end":1494204485113509,"diff":201354},{"start":1494204485128480,"end":1494204485330281,"diff":201801},{"start":1494204485348047,"end":1494204485552570,"diff":204523},{"start":1494204485569762,"end":1494204485771354,"diff":201592},{"start":1494204485787711,"end":1494204485991971,"diff":204260},{"start":1494204486008461,"end":1494204486212755,"diff":204294},{"start":1494204486229228,"end":1494204486429672,"diff":200444},{"start":1494204486448073,"end":1494204486652176,"diff":204103},{"start":1494204486668437,"end":1494204486872611,"diff":204174},{"start":1494204486890388,"end":1494204487091610,"diff":201222},{"start":1494204487110566,"end":1494204487315427,"diff":204861},{"start":1494204487331439,"end":1494204487536303,"diff":204864},{"start":1494204487552588,"end":1494204487756626,"diff":204038},{"start":1494204487773693,"end":1494204487977308,"diff":203615},{"start":1494204487997518,"end":1494204488199567,"diff":202049},{"start":1494204488220698,"end":1494204488424080,"diff":203382},{"start":1494204488444142,"end":1494204488644926,"diff":200784},{"start":1494204488662692,"end":1494204488865376,"diff":202684},{"start":1494204488898938,"end":1494204489103610,"diff":204672},{"start":1494204489125636,"end":1494204489329675,"diff":204039},{"start":1494204489346981,"end":1494204489550503,"diff":203522}],"now":1494204489556,"mem":{"start":{"process":{"rss":51810304,"heapTotal":29458432,"heapUsed":22156664,"external":123168},"os":261259264},"end":{"process":{"rss":43954176,"heapTotal":20205568,"heapUsed":17624248,"external":9284},"os":357314560}},"stats":{"moe":0.0005008410326101894,"rme":0.2464234400983284,"sem":0.00024407457729541397,"deviation":0.0012915212657537546,"mean":0.2032440714285714,"sample":[0.203294,0.202706,0.202295,0.204533,0.202722,0.203426,0.203651,0.201438,0.201865,0.204606,0.201667,0.204346,0.20438,0.200515,0.204185,0.20425,0.201385,0.204935,0.204957,0.204123,0.203716,0.202221,0.203468,0.200867,0.202808,0.204759,0.204108,0.203608],"variance":0.0000016680271798941805},"count":1,"hz":4.920192716919876,"time":203.2440714285714,"cycles":1,"battery":{"amperage":-2340,"currentCapacity":516,"percent":6,"charging":"","temp":3108}},{"msg":"sleep200 4 x 4.92 ops/sec ±0.25% (28 runs sampled)","name":"sleep200 4","num":4.92,"sampled":"28","variation":"0.25","tags":"fresh,MORETAGS,uniqd,4th","suite":["sleepy4"],"timesFor":[{"start":1494204483368169,"end":1494204483571331,"diff":203162},{"start":1494204483589480,"end":1494204483792080,"diff":202600},{"start":1494204483810297,"end":1494204484012487,"diff":202190},{"start":1494204484028633,"end":1494204484233103,"diff":204470},{"start":1494204484251025,"end":1494204484453668,"diff":202643},{"start":1494204484471017,"end":1494204484674359,"diff":203342},{"start":1494204484691428,"end":1494204484894963,"diff":203535},{"start":1494204484912155,"end":1494204485113509,"diff":201354},{"start":1494204485128480,"end":1494204485330281,"diff":201801},{"start":1494204485348047,"end":1494204485552570,"diff":204523},{"start":1494204485569762,"end":1494204485771354,"diff":201592},{"start":1494204485787711,"end":1494204485991971,"diff":204260},{"start":1494204486008461,"end":1494204486212755,"diff":204294},{"start":1494204486229228,"end":1494204486429672,"diff":200444},{"start":1494204486448073,"end":1494204486652176,"diff":204103},{"start":1494204486668437,"end":1494204486872611,"diff":204174},{"start":1494204486890388,"end":1494204487091610,"diff":201222},{"start":1494204487110566,"end":1494204487315427,"diff":204861},{"start":1494204487331439,"end":1494204487536303,"diff":204864},{"start":1494204487552588,"end":1494204487756626,"diff":204038},{"start":1494204487773693,"end":1494204487977308,"diff":203615},{"start":1494204487997518,"end":1494204488199567,"diff":202049},{"start":1494204488220698,"end":1494204488424080,"diff":203382},{"start":1494204488444142,"end":1494204488644926,"diff":200784},{"start":1494204488662692,"end":1494204488865376,"diff":202684},{"start":1494204488898938,"end":1494204489103610,"diff":204672},{"start":1494204489125636,"end":1494204489329675,"diff":204039},{"start":1494204489346981,"end":1494204489550503,"diff":203522}],"now":1494204489556,"mem":{"start":{"process":{"rss":51810304,"heapTotal":29458432,"heapUsed":22156664,"external":123168},"os":261259264},"end":{"process":{"rss":43954176,"heapTotal":20205568,"heapUsed":17627696,"external":9284},"os":357314560}},"stats":{"moe":0.0005008410326101894,"rme":0.2464234400983284,"sem":0.00024407457729541397,"deviation":0.0012915212657537546,"mean":0.2032440714285714,"sample":[0.203294,0.202706,0.202295,0.204533,0.202722,0.203426,0.203651,0.201438,0.201865,0.204606,0.201667,0.204346,0.20438,0.200515,0.204185,0.20425,0.201385,0.204935,0.204957,0.204123,0.203716,0.202221,0.203468,0.200867,0.202808,0.204759,0.204108,0.203608],"variance":0.0000016680271798941805},"count":1,"hz":4.920192716919876,"time":203.2440714285714,"cycles":1,"battery":{"amperage":-2340,"currentCapacity":516,"percent":6,"charging":"","temp":3108}},{"msg":"sleep200 4 x 4.94 ops/sec ±0.36% (28 runs sampled)","name":"sleep200 4","num":4.94,"sampled":"28","variation":"0.36","tags":"fresh,MORETAGS,uniqd,4th","suite":["sleepy4"],"timesFor":[{"start":1494204506920957,"end":1494204507121375,"diff":200418},{"start":1494204507140007,"end":1494204507345411,"diff":205404},{"start":1494204507364514,"end":1494204507564865,"diff":200351},{"start":1494204507583169,"end":1494204507787763,"diff":204594},{"start":1494204507804131,"end":1494204508006625,"diff":202494},{"start":1494204508023909,"end":1494204508224096,"diff":200187},{"start":1494204508243210,"end":1494204508448262,"diff":205052},{"start":1494204508466274,"end":1494204508666635,"diff":200361},{"start":1494204508682480,"end":1494204508886004,"diff":203524},{"start":1494204508902336,"end":1494204509102309,"diff":199973},{"start":1494204509118115,"end":1494204509321466,"diff":203351},{"start":1494204509337298,"end":1494204509537932,"diff":200634},{"start":1494204509556515,"end":1494204509761556,"diff":205041},{"start":1494204509779172,"end":1494204509983073,"diff":203901},{"start":1494204509998063,"end":1494204510200583,"diff":202520},{"start":1494204510218001,"end":1494204510421676,"diff":203675},{"start":1494204510437189,"end":1494204510639671,"diff":202482},{"start":1494204510657314,"end":1494204510857221,"diff":199907},{"start":1494204510875367,"end":1494204511078633,"diff":203266},{"start":1494204511095443,"end":1494204511300651,"diff":205208},{"start":1494204511318758,"end":1494204511520899,"diff":202141},{"start":1494204511536942,"end":1494204511741907,"diff":204965},{"start":1494204511757346,"end":1494204511959135,"diff":201789},{"start":1494204511978297,"end":1494204512178105,"diff":199808},{"start":1494204512195889,"end":1494204512397779,"diff":201890},{"start":1494204512413969,"end":1494204512615251,"diff":201282},{"start":1494204512636227,"end":1494204512836940,"diff":200713},{"start":1494204512851913,"end":1494204513053893,"diff":201980}],"now":1494204513059,"mem":{"start":{"process":{"rss":52060160,"heapTotal":29458432,"heapUsed":22363008,"external":123168},"os":344244224},"end":{"process":{"rss":74072064,"heapTotal":50089984,"heapUsed":31696696,"external":33860},"os":276226048}},"stats":{"moe":0.0007200970626122797,"rme":0.35563090265002156,"sem":0.0003509244944504287,"deviation":0.0018569178825538007,"mean":0.20248438964285714,"sample":[0.200503501,0.205494044,0.200476258,0.204674716,0.202572493,0.200288079,0.205160395,0.200497941,0.203593529,0.200046438,0.203472224,0.200705747,0.205173045,0.203976747,0.202595585,0.203757523,0.20254945,0.200019396,0.203361952,0.205277677,0.20225364,0.205103272,0.201890861,0.199949526,0.20197773,0.201358588,0.200784444,0.202048109],"variance":0.0000034481440225480908},"count":1,"hz":4.938652316673914,"time":202.48438964285714,"cycles":1,"battery":{"amperage":-2451,"currentCapacity":475,"percent":6,"charging":"","temp":3108}},{"msg":"sleep200 4 x 4.94 ops/sec ±0.36% (28 runs sampled)","name":"sleep200 4","num":4.94,"sampled":"28","variation":"0.36","tags":"fresh,MORETAGS,uniqd,4th","suite":["sleepy4"],"timesFor":[{"start":1494204506920957,"end":1494204507121375,"diff":200418},{"start":1494204507140007,"end":1494204507345411,"diff":205404},{"start":1494204507364514,"end":1494204507564865,"diff":200351},{"start":1494204507583169,"end":1494204507787763,"diff":204594},{"start":1494204507804131,"end":1494204508006625,"diff":202494},{"start":1494204508023909,"end":1494204508224096,"diff":200187},{"start":1494204508243210,"end":1494204508448262,"diff":205052},{"start":1494204508466274,"end":1494204508666635,"diff":200361},{"start":1494204508682480,"end":1494204508886004,"diff":203524},{"start":1494204508902336,"end":1494204509102309,"diff":199973},{"start":1494204509118115,"end":1494204509321466,"diff":203351},{"start":1494204509337298,"end":1494204509537932,"diff":200634},{"start":1494204509556515,"end":1494204509761556,"diff":205041},{"start":1494204509779172,"end":1494204509983073,"diff":203901},{"start":1494204509998063,"end":1494204510200583,"diff":202520},{"start":1494204510218001,"end":1494204510421676,"diff":203675},{"start":1494204510437189,"end":1494204510639671,"diff":202482},{"start":1494204510657314,"end":1494204510857221,"diff":199907},{"start":1494204510875367,"end":1494204511078633,"diff":203266},{"start":1494204511095443,"end":1494204511300651,"diff":205208},{"start":1494204511318758,"end":1494204511520899,"diff":202141},{"start":1494204511536942,"end":1494204511741907,"diff":204965},{"start":1494204511757346,"end":1494204511959135,"diff":201789},{"start":1494204511978297,"end":1494204512178105,"diff":199808},{"start":1494204512195889,"end":1494204512397779,"diff":201890},{"start":1494204512413969,"end":1494204512615251,"diff":201282},{"start":1494204512636227,"end":1494204512836940,"diff":200713},{"start":1494204512851913,"end":1494204513053893,"diff":201980}],"now":1494204513059,"mem":{"start":{"process":{"rss":52060160,"heapTotal":29458432,"heapUsed":22363008,"external":123168},"os":344244224},"end":{"process":{"rss":74072064,"heapTotal":50089984,"heapUsed":31699368,"external":33860},"os":276226048}},"stats":{"moe":0.0007200970626122797,"rme":0.35563090265002156,"sem":0.0003509244944504287,"deviation":0.0018569178825538007,"mean":0.20248438964285714,"sample":[0.200503501,0.205494044,0.200476258,0.204674716,0.202572493,0.200288079,0.205160395,0.200497941,0.203593529,0.200046438,0.203472224,0.200705747,0.205173045,0.203976747,0.202595585,0.203757523,0.20254945,0.200019396,0.203361952,0.205277677,0.20225364,0.205103272,0.201890861,0.199949526,0.20197773,0.201358588,0.200784444,0.202048109],"variance":0.0000034481440225480908},"count":1,"hz":4.938652316673914,"time":202.48438964285714,"cycles":1,"battery":{"amperage":-2451,"currentCapacity":475,"percent":6,"charging":"","temp":3108}},{"msg":"sleep200 4 x 4.93 ops/sec ±0.29% (28 runs sampled)","name":"sleep200 4","num":4.93,"sampled":"28","variation":"0.29","tags":"fresh,MORETAGS,uniqd,4th","suite":["sleepy4"],"timesFor":[{"start":1494204676963857,"end":1494204677166738,"diff":202881},{"start":1494204677191309,"end":1494204677394182,"diff":202873},{"start":1494204677416688,"end":1494204677620732,"diff":204044},{"start":1494204677643890,"end":1494204677843378,"diff":199488},{"start":1494204677869654,"end":1494204678070595,"diff":200941},{"start":1494204678089659,"end":1494204678292215,"diff":202556},{"start":1494204678314698,"end":1494204678519054,"diff":204356},{"start":1494204678538926,"end":1494204678742207,"diff":203281},{"start":1494204678762735,"end":1494204678965078,"diff":202343},{"start":1494204678983774,"end":1494204679186134,"diff":202360},{"start":1494204679203598,"end":1494204679408518,"diff":204920},{"start":1494204679428004,"end":1494204679633215,"diff":205211},{"start":1494204679651791,"end":1494204679854249,"diff":202458},{"start":1494204679873837,"end":1494204680075062,"diff":201225},{"start":1494204680093258,"end":1494204680297184,"diff":203926},{"start":1494204680317573,"end":1494204680521227,"diff":203654},{"start":1494204680543748,"end":1494204680747582,"diff":203834},{"start":1494204680767678,"end":1494204680971667,"diff":203989},{"start":1494204680990240,"end":1494204681194745,"diff":204505},{"start":1494204681216360,"end":1494204681420950,"diff":204590},{"start":1494204681441574,"end":1494204681644318,"diff":202744},{"start":1494204681661784,"end":1494204681866207,"diff":204423},{"start":1494204681884597,"end":1494204682088511,"diff":203914},{"start":1494204682108366,"end":1494204682309139,"diff":200773},{"start":1494204682328151,"end":1494204682528822,"diff":200671},{"start":1494204682549056,"end":1494204682750309,"diff":201253},{"start":1494204682768175,"end":1494204682968874,"diff":200699},{"start":1494204682989686,"end":1494204683191900,"diff":202214}],"now":1494204683197,"mem":{"start":{"process":{"rss":51458048,"heapTotal":29982720,"heapUsed":22320128,"external":123168},"os":562667520},"end":{"process":{"rss":48283648,"heapTotal":23351296,"heapUsed":18791584,"external":9284},"os":434438144}},"stats":{"moe":0.0005930312484938535,"rme":0.2921513344236004,"sem":0.00028900158308667323,"deviation":0.0015292526347026158,"mean":0.20298769117857143,"sample":[0.203070109,0.203023495,0.204220774,0.199590439,0.201049977,0.20267141,0.204506129,0.203384902,0.202444012,0.202467198,0.205069354,0.205374443,0.202565414,0.201330175,0.204027169,0.203762922,0.203993286,0.20408953,0.204661731,0.204695159,0.202851124,0.204524296,0.204071216,0.20088716,0.200775608,0.201380359,0.200801652,0.20236631],"variance":0.0000023386136207448924},"count":1,"hz":4.926407085049726,"time":202.98769117857142,"cycles":1,"battery":{"amperage":-2112,"currentCapacity":417,"percent":5,"charging":"","temp":3108}},{"msg":"sleep200 4 x 4.93 ops/sec ±0.29% (28 runs sampled)","name":"sleep200 4","num":4.93,"sampled":"28","variation":"0.29","tags":"fresh,MORETAGS,uniqd,4th","suite":["sleepy4"],"timesFor":[{"start":1494204676963857,"end":1494204677166738,"diff":202881},{"start":1494204677191309,"end":1494204677394182,"diff":202873},{"start":1494204677416688,"end":1494204677620732,"diff":204044},{"start":1494204677643890,"end":1494204677843378,"diff":199488},{"start":1494204677869654,"end":1494204678070595,"diff":200941},{"start":1494204678089659,"end":1494204678292215,"diff":202556},{"start":1494204678314698,"end":1494204678519054,"diff":204356},{"start":1494204678538926,"end":1494204678742207,"diff":203281},{"start":1494204678762735,"end":1494204678965078,"diff":202343},{"start":1494204678983774,"end":1494204679186134,"diff":202360},{"start":1494204679203598,"end":1494204679408518,"diff":204920},{"start":1494204679428004,"end":1494204679633215,"diff":205211},{"start":1494204679651791,"end":1494204679854249,"diff":202458},{"start":1494204679873837,"end":1494204680075062,"diff":201225},{"start":1494204680093258,"end":1494204680297184,"diff":203926},{"start":1494204680317573,"end":1494204680521227,"diff":203654},{"start":1494204680543748,"end":1494204680747582,"diff":203834},{"start":1494204680767678,"end":1494204680971667,"diff":203989},{"start":1494204680990240,"end":1494204681194745,"diff":204505},{"start":1494204681216360,"end":1494204681420950,"diff":204590},{"start":1494204681441574,"end":1494204681644318,"diff":202744},{"start":1494204681661784,"end":1494204681866207,"diff":204423},{"start":1494204681884597,"end":1494204682088511,"diff":203914},{"start":1494204682108366,"end":1494204682309139,"diff":200773},{"start":1494204682328151,"end":1494204682528822,"diff":200671},{"start":1494204682549056,"end":1494204682750309,"diff":201253},{"start":1494204682768175,"end":1494204682968874,"diff":200699},{"start":1494204682989686,"end":1494204683191900,"diff":202214}],"now":1494204683197,"mem":{"start":{"process":{"rss":51458048,"heapTotal":29982720,"heapUsed":22320128,"external":123168},"os":562667520},"end":{"process":{"rss":48287744,"heapTotal":23351296,"heapUsed":18796608,"external":9284},"os":434438144}},"stats":{"moe":0.0005930312484938535,"rme":0.2921513344236004,"sem":0.00028900158308667323,"deviation":0.0015292526347026158,"mean":0.20298769117857143,"sample":[0.203070109,0.203023495,0.204220774,0.199590439,0.201049977,0.20267141,0.204506129,0.203384902,0.202444012,0.202467198,0.205069354,0.205374443,0.202565414,0.201330175,0.204027169,0.203762922,0.203993286,0.20408953,0.204661731,0.204695159,0.202851124,0.204524296,0.204071216,0.20088716,0.200775608,0.201380359,0.200801652,0.20236631],"variance":0.0000023386136207448924},"count":1,"hz":4.926407085049726,"time":202.98769117857142,"cycles":1,"battery":{"amperage":-2112,"currentCapacity":417,"percent":5,"charging":"","temp":3108}},{"msg":"sleep200 4 x 4.93 ops/sec ±0.29% (28 runs sampled)","name":"sleep200 4","num":4.93,"sampled":"28","variation":"0.29","tags":"fresh,MORETAGS,uniqd,4th","suite":["sleepy4"],"timesFor":[{"start":1494204795444863,"end":1494204795646086,"diff":201223},{"start":1494204795667080,"end":1494204795870556,"diff":203476},{"start":1494204795890110,"end":1494204796090847,"diff":200737},{"start":1494204796110316,"end":1494204796312745,"diff":202429},{"start":1494204796339992,"end":1494204796541571,"diff":201579},{"start":1494204796561653,"end":1494204796765329,"diff":203676},{"start":1494204796783358,"end":1494204796988231,"diff":204873},{"start":1494204797007222,"end":1494204797212311,"diff":205089},{"start":1494204797232870,"end":1494204797435972,"diff":203102},{"start":1494204797455594,"end":1494204797657386,"diff":201792},{"start":1494204797692537,"end":1494204797894759,"diff":202222},{"start":1494204797916912,"end":1494204798121553,"diff":204641},{"start":1494204798146499,"end":1494204798348713,"diff":202214},{"start":1494204798372829,"end":1494204798573314,"diff":200485},{"start":1494204798599462,"end":1494204798801890,"diff":202428},{"start":1494204798822467,"end":1494204799026765,"diff":204298},{"start":1494204799046548,"end":1494204799249876,"diff":203328},{"start":1494204799268468,"end":1494204799472568,"diff":204100},{"start":1494204799492366,"end":1494204799697287,"diff":204921},{"start":1494204799714607,"end":1494204799917592,"diff":202985},{"start":1494204799935519,"end":1494204800137097,"diff":201578},{"start":1494204800155670,"end":1494204800360419,"diff":204749},{"start":1494204800378872,"end":1494204800580884,"diff":202012},{"start":1494204800600349,"end":1494204800805580,"diff":205231},{"start":1494204800823804,"end":1494204801026024,"diff":202220},{"start":1494204801043658,"end":1494204801246697,"diff":203039},{"start":1494204801264887,"end":1494204801467179,"diff":202292},{"start":1494204801499001,"end":1494204801698875,"diff":199874}],"now":1494204801704,"mem":{"start":{"process":{"rss":51888128,"heapTotal":29458432,"heapUsed":22067936,"external":123168},"os":296493056},"end":{"process":{"rss":76853248,"heapTotal":52711424,"heapUsed":36786016,"external":33860},"os":538857472}},"stats":{"moe":0.0005822932399382061,"rme":0.2868035436644092,"sem":0.0002837686354474689,"deviation":0.0015015624785483014,"mean":0.20302860714285714,"sample":[0.201355,0.203586,0.200916,0.202692,0.201689,0.203817,0.204978,0.205283,0.203279,0.201904,0.202366,0.205255,0.202369,0.20066,0.202567,0.204407,0.203454,0.204198,0.205027,0.203092,0.201679,0.204858,0.202124,0.205348,0.202333,0.20316,0.202412,0.199993],"variance":0.000002254689876984118},"count":1,"hz":4.925414275715192,"time":203.02860714285714,"cycles":1,"battery":{"amperage":-1630,"currentCapacity":375,"percent":4,"charging":"","temp":3108}},{"msg":"sleep200 4 x 4.93 ops/sec ±0.29% (28 runs sampled)","name":"sleep200 4","num":4.93,"sampled":"28","variation":"0.29","tags":"fresh,MORETAGS,uniqd,4th","suite":["sleepy4"],"timesFor":[{"start":1494204795444863,"end":1494204795646086,"diff":201223},{"start":1494204795667080,"end":1494204795870556,"diff":203476},{"start":1494204795890110,"end":1494204796090847,"diff":200737},{"start":1494204796110316,"end":1494204796312745,"diff":202429},{"start":1494204796339992,"end":1494204796541571,"diff":201579},{"start":1494204796561653,"end":1494204796765329,"diff":203676},{"start":1494204796783358,"end":1494204796988231,"diff":204873},{"start":1494204797007222,"end":1494204797212311,"diff":205089},{"start":1494204797232870,"end":1494204797435972,"diff":203102},{"start":1494204797455594,"end":1494204797657386,"diff":201792},{"start":1494204797692537,"end":1494204797894759,"diff":202222},{"start":1494204797916912,"end":1494204798121553,"diff":204641},{"start":1494204798146499,"end":1494204798348713,"diff":202214},{"start":1494204798372829,"end":1494204798573314,"diff":200485},{"start":1494204798599462,"end":1494204798801890,"diff":202428},{"start":1494204798822467,"end":1494204799026765,"diff":204298},{"start":1494204799046548,"end":1494204799249876,"diff":203328},{"start":1494204799268468,"end":1494204799472568,"diff":204100},{"start":1494204799492366,"end":1494204799697287,"diff":204921},{"start":1494204799714607,"end":1494204799917592,"diff":202985},{"start":1494204799935519,"end":1494204800137097,"diff":201578},{"start":1494204800155670,"end":1494204800360419,"diff":204749},{"start":1494204800378872,"end":1494204800580884,"diff":202012},{"start":1494204800600349,"end":1494204800805580,"diff":205231},{"start":1494204800823804,"end":1494204801026024,"diff":202220},{"start":1494204801043658,"end":1494204801246697,"diff":203039},{"start":1494204801264887,"end":1494204801467179,"diff":202292},{"start":1494204801499001,"end":1494204801698875,"diff":199874}],"now":1494204801704,"mem":{"start":{"process":{"rss":51888128,"heapTotal":29458432,"heapUsed":22067936,"external":123168},"os":296493056},"end":{"process":{"rss":76853248,"heapTotal":52711424,"heapUsed":36788736,"external":33860},"os":538857472}},"stats":{"moe":0.0005822932399382061,"rme":0.2868035436644092,"sem":0.0002837686354474689,"deviation":0.0015015624785483014,"mean":0.20302860714285714,"sample":[0.201355,0.203586,0.200916,0.202692,0.201689,0.203817,0.204978,0.205283,0.203279,0.201904,0.202366,0.205255,0.202369,0.20066,0.202567,0.204407,0.203454,0.204198,0.205027,0.203092,0.201679,0.204858,0.202124,0.205348,0.202333,0.20316,0.202412,0.199993],"variance":0.000002254689876984118},"count":1,"hz":4.925414275715192,"time":203.02860714285714,"cycles":1,"battery":{"amperage":-1630,"currentCapacity":375,"percent":4,"charging":"","temp":3108}},{"msg":"sleep200 4 x 4.93 ops/sec ±0.31% (28 runs sampled)","name":"sleep200 4","num":4.93,"sampled":"28","variation":"0.31","tags":"fresh,MORETAGS,uniqd,4th","suite":["sleepy4"],"timesFor":[{"start":1494206434516513,"end":1494206434717085,"diff":200572},{"start":1494206434735905,"end":1494206434941292,"diff":205387},{"start":1494206434960559,"end":1494206435161915,"diff":201356},{"start":1494206435181442,"end":1494206435385109,"diff":203667},{"start":1494206435406442,"end":1494206435609992,"diff":203550},{"start":1494206435628984,"end":1494206435829547,"diff":200563},{"start":1494206435849373,"end":1494206436049892,"diff":200519},{"start":1494206436068475,"end":1494206436271279,"diff":202804},{"start":1494206436288452,"end":1494206436492109,"diff":203657},{"start":1494206436510239,"end":1494206436714498,"diff":204259},{"start":1494206436732496,"end":1494206436937257,"diff":204761},{"start":1494206436954986,"end":1494206437158958,"diff":203972},{"start":1494206437175976,"end":1494206437377458,"diff":201482},{"start":1494206437395412,"end":1494206437599878,"diff":204466},{"start":1494206437616087,"end":1494206437820495,"diff":204408},{"start":1494206437838555,"end":1494206438041729,"diff":203174},{"start":1494206438059471,"end":1494206438261630,"diff":202159},{"start":1494206438278035,"end":1494206438482251,"diff":204216},{"start":1494206438500385,"end":1494206438703873,"diff":203488},{"start":1494206438721600,"end":1494206438923574,"diff":201974},{"start":1494206438939905,"end":1494206439143974,"diff":204069},{"start":1494206439161409,"end":1494206439362146,"diff":200737},{"start":1494206439380012,"end":1494206439585168,"diff":205156},{"start":1494206439601488,"end":1494206439805429,"diff":203941},{"start":1494206439823796,"end":1494206440027344,"diff":203548},{"start":1494206440046694,"end":1494206440250886,"diff":204192},{"start":1494206440267702,"end":1494206440467643,"diff":199941},{"start":1494206440484962,"end":1494206440685410,"diff":200448}],"now":1494206440692,"mem":{"start":{"process":{"rss":51400704,"heapTotal":29458432,"heapUsed":22338544,"external":123168},"os":290770944},"end":{"process":{"rss":47624192,"heapTotal":23351296,"heapUsed":18292760,"external":9284},"os":357011456}},"stats":{"moe":0.0006329147292183768,"rme":0.31171884846397546,"sem":0.000308437977201938,"deviation":0.0016321003651282757,"mean":0.20304024999999998,"sample":[0.200711,0.205484,0.201527,0.203745,0.203614,0.200648,0.200631,0.202881,0.203728,0.204457,0.204845,0.204057,0.201554,0.20454,0.204512,0.203241,0.202226,0.2043,0.203557,0.202056,0.204155,0.200925,0.205252,0.204027,0.203646,0.204267,0.200009,0.200532],"variance":0.000002663751601851851},"count":1,"hz":4.925131839622932,"time":203.04025,"cycles":1,"battery":{"amperage":4335,"currentCapacity":1421,"percent":18,"charging":"","temp":3104}},{"msg":"sleep200 4 x 4.93 ops/sec ±0.31% (28 runs sampled)","name":"sleep200 4","num":4.93,"sampled":"28","variation":"0.31","tags":"fresh,MORETAGS,uniqd,4th","suite":["sleepy4"],"timesFor":[{"start":1494206434516513,"end":1494206434717085,"diff":200572},{"start":1494206434735905,"end":1494206434941292,"diff":205387},{"start":1494206434960559,"end":1494206435161915,"diff":201356},{"start":1494206435181442,"end":1494206435385109,"diff":203667},{"start":1494206435406442,"end":1494206435609992,"diff":203550},{"start":1494206435628984,"end":1494206435829547,"diff":200563},{"start":1494206435849373,"end":1494206436049892,"diff":200519},{"start":1494206436068475,"end":1494206436271279,"diff":202804},{"start":1494206436288452,"end":1494206436492109,"diff":203657},{"start":1494206436510239,"end":1494206436714498,"diff":204259},{"start":1494206436732496,"end":1494206436937257,"diff":204761},{"start":1494206436954986,"end":1494206437158958,"diff":203972},{"start":1494206437175976,"end":1494206437377458,"diff":201482},{"start":1494206437395412,"end":1494206437599878,"diff":204466},{"start":1494206437616087,"end":1494206437820495,"diff":204408},{"start":1494206437838555,"end":1494206438041729,"diff":203174},{"start":1494206438059471,"end":1494206438261630,"diff":202159},{"start":1494206438278035,"end":1494206438482251,"diff":204216},{"start":1494206438500385,"end":1494206438703873,"diff":203488},{"start":1494206438721600,"end":1494206438923574,"diff":201974},{"start":1494206438939905,"end":1494206439143974,"diff":204069},{"start":1494206439161409,"end":1494206439362146,"diff":200737},{"start":1494206439380012,"end":1494206439585168,"diff":205156},{"start":1494206439601488,"end":1494206439805429,"diff":203941},{"start":1494206439823796,"end":1494206440027344,"diff":203548},{"start":1494206440046694,"end":1494206440250886,"diff":204192},{"start":1494206440267702,"end":1494206440467643,"diff":199941},{"start":1494206440484962,"end":1494206440685410,"diff":200448}],"now":1494206440692,"mem":{"start":{"process":{"rss":51400704,"heapTotal":29458432,"heapUsed":22338544,"external":123168},"os":290770944},"end":{"process":{"rss":47624192,"heapTotal":23351296,"heapUsed":18296336,"external":9284},"os":357019648}},"stats":{"moe":0.0006329147292183768,"rme":0.31171884846397546,"sem":0.000308437977201938,"deviation":0.0016321003651282757,"mean":0.20304024999999998,"sample":[0.200711,0.205484,0.201527,0.203745,0.203614,0.200648,0.200631,0.202881,0.203728,0.204457,0.204845,0.204057,0.201554,0.20454,0.204512,0.203241,0.202226,0.2043,0.203557,0.202056,0.204155,0.200925,0.205252,0.204027,0.203646,0.204267,0.200009,0.200532],"variance":0.000002663751601851851},"count":1,"hz":4.925131839622932,"time":203.04025,"cycles":1,"battery":{"amperage":4335,"currentCapacity":1421,"percent":18,"charging":"","temp":3104}},{"msg":"sleep200 4 x 4.92 ops/sec ±0.26% (28 runs sampled)","name":"sleep200 4","num":4.92,"sampled":"28","variation":"0.26","tags":"fresh,MORETAGS,uniqd,4th","suite":["sleepy4"],"timesFor":[{"start":1494206716899209,"end":1494206717101762,"diff":202553},{"start":1494206717120320,"end":1494206717324653,"diff":204333},{"start":1494206717342319,"end":1494206717542167,"diff":199848},{"start":1494206717559516,"end":1494206717760302,"diff":200786},{"start":1494206717777291,"end":1494206717980938,"diff":203647},{"start":1494206717997086,"end":1494206718201211,"diff":204125},{"start":1494206718217801,"end":1494206718421667,"diff":203866},{"start":1494206718439965,"end":1494206718642316,"diff":202351},{"start":1494206718658562,"end":1494206718859702,"diff":201140},{"start":1494206718876317,"end":1494206719080857,"diff":204540},{"start":1494206719098416,"end":1494206719300403,"diff":201987},{"start":1494206719318610,"end":1494206719521371,"diff":202761},{"start":1494206719539955,"end":1494206719743140,"diff":203185},{"start":1494206719759703,"end":1494206719962813,"diff":203110},{"start":1494206719981145,"end":1494206720182383,"diff":201238},{"start":1494206720198925,"end":1494206720401317,"diff":202392},{"start":1494206720417729,"end":1494206720621528,"diff":203799},{"start":1494206720638907,"end":1494206720840068,"diff":201161},{"start":1494206720858099,"end":1494206721062811,"diff":204712},{"start":1494206721078846,"end":1494206721283408,"diff":204562},{"start":1494206721300007,"end":1494206721504095,"diff":204088},{"start":1494206721522557,"end":1494206721727110,"diff":204553},{"start":1494206721744057,"end":1494206721947106,"diff":203049},{"start":1494206721965361,"end":1494206722167729,"diff":202368},{"start":1494206722187674,"end":1494206722392138,"diff":204464},{"start":1494206722409086,"end":1494206722613651,"diff":204565},{"start":1494206722629445,"end":1494206722834060,"diff":204615},{"start":1494206722861856,"end":1494206723065414,"diff":203558}],"now":1494206723071,"mem":{"start":{"process":{"rss":46014464,"heapTotal":27852800,"heapUsed":15498304,"external":1547286},"os":375263232},"end":{"process":{"rss":63844352,"heapTotal":30167040,"heapUsed":18510784,"external":17476},"os":768630784}},"stats":{"moe":0.0005291309044500832,"rme":0.26039183607813077,"sem":0.0002578610645468242,"deviation":0.0013644724991945423,"mean":0.20320564285714285,"sample":[0.202641,0.204412,0.199994,0.200863,0.203727,0.204202,0.203933,0.202424,0.20122,0.204604,0.202076,0.202845,0.203261,0.20319,0.201311,0.202459,0.203899,0.201283,0.204833,0.204713,0.204159,0.204631,0.203148,0.202441,0.20454,0.204638,0.204689,0.203622],"variance":0.0000018617852010582},"count":1,"hz":4.9211231830949576,"time":203.20564285714286,"cycles":1,"battery":{"amperage":3598,"currentCapacity":1670,"percent":22,"charging":"","temp":3108}},{"msg":"sleep200 4 x 4.92 ops/sec ±0.26% (28 runs sampled)","name":"sleep200 4","num":4.92,"sampled":"28","variation":"0.26","tags":"fresh,MORETAGS,uniqd,4th","suite":["sleepy4"],"timesFor":[{"start":1494206716899209,"end":1494206717101762,"diff":202553},{"start":1494206717120320,"end":1494206717324653,"diff":204333},{"start":1494206717342319,"end":1494206717542167,"diff":199848},{"start":1494206717559516,"end":1494206717760302,"diff":200786},{"start":1494206717777291,"end":1494206717980938,"diff":203647},{"start":1494206717997086,"end":1494206718201211,"diff":204125},{"start":1494206718217801,"end":1494206718421667,"diff":203866},{"start":1494206718439965,"end":1494206718642316,"diff":202351},{"start":1494206718658562,"end":1494206718859702,"diff":201140},{"start":1494206718876317,"end":1494206719080857,"diff":204540},{"start":1494206719098416,"end":1494206719300403,"diff":201987},{"start":1494206719318610,"end":1494206719521371,"diff":202761},{"start":1494206719539955,"end":1494206719743140,"diff":203185},{"start":1494206719759703,"end":1494206719962813,"diff":203110},{"start":1494206719981145,"end":1494206720182383,"diff":201238},{"start":1494206720198925,"end":1494206720401317,"diff":202392},{"start":1494206720417729,"end":1494206720621528,"diff":203799},{"start":1494206720638907,"end":1494206720840068,"diff":201161},{"start":1494206720858099,"end":1494206721062811,"diff":204712},{"start":1494206721078846,"end":1494206721283408,"diff":204562},{"start":1494206721300007,"end":1494206721504095,"diff":204088},{"start":1494206721522557,"end":1494206721727110,"diff":204553},{"start":1494206721744057,"end":1494206721947106,"diff":203049},{"start":1494206721965361,"end":1494206722167729,"diff":202368},{"start":1494206722187674,"end":1494206722392138,"diff":204464},{"start":1494206722409086,"end":1494206722613651,"diff":204565},{"start":1494206722629445,"end":1494206722834060,"diff":204615},{"start":1494206722861856,"end":1494206723065414,"diff":203558}],"now":1494206723071,"mem":{"start":{"process":{"rss":46014464,"heapTotal":27852800,"heapUsed":15498304,"external":1547286},"os":375263232},"end":{"process":{"rss":63844352,"heapTotal":30167040,"heapUsed":18514384,"external":17476},"os":768630784}},"stats":{"moe":0.0005291309044500832,"rme":0.26039183607813077,"sem":0.0002578610645468242,"deviation":0.0013644724991945423,"mean":0.20320564285714285,"sample":[0.202641,0.204412,0.199994,0.200863,0.203727,0.204202,0.203933,0.202424,0.20122,0.204604,0.202076,0.202845,0.203261,0.20319,0.201311,0.202459,0.203899,0.201283,0.204833,0.204713,0.204159,0.204631,0.203148,0.202441,0.20454,0.204638,0.204689,0.203622],"variance":0.0000018617852010582},"count":1,"hz":4.9211231830949576,"time":203.20564285714286,"cycles":1,"battery":{"amperage":3598,"currentCapacity":1670,"percent":22,"charging":"","temp":3108}}],"sleep3":[{"msg":"sleep3 x 3.30 ops/sec ±0.30% (20 runs sampled)","name":"sleep3","num":3.3,"sampled":"20","variation":"0.30","tags":"fresh,MORETAGS,uniqd,4th","suite":["sleepy4"],"timesFor":[{"start":1494204670450983,"end":1494204670755806,"diff":304823},{"start":1494204670778082,"end":1494204671082309,"diff":304227},{"start":1494204671105140,"end":1494204671409687,"diff":304547},{"start":1494204671438855,"end":1494204671742071,"diff":303216},{"start":1494204671763567,"end":1494204672069227,"diff":305660},{"start":1494204672087519,"end":1494204672390000,"diff":302481},{"start":1494204672416086,"end":1494204672716334,"diff":300248},{"start":1494204672736449,"end":1494204673039100,"diff":302651},{"start":1494204673059327,"end":1494204673363959,"diff":304632},{"start":1494204673391351,"end":1494204673692281,"diff":300930},{"start":1494204673711827,"end":1494204674014056,"diff":302229},{"start":1494204674032622,"end":1494204674334253,"diff":301631},{"start":1494204674351928,"end":1494204674655572,"diff":303644},{"start":1494204674675022,"end":1494204674979510,"diff":304488},{"start":1494204675002502,"end":1494204675302713,"diff":300211},{"start":1494204675328829,"end":1494204675629477,"diff":300648},{"start":1494204675656148,"end":1494204675960702,"diff":304554},{"start":1494204675983101,"end":1494204676284199,"diff":301098},{"start":1494204676309342,"end":1494204676610415,"diff":301073},{"start":1494204676631174,"end":1494204676934159,"diff":302985}],"now":1494204676940,"mem":{"start":{"process":{"rss":51458048,"heapTotal":29982720,"heapUsed":22320128,"external":123168},"os":562667520},"end":{"process":{"rss":44920832,"heapTotal":20205568,"heapUsed":17653472,"external":9284},"os":440971264}},"stats":{"moe":0.0009028024402216532,"rme":0.2978919759747342,"sem":0.0004313437363696384,"deviation":0.0019290278323825197,"mean":0.30306369860000004,"sample":[0.304992625,0.30443376,0.30470802,0.303392438,0.305782266,0.302586784,0.300402723,0.302761577,0.304824759,0.301111049,0.30235172,0.301742142,0.303759834,0.304676975,0.30036017,0.300763715,0.307057591,0.301266724,0.301201784,0.303097316],"variance":0.0000037211483781064024},"count":1,"hz":3.299636362320828,"time":303.06369860000007,"cycles":1,"battery":{"amperage":-2112,"currentCapacity":417,"percent":5,"charging":"","temp":3108}},{"msg":"sleep3 x 3.30 ops/sec ±0.30% (20 runs sampled)","name":"sleep3","num":3.3,"sampled":"20","variation":"0.30","tags":"fresh,MORETAGS,uniqd,4th","suite":["sleepy4"],"timesFor":[{"start":1494204670450983,"end":1494204670755806,"diff":304823},{"start":1494204670778082,"end":1494204671082309,"diff":304227},{"start":1494204671105140,"end":1494204671409687,"diff":304547},{"start":1494204671438855,"end":1494204671742071,"diff":303216},{"start":1494204671763567,"end":1494204672069227,"diff":305660},{"start":1494204672087519,"end":1494204672390000,"diff":302481},{"start":1494204672416086,"end":1494204672716334,"diff":300248},{"start":1494204672736449,"end":1494204673039100,"diff":302651},{"start":1494204673059327,"end":1494204673363959,"diff":304632},{"start":1494204673391351,"end":1494204673692281,"diff":300930},{"start":1494204673711827,"end":1494204674014056,"diff":302229},{"start":1494204674032622,"end":1494204674334253,"diff":301631},{"start":1494204674351928,"end":1494204674655572,"diff":303644},{"start":1494204674675022,"end":1494204674979510,"diff":304488},{"start":1494204675002502,"end":1494204675302713,"diff":300211},{"start":1494204675328829,"end":1494204675629477,"diff":300648},{"start":1494204675656148,"end":1494204675960702,"diff":304554},{"start":1494204675983101,"end":1494204676284199,"diff":301098},{"start":1494204676309342,"end":1494204676610415,"diff":301073},{"start":1494204676631174,"end":1494204676934159,"diff":302985}],"now":1494204676940,"mem":{"start":{"process":{"rss":51458048,"heapTotal":29982720,"heapUsed":22320128,"external":123168},"os":562667520},"end":{"process":{"rss":44924928,"heapTotal":20205568,"heapUsed":17657512,"external":9284},"os":440971264}},"stats":{"moe":0.0009028024402216532,"rme":0.2978919759747342,"sem":0.0004313437363696384,"deviation":0.0019290278323825197,"mean":0.30306369860000004,"sample":[0.304992625,0.30443376,0.30470802,0.303392438,0.305782266,0.302586784,0.300402723,0.302761577,0.304824759,0.301111049,0.30235172,0.301742142,0.303759834,0.304676975,0.30036017,0.300763715,0.307057591,0.301266724,0.301201784,0.303097316],"variance":0.0000037211483781064024},"count":1,"hz":3.299636362320828,"time":303.06369860000007,"cycles":1,"battery":{"amperage":-2112,"currentCapacity":417,"percent":5,"charging":"","temp":3108}},{"msg":"sleep3 x 3.30 ops/sec ±0.24% (20 runs sampled)","name":"sleep3","num":3.3,"sampled":"20","variation":"0.24","tags":"fresh,MORETAGS,uniqd,4th","suite":["sleepy4"],"timesFor":[{"start":1494204789001906,"end":1494204789304107,"diff":302201},{"start":1494204789322297,"end":1494204789625370,"diff":303073},{"start":1494204789644954,"end":1494204789949218,"diff":304264},{"start":1494204789972316,"end":1494204790275594,"diff":303278},{"start":1494204790297623,"end":1494204790597874,"diff":300251},{"start":1494204790616848,"end":1494204790919588,"diff":302740},{"start":1494204790937994,"end":1494204791242833,"diff":304839},{"start":1494204791260529,"end":1494204791564021,"diff":303492},{"start":1494204791581646,"end":1494204791886967,"diff":305321},{"start":1494204791905783,"end":1494204792206737,"diff":300954},{"start":1494204792224674,"end":1494204792524913,"diff":300239},{"start":1494204792543218,"end":1494204792845437,"diff":302219},{"start":1494204792863471,"end":1494204793163874,"diff":300403},{"start":1494204793181564,"end":1494204793483180,"diff":301616},{"start":1494204793502294,"end":1494204793806139,"diff":303845},{"start":1494204793828978,"end":1494204794130719,"diff":301741},{"start":1494204794150233,"end":1494204794454680,"diff":304447},{"start":1494204794473746,"end":1494204794776592,"diff":302846},{"start":1494204794794459,"end":1494204795095375,"diff":300916},{"start":1494204795116532,"end":1494204795419593,"diff":303061}],"now":1494204795425,"mem":{"start":{"process":{"rss":51888128,"heapTotal":29458432,"heapUsed":22067936,"external":123168},"os":296493056},"end":{"process":{"rss":72499200,"heapTotal":48517120,"heapUsed":33869752,"external":33860},"os":545898496}},"stats":{"moe":0.0007223788586313014,"rme":0.2386422689753828,"sem":0.0003451404006838516,"deviation":0.0015435147954212143,"mean":0.30270365000000005,"sample":[0.302325,0.303187,0.304364,0.303377,0.30036,0.302844,0.304955,0.303599,0.305428,0.301053,0.300346,0.302336,0.300506,0.301754,0.303963,0.301892,0.30456,0.302962,0.301056,0.303206],"variance":0.000002382437923684193},"count":1,"hz":3.3035610901949806,"time":302.70365000000004,"cycles":1,"battery":{"amperage":-1630,"currentCapacity":375,"percent":4,"charging":"","temp":3108}},{"msg":"sleep3 x 3.30 ops/sec ±0.24% (20 runs sampled)","name":"sleep3","num":3.3,"sampled":"20","variation":"0.24","tags":"fresh,MORETAGS,uniqd,4th","suite":["sleepy4"],"timesFor":[{"start":1494204789001906,"end":1494204789304107,"diff":302201},{"start":1494204789322297,"end":1494204789625370,"diff":303073},{"start":1494204789644954,"end":1494204789949218,"diff":304264},{"start":1494204789972316,"end":1494204790275594,"diff":303278},{"start":1494204790297623,"end":1494204790597874,"diff":300251},{"start":1494204790616848,"end":1494204790919588,"diff":302740},{"start":1494204790937994,"end":1494204791242833,"diff":304839},{"start":1494204791260529,"end":1494204791564021,"diff":303492},{"start":1494204791581646,"end":1494204791886967,"diff":305321},{"start":1494204791905783,"end":1494204792206737,"diff":300954},{"start":1494204792224674,"end":1494204792524913,"diff":300239},{"start":1494204792543218,"end":1494204792845437,"diff":302219},{"start":1494204792863471,"end":1494204793163874,"diff":300403},{"start":1494204793181564,"end":1494204793483180,"diff":301616},{"start":1494204793502294,"end":1494204793806139,"diff":303845},{"start":1494204793828978,"end":1494204794130719,"diff":301741},{"start":1494204794150233,"end":1494204794454680,"diff":304447},{"start":1494204794473746,"end":1494204794776592,"diff":302846},{"start":1494204794794459,"end":1494204795095375,"diff":300916},{"start":1494204795116532,"end":1494204795419593,"diff":303061}],"now":1494204795425,"mem":{"start":{"process":{"rss":51888128,"heapTotal":29458432,"heapUsed":22067936,"external":123168},"os":296493056},"end":{"process":{"rss":72499200,"heapTotal":48517120,"heapUsed":33872448,"external":33860},"os":545898496}},"stats":{"moe":0.0007223788586313014,"rme":0.2386422689753828,"sem":0.0003451404006838516,"deviation":0.0015435147954212143,"mean":0.30270365000000005,"sample":[0.302325,0.303187,0.304364,0.303377,0.30036,0.302844,0.304955,0.303599,0.305428,0.301053,0.300346,0.302336,0.300506,0.301754,0.303963,0.301892,0.30456,0.302962,0.301056,0.303206],"variance":0.000002382437923684193},"count":1,"hz":3.3035610901949806,"time":302.70365000000004,"cycles":1,"battery":{"amperage":-1630,"currentCapacity":375,"percent":4,"charging":"","temp":3108}},{"msg":"sleep3 x 3.30 ops/sec ±0.29% (20 runs sampled)","name":"sleep3","num":3.3,"sampled":"20","variation":"0.29","tags":"fresh,MORETAGS,uniqd,4th","suite":["sleepy4"],"timesFor":[{"start":1494206428085526,"end":1494206428385762,"diff":300236},{"start":1494206428402035,"end":1494206428706697,"diff":304662},{"start":1494206428723302,"end":1494206429028206,"diff":304904},{"start":1494206429045940,"end":1494206429345910,"diff":299970},{"start":1494206429365758,"end":1494206429670540,"diff":304782},{"start":1494206429686935,"end":1494206429991159,"diff":304224},{"start":1494206430008507,"end":1494206430309122,"diff":300615},{"start":1494206430324189,"end":1494206430628519,"diff":304330},{"start":1494206430645139,"end":1494206430947711,"diff":302572},{"start":1494206430966107,"end":1494206431267083,"diff":300976},{"start":1494206431283905,"end":1494206431586164,"diff":302259},{"start":1494206431602626,"end":1494206431907284,"diff":304658},{"start":1494206431927803,"end":1494206432228323,"diff":300520},{"start":1494206432246104,"end":1494206432546084,"diff":299980},{"start":1494206432563276,"end":1494206432864964,"diff":301688},{"start":1494206432884782,"end":1494206433188667,"diff":303885},{"start":1494206433207315,"end":1494206433509050,"diff":301735},{"start":1494206433526268,"end":1494206433830533,"diff":304265},{"start":1494206433863566,"end":1494206434164177,"diff":300611},{"start":1494206434183659,"end":1494206434488488,"diff":304829}],"now":1494206434495,"mem":{"start":{"process":{"rss":51400704,"heapTotal":29458432,"heapUsed":22338544,"external":123168},"os":290770944},"end":{"process":{"rss":43892736,"heapTotal":19681280,"heapUsed":17300208,"external":9284},"os":306413568}},"stats":{"moe":0.0008914724358578625,"rme":0.2945303172775579,"sem":0.00042593045191488896,"deviation":0.0019048188883377943,"mean":0.30267595,"sample":[0.300343,0.30473,0.304975,0.300066,0.304858,0.304288,0.300681,0.304457,0.302726,0.3011,0.302345,0.304729,0.300602,0.300099,0.301758,0.303979,0.301814,0.304348,0.300713,0.304908],"variance":0.0000036283349973684304},"count":1,"hz":3.30386342225076,"time":302.67595,"cycles":1,"battery":{"amperage":4335,"currentCapacity":1421,"percent":18,"charging":"","temp":3104}},{"msg":"sleep3 x 3.30 ops/sec ±0.29% (20 runs sampled)","name":"sleep3","num":3.3,"sampled":"20","variation":"0.29","tags":"fresh,MORETAGS,uniqd,4th","suite":["sleepy4"],"timesFor":[{"start":1494206428085526,"end":1494206428385762,"diff":300236},{"start":1494206428402035,"end":1494206428706697,"diff":304662},{"start":1494206428723302,"end":1494206429028206,"diff":304904},{"start":1494206429045940,"end":1494206429345910,"diff":299970},{"start":1494206429365758,"end":1494206429670540,"diff":304782},{"start":1494206429686935,"end":1494206429991159,"diff":304224},{"start":1494206430008507,"end":1494206430309122,"diff":300615},{"start":1494206430324189,"end":1494206430628519,"diff":304330},{"start":1494206430645139,"end":1494206430947711,"diff":302572},{"start":1494206430966107,"end":1494206431267083,"diff":300976},{"start":1494206431283905,"end":1494206431586164,"diff":302259},{"start":1494206431602626,"end":1494206431907284,"diff":304658},{"start":1494206431927803,"end":1494206432228323,"diff":300520},{"start":1494206432246104,"end":1494206432546084,"diff":299980},{"start":1494206432563276,"end":1494206432864964,"diff":301688},{"start":1494206432884782,"end":1494206433188667,"diff":303885},{"start":1494206433207315,"end":1494206433509050,"diff":301735},{"start":1494206433526268,"end":1494206433830533,"diff":304265},{"start":1494206433863566,"end":1494206434164177,"diff":300611},{"start":1494206434183659,"end":1494206434488488,"diff":304829}],"now":1494206434495,"mem":{"start":{"process":{"rss":51400704,"heapTotal":29458432,"heapUsed":22338544,"external":123168},"os":290770944},"end":{"process":{"rss":43896832,"heapTotal":19681280,"heapUsed":17303728,"external":9284},"os":306413568}},"stats":{"moe":0.0008914724358578625,"rme":0.2945303172775579,"sem":0.00042593045191488896,"deviation":0.0019048188883377943,"mean":0.30267595,"sample":[0.300343,0.30473,0.304975,0.300066,0.304858,0.304288,0.300681,0.304457,0.302726,0.3011,0.302345,0.304729,0.300602,0.300099,0.301758,0.303979,0.301814,0.304348,0.300713,0.304908],"variance":0.0000036283349973684304},"count":1,"hz":3.30386342225076,"time":302.67595,"cycles":1,"battery":{"amperage":4335,"currentCapacity":1421,"percent":18,"charging":"","temp":3104}},{"msg":"sleep3 x 3.30 ops/sec ±0.21% (20 runs sampled)","name":"sleep3","num":3.3,"sampled":"20","variation":"0.21","tags":"fresh,MORETAGS,uniqd,4th","suite":["sleepy4"],"timesFor":[{"start":1494206710491745,"end":1494206710795203,"diff":303458},{"start":1494206710812058,"end":1494206711116133,"diff":304075},{"start":1494206711132705,"end":1494206711437043,"diff":304338},{"start":1494206711453943,"end":1494206711757825,"diff":303882},{"start":1494206711775054,"end":1494206712077078,"diff":302024},{"start":1494206712093180,"end":1494206712397534,"diff":304354},{"start":1494206712414443,"end":1494206712714235,"diff":299792},{"start":1494206712732529,"end":1494206713034853,"diff":302324},{"start":1494206713049874,"end":1494206713353964,"diff":304090},{"start":1494206713370541,"end":1494206713674905,"diff":304364},{"start":1494206713691823,"end":1494206713997560,"diff":305737},{"start":1494206714013986,"end":1494206714315151,"diff":301165},{"start":1494206714332674,"end":1494206714634835,"diff":302161},{"start":1494206714651185,"end":1494206714954645,"diff":303460},{"start":1494206714973191,"end":1494206715277053,"diff":303862},{"start":1494206715294304,"end":1494206715597377,"diff":303073},{"start":1494206715615969,"end":1494206715919931,"diff":303962},{"start":1494206715936273,"end":1494206716239064,"diff":302791},{"start":1494206716256184,"end":1494206716557657,"diff":301473},{"start":1494206716574881,"end":1494206716878078,"diff":303197}],"now":1494206716883,"mem":{"start":{"process":{"rss":46014464,"heapTotal":27852800,"heapUsed":15498304,"external":1547286},"os":375263232},"end":{"process":{"rss":63299584,"heapTotal":29642752,"heapUsed":21626984,"external":17476},"os":786718720}},"stats":{"moe":0.000639641643058846,"rme":0.21091890753982576,"sem":0.0003056099584609871,"deviation":0.0013667292834393084,"mean":0.30326425,"sample":[0.303573,0.304176,0.304399,0.30394,0.302104,0.304442,0.299856,0.302413,0.304149,0.30443,0.30581,0.301242,0.302238,0.303587,0.303942,0.303144,0.304034,0.302879,0.301633,0.303294],"variance":0.0000018679489342105252},"count":1,"hz":3.297454282857277,"time":303.26425,"cycles":1,"battery":{"amperage":3598,"currentCapacity":1670,"percent":22,"charging":"","temp":3108}},{"msg":"sleep3 x 3.30 ops/sec ±0.21% (20 runs sampled)","name":"sleep3","num":3.3,"sampled":"20","variation":"0.21","tags":"fresh,MORETAGS,uniqd,4th","suite":["sleepy4"],"timesFor":[{"start":1494206710491745,"end":1494206710795203,"diff":303458},{"start":1494206710812058,"end":1494206711116133,"diff":304075},{"start":1494206711132705,"end":1494206711437043,"diff":304338},{"start":1494206711453943,"end":1494206711757825,"diff":303882},{"start":1494206711775054,"end":1494206712077078,"diff":302024},{"start":1494206712093180,"end":1494206712397534,"diff":304354},{"start":1494206712414443,"end":1494206712714235,"diff":299792},{"start":1494206712732529,"end":1494206713034853,"diff":302324},{"start":1494206713049874,"end":1494206713353964,"diff":304090},{"start":1494206713370541,"end":1494206713674905,"diff":304364},{"start":1494206713691823,"end":1494206713997560,"diff":305737},{"start":1494206714013986,"end":1494206714315151,"diff":301165},{"start":1494206714332674,"end":1494206714634835,"diff":302161},{"start":1494206714651185,"end":1494206714954645,"diff":303460},{"start":1494206714973191,"end":1494206715277053,"diff":303862},{"start":1494206715294304,"end":1494206715597377,"diff":303073},{"start":1494206715615969,"end":1494206715919931,"diff":303962},{"start":1494206715936273,"end":1494206716239064,"diff":302791},{"start":1494206716256184,"end":1494206716557657,"diff":301473},{"start":1494206716574881,"end":1494206716878078,"diff":303197}],"now":1494206716883,"mem":{"start":{"process":{"rss":46014464,"heapTotal":27852800,"heapUsed":15498304,"external":1547286},"os":375263232},"end":{"process":{"rss":63299584,"heapTotal":29642752,"heapUsed":21629728,"external":17476},"os":786718720}},"stats":{"moe":0.000639641643058846,"rme":0.21091890753982576,"sem":0.0003056099584609871,"deviation":0.0013667292834393084,"mean":0.30326425,"sample":[0.303573,0.304176,0.304399,0.30394,0.302104,0.304442,0.299856,0.302413,0.304149,0.30443,0.30581,0.301242,0.302238,0.303587,0.303942,0.303144,0.304034,0.302879,0.301633,0.303294],"variance":0.0000018679489342105252},"count":1,"hz":3.297454282857277,"time":303.26425,"cycles":1,"battery":{"amperage":3598,"currentCapacity":1670,"percent":22,"charging":"","temp":3108}}]}}
\ No newline at end of file
diff --git a/_modules/bench-chain/example/basic.js b/_modules/bench-chain/example/basic.js
new file mode 100644
index 0000000..c1f7691
--- /dev/null
+++ b/_modules/bench-chain/example/basic.js
@@ -0,0 +1,13 @@
+const Bench = require('../src')
+
+Bench
+ // location to store benchmarks
+ .init(__dirname, 'basic.json')
+ // tag current benchmarks with, to mark what changes caused differences
+ .tags('v1')
+ // actual benchmarks
+ .add('1 * 1', () => 1 * 1)
+ .add('1 + 1', () => 1 + 1)
+ .run()
+
+// require('fliplog').quick(b)
diff --git a/_modules/bench-chain/example/basic.json b/_modules/bench-chain/example/basic.json
new file mode 100644
index 0000000..688f8d1
--- /dev/null
+++ b/_modules/bench-chain/example/basic.json
@@ -0,0 +1 @@
+{"/Users/james/code/fluents/chain/packages/bench-chain/example/basic.json":{"1 * 1":[{"msg":"1 * 1 x 89,814,539 ops/sec ±1.51% (84 runs sampled)","name":"1 * 1","num":89814539,"sampled":"84","variation":"1.51","tags":"v1","suite":["/Users/james/code/fluents/chain/packages/bench-chain/example/basic.json"],"now":1494206448978,"mem":{"start":{"process":{"rss":51613696,"heapTotal":29458432,"heapUsed":22395128,"external":123168},"os":294092800},"end":{"process":{"rss":73793536,"heapTotal":50614272,"heapUsed":38345704,"external":25668},"os":275288064}},"stats":{"moe":1.681155037154013e-10,"rme":1.509921650737073,"sem":8.577321618132719e-11,"deviation":7.861245115014859e-10,"mean":1.1134054779155939e-8,"sample":[1.1214452772969803e-8,1.1587269515213069e-8,1.1075421148763713e-8,1.1226995368542624e-8,1.0693602394048899e-8,1.0719963127923494e-8,1.0261590545530625e-8,1.2516221031291156e-8,1.0911536122376901e-8,1.1075779397588597e-8,1.0912941627177e-8,1.0823993251970669e-8,1.0656938967158774e-8,1.1048472447186651e-8,1.073946217756465e-8,1.0119634560720518e-8,1.1039035486385979e-8,1.1583768989624765e-8,1.1454462548015558e-8,1.045293998474425e-8,1.0768174632766694e-8,1.1484379721617688e-8,1.0092528396718588e-8,1.1328569475206595e-8,1.3420763763355557e-8,1.1061523563187581e-8,1.0807693869328527e-8,1.0637475521352252e-8,1.1780398029839745e-8,1.2298275641285915e-8,1.091583717756116e-8,1.228753939227365e-8,1.0774899508709244e-8,1.054475337079178e-8,1.2016205099054586e-8,1.0475455763530797e-8,1.0494585807225377e-8,1.2354299340677188e-8,1.0226765195501238e-8,1.2109903272252535e-8,1.0701697810898346e-8,1.1301951732947713e-8,1.0759087941982092e-8,1.0942384993300581e-8,1.0860789500807366e-8,1.1759315940870206e-8,1.2935228014504478e-8,1.0890850998041708e-8,1.091681320019864e-8,1.1518433553940476e-8,1.0977131399194821e-8,9.863879978886678e-9,1.2752906985823466e-8,1.0670855495554022e-8,1.1616231022215837e-8,1.0337641367118812e-8,1.1072000799557745e-8,1.031265518759936e-8,1.0393665066510087e-8,9.917366019420508e-9,1.0849077229157623e-8,1.0213686492159025e-8,1.1193027606605097e-8,1.04067437698523e-8,1.156352579979199e-8,1.0730392876440219e-8,1.1729254443635864e-8,1.1265058077251022e-8,1.1307222255190097e-8,1.0162933315010135e-8,1.1178582471570412e-8,1.0947265106487973e-8,1.0180892131539742e-8,1.2878423497003221e-8,1.1646292519450179e-8,1.2971731261146178e-8,1.3364092361412593e-8,1.0681591744566286e-8,1.0339788616921266e-8,1.0547681438704217e-8,1.1510234963785656e-8,1.038019595411288e-8,1.1430591516567399e-8,1.1286920984330542e-8],"variance":6.1799174758345e-19},"count":5122832,"hz":89814539.2523216,"time":0.000011134054779155938,"cycles":5,"battery":{"amperage":4335,"currentCapacity":1421,"percent":18,"charging":"","temp":3104}},{"msg":"1 * 1 x 89,814,539 ops/sec ±1.51% (84 runs sampled)","name":"1 * 1","num":89814539,"sampled":"84","variation":"1.51","tags":"v1","suite":["/Users/james/code/fluents/chain/packages/bench-chain/example/basic.json"],"now":1494206448979,"mem":{"start":{"process":{"rss":51613696,"heapTotal":29458432,"heapUsed":22395128,"external":123168},"os":294092800},"end":{"process":{"rss":73809920,"heapTotal":50614272,"heapUsed":38371688,"external":25668},"os":275288064}},"stats":{"moe":1.681155037154013e-10,"rme":1.509921650737073,"sem":8.577321618132719e-11,"deviation":7.861245115014859e-10,"mean":1.1134054779155939e-8,"sample":[1.1214452772969803e-8,1.1587269515213069e-8,1.1075421148763713e-8,1.1226995368542624e-8,1.0693602394048899e-8,1.0719963127923494e-8,1.0261590545530625e-8,1.2516221031291156e-8,1.0911536122376901e-8,1.1075779397588597e-8,1.0912941627177e-8,1.0823993251970669e-8,1.0656938967158774e-8,1.1048472447186651e-8,1.073946217756465e-8,1.0119634560720518e-8,1.1039035486385979e-8,1.1583768989624765e-8,1.1454462548015558e-8,1.045293998474425e-8,1.0768174632766694e-8,1.1484379721617688e-8,1.0092528396718588e-8,1.1328569475206595e-8,1.3420763763355557e-8,1.1061523563187581e-8,1.0807693869328527e-8,1.0637475521352252e-8,1.1780398029839745e-8,1.2298275641285915e-8,1.091583717756116e-8,1.228753939227365e-8,1.0774899508709244e-8,1.054475337079178e-8,1.2016205099054586e-8,1.0475455763530797e-8,1.0494585807225377e-8,1.2354299340677188e-8,1.0226765195501238e-8,1.2109903272252535e-8,1.0701697810898346e-8,1.1301951732947713e-8,1.0759087941982092e-8,1.0942384993300581e-8,1.0860789500807366e-8,1.1759315940870206e-8,1.2935228014504478e-8,1.0890850998041708e-8,1.091681320019864e-8,1.1518433553940476e-8,1.0977131399194821e-8,9.863879978886678e-9,1.2752906985823466e-8,1.0670855495554022e-8,1.1616231022215837e-8,1.0337641367118812e-8,1.1072000799557745e-8,1.031265518759936e-8,1.0393665066510087e-8,9.917366019420508e-9,1.0849077229157623e-8,1.0213686492159025e-8,1.1193027606605097e-8,1.04067437698523e-8,1.156352579979199e-8,1.0730392876440219e-8,1.1729254443635864e-8,1.1265058077251022e-8,1.1307222255190097e-8,1.0162933315010135e-8,1.1178582471570412e-8,1.0947265106487973e-8,1.0180892131539742e-8,1.2878423497003221e-8,1.1646292519450179e-8,1.2971731261146178e-8,1.3364092361412593e-8,1.0681591744566286e-8,1.0339788616921266e-8,1.0547681438704217e-8,1.1510234963785656e-8,1.038019595411288e-8,1.1430591516567399e-8,1.1286920984330542e-8],"variance":6.1799174758345e-19},"count":5122832,"hz":89814539.2523216,"time":0.000011134054779155938,"cycles":5,"battery":{"amperage":4335,"currentCapacity":1421,"percent":18,"charging":"","temp":3104}},{"msg":"1 * 1 x 86,679,642 ops/sec ±2.41% (80 runs sampled)","name":"1 * 1","num":86679642,"sampled":"80","variation":"2.41","tags":"v1","suite":["/Users/james/code/fluents/chain/packages/bench-chain/example/basic.json"],"now":1494206731283,"mem":{"start":{"process":{"rss":46718976,"heapTotal":27320320,"heapUsed":14588280,"external":507546},"os":787296256},"end":{"process":{"rss":68014080,"heapTotal":48828416,"heapUsed":32462936,"external":17476},"os":702812160}},"stats":{"moe":2.779395943984618e-10,"rme":2.409170465534399,"sem":1.4180591550941928e-10,"deviation":1.268350666762613e-9,"mean":1.1536734256652509e-8,"sample":[1.765865641166721e-8,1.1121679587848918e-8,1.2099767721140498e-8,1.2385409258570951e-8,1.0195685915277237e-8,1.1034270155629762e-8,1.133786184431951e-8,1.25444241854875e-8,1.1835002990065957e-8,9.843901972663089e-9,9.891606712398325e-9,1.0479380361812072e-8,1.1803905227020307e-8,1.1012328716966065e-8,1.1600877282199738e-8,1.4836538288300069e-8,1.169406090954582e-8,1.0995280568927697e-8,1.4067434337023675e-8,1.1944552448336847e-8,1.0839328760167621e-8,1.2086168314428294e-8,1.195850093309551e-8,1.0808138398415608e-8,1.0879624382803765e-8,1.1578210994466907e-8,1.2097598322772199e-8,1.3671258624086593e-8,1.2290746090888714e-8,9.931902335034467e-9,1.113786507979405e-8,1.1187847150179267e-8,1.2002283676921322e-8,1.1841101186376748e-8,1.1710721599674225e-8,1.0839716218077586e-8,1.1436207670465499e-8,1.1530359942586488e-8,1.1104931157447203e-8,1.1825602869978231e-8,1.1015622109200751e-8,1.056423364409395e-8,1.1501106870384288e-8,1.1335274884920157e-8,1.0521225816088067e-8,1.0735683769252541e-8,1.1466429387442605e-8,1.1430202072861071e-8,1.2165984643880654e-8,1.1444150557619737e-8,1.0722703929268784e-8,9.841237184103143e-9,1.0831579601968365e-8,1.1177579515565249e-8,1.081511264079494e-8,1.16169567854632e-8,1.1318763768037992e-8,1.0945747400590557e-8,1.1383770769833811e-8,1.0795999128596619e-8,1.3515652176941321e-8,1.0345013053638128e-8,1.1009206616629334e-8,1.1511656568009512e-8,1.3196421364551142e-8,1.348663119399676e-8,1.2254980677829555e-8,1.0168952423774454e-8,1.1777488771781698e-8,1.0226607443224316e-8,1.0733507278655996e-8,1.0750532921983471e-8,1.036513426847969e-8,1.0771234556483927e-8,1.2280906089260032e-8,1.5843135009095177e-8,1.1309477053495733e-8,1.098405509807738e-8,1.0856169299901677e-8,1.0781875583563599e-8],"variance":1.6087134138771647e-18},"count":5168674,"hz":86679642.41469486,"time":0.000011536734256652508,"cycles":4,"battery":{"amperage":3561,"currentCapacity":1729,"percent":22,"charging":"","temp":3108}},{"msg":"1 * 1 x 86,679,642 ops/sec ±2.41% (80 runs sampled)","name":"1 * 1","num":86679642,"sampled":"80","variation":"2.41","tags":"v1","suite":["/Users/james/code/fluents/chain/packages/bench-chain/example/basic.json"],"now":1494206731283,"mem":{"start":{"process":{"rss":46718976,"heapTotal":27320320,"heapUsed":14588280,"external":507546},"os":787296256},"end":{"process":{"rss":68022272,"heapTotal":48828416,"heapUsed":32488872,"external":17476},"os":700739584}},"stats":{"moe":2.779395943984618e-10,"rme":2.409170465534399,"sem":1.4180591550941928e-10,"deviation":1.268350666762613e-9,"mean":1.1536734256652509e-8,"sample":[1.765865641166721e-8,1.1121679587848918e-8,1.2099767721140498e-8,1.2385409258570951e-8,1.0195685915277237e-8,1.1034270155629762e-8,1.133786184431951e-8,1.25444241854875e-8,1.1835002990065957e-8,9.843901972663089e-9,9.891606712398325e-9,1.0479380361812072e-8,1.1803905227020307e-8,1.1012328716966065e-8,1.1600877282199738e-8,1.4836538288300069e-8,1.169406090954582e-8,1.0995280568927697e-8,1.4067434337023675e-8,1.1944552448336847e-8,1.0839328760167621e-8,1.2086168314428294e-8,1.195850093309551e-8,1.0808138398415608e-8,1.0879624382803765e-8,1.1578210994466907e-8,1.2097598322772199e-8,1.3671258624086593e-8,1.2290746090888714e-8,9.931902335034467e-9,1.113786507979405e-8,1.1187847150179267e-8,1.2002283676921322e-8,1.1841101186376748e-8,1.1710721599674225e-8,1.0839716218077586e-8,1.1436207670465499e-8,1.1530359942586488e-8,1.1104931157447203e-8,1.1825602869978231e-8,1.1015622109200751e-8,1.056423364409395e-8,1.1501106870384288e-8,1.1335274884920157e-8,1.0521225816088067e-8,1.0735683769252541e-8,1.1466429387442605e-8,1.1430202072861071e-8,1.2165984643880654e-8,1.1444150557619737e-8,1.0722703929268784e-8,9.841237184103143e-9,1.0831579601968365e-8,1.1177579515565249e-8,1.081511264079494e-8,1.16169567854632e-8,1.1318763768037992e-8,1.0945747400590557e-8,1.1383770769833811e-8,1.0795999128596619e-8,1.3515652176941321e-8,1.0345013053638128e-8,1.1009206616629334e-8,1.1511656568009512e-8,1.3196421364551142e-8,1.348663119399676e-8,1.2254980677829555e-8,1.0168952423774454e-8,1.1777488771781698e-8,1.0226607443224316e-8,1.0733507278655996e-8,1.0750532921983471e-8,1.036513426847969e-8,1.0771234556483927e-8,1.2280906089260032e-8,1.5843135009095177e-8,1.1309477053495733e-8,1.098405509807738e-8,1.0856169299901677e-8,1.0781875583563599e-8],"variance":1.6087134138771647e-18},"count":5168674,"hz":86679642.41469486,"time":0.000011536734256652508,"cycles":4,"battery":{"amperage":3561,"currentCapacity":1729,"percent":22,"charging":"","temp":3108}}],"1 + 1":[{"msg":"1 + 1 x 88,185,620 ops/sec ±2.18% (83 runs sampled)","name":"1 + 1","num":88185620,"sampled":"83","variation":"2.18","tags":"v1","suite":["/Users/james/code/fluents/chain/packages/bench-chain/example/basic.json"],"now":1494206454422,"mem":{"start":{"process":{"rss":51613696,"heapTotal":29458432,"heapUsed":22395128,"external":123168},"os":294092800},"end":{"process":{"rss":90537984,"heapTotal":67403776,"heapUsed":48162840,"external":25668},"os":266162176}},"stats":{"moe":2.4719645422045425e-10,"rme":2.1799172462096674,"sem":1.2612063990839503e-10,"deviation":1.1490137128446087e-9,"mean":1.1339717351668611e-8,"sample":[1.7640844366931902e-8,1.0925860841210517e-8,1.076348916283834e-8,1.1577188023777243e-8,1.0113825177886796e-8,1.121747981719052e-8,1.055340312810734e-8,1.0091061319750375e-8,1.1815031093271573e-8,1.2393350834030477e-8,1.142981166635955e-8,1.0711768934280546e-8,1.1196285880304887e-8,1.1003774286927049e-8,1.139056363508986e-8,1.0086155315841663e-8,1.0918213578759123e-8,1.0442919920083158e-8,1.3972495372166512e-8,1.0768678579621599e-8,1.0179761870419878e-8,1.4071792891278833e-8,1.2155900244848842e-8,1.0417016219445162e-8,1.1179997947327965e-8,1.1308660789701299e-8,1.0508851714383538e-8,1.1419019623594484e-8,1.042403529610874e-8,1.1250946629220055e-8,1.0724109934556823e-8,1.0944827602343195e-8,1.1121869689224844e-8,1.1686532556635919e-8,9.821351275677927e-9,1.021014193783873e-8,1.0128640184186165e-8,1.1713244853885684e-8,1.1804885581676846e-8,1.1444562039212873e-8,1.1318019842752311e-8,1.011889117059136e-8,1.1118360044330715e-8,1.1593916927485277e-8,1.0428714822634246e-8,9.799708465497461e-9,1.0925524555425482e-8,1.0347992990069265e-8,1.1415509978700356e-8,9.889789351113456e-9,9.915331766731843e-9,1.2360579356580703e-8,1.0802297023587153e-8,1.0361641609101991e-8,1.0533614208914343e-8,1.1584167913890472e-8,1.1267519952331224e-8,1.1680098207663348e-8,1.2060309737860723e-8,1.0692718110781551e-8,1.30038192735659e-8,1.2007860044720675e-8,1.1357795818219112e-8,1.080795145147214e-8,1.253567164074339e-8,1.2837696081910431e-8,1.187098389384962e-8,1.3117297791809425e-8,1.2273618155315045e-8,1.1787337357206198e-8,1.1329133718250388e-8,1.07701252787243e-8,1.3431411009834026e-8,1.1564084945885175e-8,1.0508461753839746e-8,1.123827291154681e-8,1.0788843384826322e-8,1.2906719098161648e-8,1.1266935011515535e-8,1.1233398404749406e-8,1.1374174161058384e-8,1.2067134047377087e-8,1.1374759101874072e-8],"variance":1.320232512304953e-18},"count":5128724,"hz":88185619.53423402,"time":0.00001133971735166861,"cycles":4,"battery":{"amperage":4335,"currentCapacity":1421,"percent":18,"charging":"","temp":3104}},{"msg":"1 + 1 x 88,185,620 ops/sec ±2.18% (83 runs sampled)","name":"1 + 1","num":88185620,"sampled":"83","variation":"2.18","tags":"v1","suite":["/Users/james/code/fluents/chain/packages/bench-chain/example/basic.json"],"now":1494206454422,"mem":{"start":{"process":{"rss":51613696,"heapTotal":29458432,"heapUsed":22395128,"external":123168},"os":294092800},"end":{"process":{"rss":90537984,"heapTotal":67403776,"heapUsed":48165656,"external":25668},"os":266162176}},"stats":{"moe":2.4719645422045425e-10,"rme":2.1799172462096674,"sem":1.2612063990839503e-10,"deviation":1.1490137128446087e-9,"mean":1.1339717351668611e-8,"sample":[1.7640844366931902e-8,1.0925860841210517e-8,1.076348916283834e-8,1.1577188023777243e-8,1.0113825177886796e-8,1.121747981719052e-8,1.055340312810734e-8,1.0091061319750375e-8,1.1815031093271573e-8,1.2393350834030477e-8,1.142981166635955e-8,1.0711768934280546e-8,1.1196285880304887e-8,1.1003774286927049e-8,1.139056363508986e-8,1.0086155315841663e-8,1.0918213578759123e-8,1.0442919920083158e-8,1.3972495372166512e-8,1.0768678579621599e-8,1.0179761870419878e-8,1.4071792891278833e-8,1.2155900244848842e-8,1.0417016219445162e-8,1.1179997947327965e-8,1.1308660789701299e-8,1.0508851714383538e-8,1.1419019623594484e-8,1.042403529610874e-8,1.1250946629220055e-8,1.0724109934556823e-8,1.0944827602343195e-8,1.1121869689224844e-8,1.1686532556635919e-8,9.821351275677927e-9,1.021014193783873e-8,1.0128640184186165e-8,1.1713244853885684e-8,1.1804885581676846e-8,1.1444562039212873e-8,1.1318019842752311e-8,1.011889117059136e-8,1.1118360044330715e-8,1.1593916927485277e-8,1.0428714822634246e-8,9.799708465497461e-9,1.0925524555425482e-8,1.0347992990069265e-8,1.1415509978700356e-8,9.889789351113456e-9,9.915331766731843e-9,1.2360579356580703e-8,1.0802297023587153e-8,1.0361641609101991e-8,1.0533614208914343e-8,1.1584167913890472e-8,1.1267519952331224e-8,1.1680098207663348e-8,1.2060309737860723e-8,1.0692718110781551e-8,1.30038192735659e-8,1.2007860044720675e-8,1.1357795818219112e-8,1.080795145147214e-8,1.253567164074339e-8,1.2837696081910431e-8,1.187098389384962e-8,1.3117297791809425e-8,1.2273618155315045e-8,1.1787337357206198e-8,1.1329133718250388e-8,1.07701252787243e-8,1.3431411009834026e-8,1.1564084945885175e-8,1.0508461753839746e-8,1.123827291154681e-8,1.0788843384826322e-8,1.2906719098161648e-8,1.1266935011515535e-8,1.1233398404749406e-8,1.1374174161058384e-8,1.2067134047377087e-8,1.1374759101874072e-8],"variance":1.320232512304953e-18},"count":5128724,"hz":88185619.53423402,"time":0.00001133971735166861,"cycles":4,"battery":{"amperage":4335,"currentCapacity":1421,"percent":18,"charging":"","temp":3104}},{"msg":"1 + 1 x 78,387,784 ops/sec ±10.30% (72 runs sampled)","name":"1 + 1","num":78387784,"sampled":"72","variation":"10.30","tags":"v1","suite":["/Users/james/code/fluents/chain/packages/bench-chain/example/basic.json"],"now":1494206736692,"mem":{"start":{"process":{"rss":46718976,"heapTotal":27320320,"heapUsed":14588280,"external":507546},"os":787296256},"end":{"process":{"rss":87171072,"heapTotal":64045056,"heapUsed":45782080,"external":17476},"os":683413504}},"stats":{"moe":1.3141428570109393e-9,"rme":10.301274684966,"sem":6.704810494953772e-10,"deviation":5.689220361063052e-9,"mean":1.275708975054165e-8,"sample":[1.1724542128963711e-8,1.0942733545106389e-8,1.0905011873704394e-8,1.1506834196872205e-8,1.1261751108963252e-8,1.0873972326950755e-8,1.2435445646951971e-8,1.038046838072398e-8,1.1061656044256407e-8,1.1623809119068628e-8,1.153595996198231e-8,1.242708876657949e-8,1.157183339967881e-8,1.1044126978109254e-8,1.1619121113006017e-8,1.1324795862814268e-8,1.1306043838563823e-8,1.1861150074086805e-8,1.0350771668625237e-8,1.3661784158696234e-8,1.1367170811937315e-8,1.039676075468897e-8,1.0781818497213828e-8,1.061420038090259e-8,1.0331644011746871e-8,1.3135630397453092e-8,1.0831961059453132e-8,1.0781228208499683e-8,1.1063939507342237e-8,1.0903186003144641e-8,1.135421099573864e-8,1.2596071606136405e-8,1.2688783404349378e-8,1.2616364746517786e-8,1.0896222670660834e-8,1.0594411945576981e-8,1.1353216233955238e-8,1.0986547040593643e-8,1.062365794200897e-8,1.1369729279559694e-8,1.1090599123137384e-8,1.0806097253084707e-8,1.3656089762528479e-8,1.0731490119329634e-8,1.2441883529709256e-8,1.1871686075463822e-8,1.1431603462487236e-8,1.0313889122657908e-8,1.0325430069815888e-8,1.0212404321650942e-8,1.091304663250734e-8,1.1490103696235285e-8,1.044608212278781e-8,1.3595550461792311e-8,1.4682787762479324e-8,1.525417398417131e-8,2.1081648588087438e-8,4.53643897323343e-8,3.533306126327979e-8,3.349003760159362e-8,1.7893462086216746e-8,1.2402522625193126e-8,1.1655926939217765e-8,1.307617954980945e-8,1.0320150320334135e-8,1.0251122484517134e-8,1.0500835080376364e-8,9.950567856611391e-9,1.0155695901291369e-8,9.995543500344846e-9,1.0981878922047237e-8,1.208886639672155e-8],"variance":3.236722831673441e-17},"count":5113879,"hz":78387784.3265578,"time":0.000012757089750541651,"cycles":5,"battery":{"amperage":3561,"currentCapacity":1729,"percent":22,"charging":"","temp":3108}},{"msg":"1 + 1 x 78,387,784 ops/sec ±10.30% (72 runs sampled)","name":"1 + 1","num":78387784,"sampled":"72","variation":"10.30","tags":"v1","suite":["/Users/james/code/fluents/chain/packages/bench-chain/example/basic.json"],"now":1494206736692,"mem":{"start":{"process":{"rss":46718976,"heapTotal":27320320,"heapUsed":14588280,"external":507546},"os":787296256},"end":{"process":{"rss":87175168,"heapTotal":64045056,"heapUsed":45786952,"external":17476},"os":683413504}},"stats":{"moe":1.3141428570109393e-9,"rme":10.301274684966,"sem":6.704810494953772e-10,"deviation":5.689220361063052e-9,"mean":1.275708975054165e-8,"sample":[1.1724542128963711e-8,1.0942733545106389e-8,1.0905011873704394e-8,1.1506834196872205e-8,1.1261751108963252e-8,1.0873972326950755e-8,1.2435445646951971e-8,1.038046838072398e-8,1.1061656044256407e-8,1.1623809119068628e-8,1.153595996198231e-8,1.242708876657949e-8,1.157183339967881e-8,1.1044126978109254e-8,1.1619121113006017e-8,1.1324795862814268e-8,1.1306043838563823e-8,1.1861150074086805e-8,1.0350771668625237e-8,1.3661784158696234e-8,1.1367170811937315e-8,1.039676075468897e-8,1.0781818497213828e-8,1.061420038090259e-8,1.0331644011746871e-8,1.3135630397453092e-8,1.0831961059453132e-8,1.0781228208499683e-8,1.1063939507342237e-8,1.0903186003144641e-8,1.135421099573864e-8,1.2596071606136405e-8,1.2688783404349378e-8,1.2616364746517786e-8,1.0896222670660834e-8,1.0594411945576981e-8,1.1353216233955238e-8,1.0986547040593643e-8,1.062365794200897e-8,1.1369729279559694e-8,1.1090599123137384e-8,1.0806097253084707e-8,1.3656089762528479e-8,1.0731490119329634e-8,1.2441883529709256e-8,1.1871686075463822e-8,1.1431603462487236e-8,1.0313889122657908e-8,1.0325430069815888e-8,1.0212404321650942e-8,1.091304663250734e-8,1.1490103696235285e-8,1.044608212278781e-8,1.3595550461792311e-8,1.4682787762479324e-8,1.525417398417131e-8,2.1081648588087438e-8,4.53643897323343e-8,3.533306126327979e-8,3.349003760159362e-8,1.7893462086216746e-8,1.2402522625193126e-8,1.1655926939217765e-8,1.307617954980945e-8,1.0320150320334135e-8,1.0251122484517134e-8,1.0500835080376364e-8,9.950567856611391e-9,1.0155695901291369e-8,9.995543500344846e-9,1.0981878922047237e-8,1.208886639672155e-8],"variance":3.236722831673441e-17},"count":5113879,"hz":78387784.3265578,"time":0.000012757089750541651,"cycles":5,"battery":{"amperage":3561,"currentCapacity":1729,"percent":22,"charging":"","temp":3108}}]}}
\ No newline at end of file
diff --git a/_modules/bench-chain/example/bench.js b/_modules/bench-chain/example/bench.js
new file mode 100644
index 0000000..3f38aad
--- /dev/null
+++ b/_modules/bench-chain/example/bench.js
@@ -0,0 +1,19 @@
+const {resolve} = require('path')
+const Bench = require('../')
+// const Bench = require('bench-chain')
+
+const {record, suite} = Bench.suite(__dirname, true)
+
+/* prettier-ignore */
+
+suite
+ .add('1 * 1', () => 1 * 1)
+ .add('1 + 1', () => 1 + 1)
+ .run()
+
+// true auto calls the following functions:
+record.setup(true)
+
+// suite.on('complete', () => {
+// record.echoFastest().save().echoAvgs().echoTrend()
+// })
diff --git a/_modules/bench-chain/example/configstore.js b/_modules/bench-chain/example/configstore.js
new file mode 100644
index 0000000..c95e414
--- /dev/null
+++ b/_modules/bench-chain/example/configstore.js
@@ -0,0 +1,13 @@
+const Bench = require('../src')
+
+Bench
+ // location to store benchmarks
+ // .init(__dirname, 'configstore.basic.json')
+ .init(__dirname, 'basic-configstore.json')
+ .name('configstore-basic')
+ // tag current benchmarks with, to mark what changes caused differences
+ .tags('v0.4.1,configstore')
+ // actual benchmarks
+ .add('1 * 1', () => 1 * 1)
+ .add('1 + 1', () => 1 + 1)
+ .run()
diff --git a/_modules/bench-chain/example/math/async-first-faster.js b/_modules/bench-chain/example/math/async-first-faster.js
new file mode 100644
index 0000000..beddb4d
--- /dev/null
+++ b/_modules/bench-chain/example/math/async-first-faster.js
@@ -0,0 +1,18 @@
+const Bench = require('../../')
+
+const sleep = sleepDuration =>
+ new Promise(resolve => setTimeout(resolve, sleepDuration))
+
+/* prettier-ignore */
+
+Bench
+ .init().dir(__dirname).filename('async-first-faster.json').setup()
+ .addAsync('zoomzoom', async done => {
+ await sleep(10)
+ done()
+ })
+ .addAsync('snail', async done => {
+ await sleep(200)
+ done()
+ })
+ .run()
diff --git a/_modules/bench-chain/example/math/async-first-faster.json b/_modules/bench-chain/example/math/async-first-faster.json
new file mode 100644
index 0000000..6abb00c
--- /dev/null
+++ b/_modules/bench-chain/example/math/async-first-faster.json
@@ -0,0 +1 @@
+{"/Users/james/code/fluents/chain/packages/bench-chain/example/math/async-first-faster.json":{"zoomzoom":[{"msg":"zoomzoom x 86.98 ops/sec ±0.84% (78 runs sampled)","name":"zoomzoom","num":86.98,"sampled":"78","variation":"0.84","suite":["/Users/james/code/fluents/chain/packages/bench-chain/example/math/async-first-faster.json"],"timesFor":[{"start":1494397664417798,"end":1494397664429575,"diff":11777},{"start":1494397664435944,"end":1494397664446626,"diff":10682},{"start":1494397664446905,"end":1494397664457627,"diff":10722},{"start":1494397664457653,"end":1494397664467894,"diff":10241},{"start":1494397664467911,"end":1494397664478100,"diff":10189},{"start":1494397664478121,"end":1494397664490880,"diff":12759},{"start":1494397664519043,"end":1494397664529556,"diff":10513},{"start":1494397664529649,"end":1494397664541039,"diff":11390},{"start":1494397664541278,"end":1494397664551489,"diff":10211},{"start":1494397664551511,"end":1494397664564164,"diff":12653},{"start":1494397664564183,"end":1494397664575255,"diff":11072},{"start":1494397664600255,"end":1494397664610842,"diff":10587},{"start":1494397664610888,"end":1494397664622440,"diff":11552},{"start":1494397664622463,"end":1494397664635110,"diff":12647},{"start":1494397664635124,"end":1494397664646990,"diff":11866},{"start":1494397664647014,"end":1494397664657221,"diff":10207},{"start":1494397664677901,"end":1494397664690324,"diff":12423},{"start":1494397664690351,"end":1494397664702874,"diff":12523},{"start":1494397664702893,"end":1494397664714360,"diff":11467},{"start":1494397664714377,"end":1494397664726316,"diff":11939},{"start":1494397664726339,"end":1494397664737436,"diff":11097},{"start":1494397664756227,"end":1494397664768004,"diff":11777},{"start":1494397664768043,"end":1494397664779487,"diff":11444},{"start":1494397664779509,"end":1494397664791186,"diff":11677},{"start":1494397664791206,"end":1494397664802934,"diff":11728},{"start":1494397664802957,"end":1494397664814168,"diff":11211},{"start":1494397664836071,"end":1494397664846997,"diff":10926},{"start":1494397664847057,"end":1494397664857905,"diff":10848},{"start":1494397664857925,"end":1494397664868195,"diff":10270},{"start":1494397664868215,"end":1494397664879610,"diff":11395},{"start":1494397664879635,"end":1494397664891265,"diff":11630},{"start":1494397664912225,"end":1494397664923844,"diff":11619},{"start":1494397664923886,"end":1494397664934310,"diff":10424},{"start":1494397664934326,"end":1494397664947021,"diff":12695},{"start":1494397664947044,"end":1494397664957952,"diff":10908},{"start":1494397664957972,"end":1494397664968380,"diff":10408},{"start":1494397664991447,"end":1494397665000812,"diff":9365},{"start":1494397665000865,"end":1494397665012217,"diff":11352},{"start":1494397665012240,"end":1494397665023925,"diff":11685},{"start":1494397665023947,"end":1494397665035361,"diff":11414},{"start":1494397665035385,"end":1494397665047045,"diff":11660},{"start":1494397665066474,"end":1494397665079234,"diff":12760},{"start":1494397665079312,"end":1494397665091343,"diff":12031},{"start":1494397665091367,"end":1494397665102014,"diff":10647},{"start":1494397665102038,"end":1494397665114291,"diff":12253},{"start":1494397665114310,"end":1494397665126991,"diff":12681},{"start":1494397665143860,"end":1494397665154918,"diff":11058},{"start":1494397665154974,"end":1494397665165115,"diff":10141},{"start":1494397665165136,"end":1494397665176677,"diff":11541},{"start":1494397665176700,"end":1494397665188262,"diff":11562},{"start":1494397665188285,"end":1494397665201075,"diff":12790},{"start":1494397665217879,"end":1494397665229294,"diff":11415},{"start":1494397665229451,"end":1494397665240941,"diff":11490},{"start":1494397665240966,"end":1494397665252985,"diff":12019},{"start":1494397665253027,"end":1494397665264152,"diff":11125},{"start":1494397665264175,"end":1494397665276927,"diff":12752},{"start":1494397665296608,"end":1494397665308154,"diff":11546},{"start":1494397665308215,"end":1494397665319329,"diff":11114},{"start":1494397665319351,"end":1494397665329562,"diff":10211},{"start":1494397665329583,"end":1494397665340039,"diff":10456},{"start":1494397665340057,"end":1494397665352583,"diff":12526},{"start":1494397665368708,"end":1494397665379396,"diff":10688},{"start":1494397665379423,"end":1494397665391052,"diff":11629},{"start":1494397665391078,"end":1494397665402939,"diff":11861},{"start":1494397665402963,"end":1494397665414151,"diff":11188},{"start":1494397665414187,"end":1494397665425219,"diff":11032},{"start":1494397665443861,"end":1494397665454955,"diff":11094},{"start":1494397665454993,"end":1494397665466214,"diff":11221},{"start":1494397665466235,"end":1494397665478951,"diff":12716},{"start":1494397665478976,"end":1494397665491088,"diff":12112},{"start":1494397665491152,"end":1494397665503721,"diff":12569},{"start":1494397665520521,"end":1494397665531094,"diff":10573},{"start":1494397665531140,"end":1494397665542992,"diff":11852},{"start":1494397665543010,"end":1494397665554765,"diff":11755},{"start":1494397665554800,"end":1494397665565911,"diff":11111},{"start":1494397665565930,"end":1494397665578581,"diff":12651},{"start":1494397665597037,"end":1494397665607588,"diff":10551},{"start":1494397665607616,"end":1494397665620263,"diff":12647},{"start":1494397665620285,"end":1494397665634009,"diff":13724},{"start":1494397665634028,"end":1494397665646329,"diff":12301},{"start":1494397665646352,"end":1494397665657462,"diff":11110},{"start":1494397665677329,"end":1494397665688056,"diff":10727},{"start":1494397665688097,"end":1494397665700892,"diff":12795},{"start":1494397665700928,"end":1494397665712040,"diff":11112},{"start":1494397665712060,"end":1494397665722731,"diff":10671},{"start":1494397665722752,"end":1494397665735328,"diff":12576},{"start":1494397665755122,"end":1494397665768723,"diff":13601},{"start":1494397665768758,"end":1494397665779641,"diff":10883},{"start":1494397665779660,"end":1494397665790947,"diff":11287},{"start":1494397665790967,"end":1494397665801992,"diff":11025},{"start":1494397665802014,"end":1494397665814098,"diff":12084},{"start":1494397665833631,"end":1494397665846367,"diff":12736},{"start":1494397665846413,"end":1494397665858117,"diff":11704},{"start":1494397665858156,"end":1494397665870921,"diff":12765},{"start":1494397665870944,"end":1494397665882207,"diff":11263},{"start":1494397665882229,"end":1494397665892999,"diff":10770},{"start":1494397665909305,"end":1494397665918952,"diff":9647},{"start":1494397665918976,"end":1494397665929126,"diff":10150},{"start":1494397665929182,"end":1494397665940775,"diff":11593},{"start":1494397665940834,"end":1494397665951737,"diff":10903},{"start":1494397665951750,"end":1494397665964050,"diff":12300},{"start":1494397665983942,"end":1494397665995100,"diff":11158},{"start":1494397665995141,"end":1494397666006784,"diff":11643},{"start":1494397666006806,"end":1494397666017814,"diff":11008},{"start":1494397666017839,"end":1494397666029292,"diff":11453},{"start":1494397666029352,"end":1494397666041118,"diff":11766},{"start":1494397666057978,"end":1494397666070432,"diff":12454},{"start":1494397666070476,"end":1494397666082352,"diff":11876},{"start":1494397666082375,"end":1494397666093077,"diff":10702},{"start":1494397666093097,"end":1494397666104811,"diff":11714},{"start":1494397666104880,"end":1494397666117641,"diff":12761},{"start":1494397666134358,"end":1494397666144245,"diff":9887},{"start":1494397666144335,"end":1494397666153834,"diff":9499},{"start":1494397666153853,"end":1494397666164189,"diff":10336},{"start":1494397666164211,"end":1494397666176159,"diff":11948},{"start":1494397666176179,"end":1494397666187614,"diff":11435},{"start":1494397666205358,"end":1494397666214644,"diff":9286},{"start":1494397666214683,"end":1494397666225616,"diff":10933},{"start":1494397666225652,"end":1494397666235907,"diff":10255},{"start":1494397666235927,"end":1494397666246898,"diff":10971},{"start":1494397666246922,"end":1494397666257885,"diff":10963},{"start":1494397666276389,"end":1494397666285562,"diff":9173},{"start":1494397666285602,"end":1494397666296879,"diff":11277},{"start":1494397666296904,"end":1494397666308286,"diff":11382},{"start":1494397666308310,"end":1494397666317519,"diff":9209},{"start":1494397666317535,"end":1494397666329529,"diff":11994},{"start":1494397666347633,"end":1494397666358317,"diff":10684},{"start":1494397666358367,"end":1494397666369629,"diff":11262},{"start":1494397666369644,"end":1494397666382301,"diff":12657},{"start":1494397666382325,"end":1494397666393060,"diff":10735},{"start":1494397666393081,"end":1494397666402982,"diff":9901},{"start":1494397666421126,"end":1494397666433943,"diff":12817},{"start":1494397666433991,"end":1494397666446872,"diff":12881},{"start":1494397666446895,"end":1494397666457960,"diff":11065},{"start":1494397666457980,"end":1494397666468156,"diff":10176},{"start":1494397666468175,"end":1494397666479354,"diff":11179},{"start":1494397666499932,"end":1494397666511151,"diff":11219},{"start":1494397666511191,"end":1494397666523663,"diff":12472},{"start":1494397666523702,"end":1494397666535262,"diff":11560},{"start":1494397666535286,"end":1494397666546823,"diff":11537},{"start":1494397666546849,"end":1494397666558400,"diff":11551},{"start":1494397666575701,"end":1494397666586214,"diff":10513},{"start":1494397666586255,"end":1494397666596829,"diff":10574},{"start":1494397666596852,"end":1494397666607985,"diff":11133},{"start":1494397666608003,"end":1494397666618211,"diff":10208},{"start":1494397666618233,"end":1494397666629585,"diff":11352},{"start":1494397666645673,"end":1494397666656293,"diff":10620},{"start":1494397666656335,"end":1494397666667793,"diff":11458},{"start":1494397666667820,"end":1494397666679433,"diff":11613},{"start":1494397666679458,"end":1494397666691021,"diff":11563},{"start":1494397666691045,"end":1494397666703406,"diff":12361},{"start":1494397666719571,"end":1494397666731152,"diff":11581},{"start":1494397666731187,"end":1494397666742932,"diff":11745},{"start":1494397666742950,"end":1494397666754691,"diff":11741},{"start":1494397666754715,"end":1494397666767424,"diff":12709},{"start":1494397666767489,"end":1494397666778145,"diff":10656},{"start":1494397666794835,"end":1494397666805606,"diff":10771},{"start":1494397666805642,"end":1494397666817903,"diff":12261},{"start":1494397666817924,"end":1494397666829841,"diff":11917},{"start":1494397666829859,"end":1494397666841112,"diff":11253},{"start":1494397666841145,"end":1494397666853545,"diff":12400},{"start":1494397666870751,"end":1494397666883384,"diff":12633},{"start":1494397666883420,"end":1494397666895163,"diff":11743},{"start":1494397666895184,"end":1494397666906247,"diff":11063},{"start":1494397666906271,"end":1494397666918138,"diff":11867},{"start":1494397666918155,"end":1494397666929494,"diff":11339},{"start":1494397666945406,"end":1494397666958034,"diff":12628},{"start":1494397666958073,"end":1494397666967780,"diff":9707},{"start":1494397666967794,"end":1494397666979362,"diff":11568},{"start":1494397666979383,"end":1494397666991121,"diff":11738},{"start":1494397666991161,"end":1494397667002311,"diff":11150},{"start":1494397667018895,"end":1494397667029437,"diff":10542},{"start":1494397667029478,"end":1494397667041304,"diff":11826},{"start":1494397667041324,"end":1494397667051195,"diff":9871},{"start":1494397667051235,"end":1494397667062295,"diff":11060},{"start":1494397667062315,"end":1494397667073538,"diff":11223},{"start":1494397667089704,"end":1494397667100159,"diff":10455},{"start":1494397667100206,"end":1494397667112474,"diff":12268},{"start":1494397667112494,"end":1494397667123805,"diff":11311},{"start":1494397667123829,"end":1494397667136380,"diff":12551},{"start":1494397667136403,"end":1494397667147394,"diff":10991},{"start":1494397667165550,"end":1494397667178299,"diff":12749},{"start":1494397667178380,"end":1494397667190961,"diff":12581},{"start":1494397667190984,"end":1494397667202919,"diff":11935},{"start":1494397667202942,"end":1494397667214112,"diff":11170},{"start":1494397667214143,"end":1494397667224756,"diff":10613},{"start":1494397667240799,"end":1494397667252242,"diff":11443},{"start":1494397667252265,"end":1494397667263993,"diff":11728},{"start":1494397667264014,"end":1494397667275341,"diff":11327},{"start":1494397667275361,"end":1494397667286176,"diff":10815},{"start":1494397667286186,"end":1494397667296497,"diff":10311},{"start":1494397667314204,"end":1494397667326078,"diff":11874},{"start":1494397667326192,"end":1494397667337625,"diff":11433},{"start":1494397667337645,"end":1494397667349712,"diff":12067},{"start":1494397667349727,"end":1494397667360879,"diff":11152},{"start":1494397667360905,"end":1494397667370943,"diff":10038},{"start":1494397667387436,"end":1494397667398267,"diff":10831},{"start":1494397667398335,"end":1494397667409002,"diff":10667},{"start":1494397667409040,"end":1494397667421817,"diff":12777},{"start":1494397667421840,"end":1494397667434602,"diff":12762},{"start":1494397667434642,"end":1494397667445485,"diff":10843},{"start":1494397667462287,"end":1494397667472785,"diff":10498},{"start":1494397667472948,"end":1494397667485297,"diff":12349},{"start":1494397667485351,"end":1494397667498142,"diff":12791},{"start":1494397667498181,"end":1494397667510980,"diff":12799},{"start":1494397667511003,"end":1494397667523756,"diff":12753},{"start":1494397667540018,"end":1494397667552807,"diff":12789},{"start":1494397667552902,"end":1494397667564933,"diff":12031},{"start":1494397667564955,"end":1494397667577679,"diff":12724},{"start":1494397667577703,"end":1494397667590445,"diff":12742},{"start":1494397667590469,"end":1494397667603215,"diff":12746},{"start":1494397667621831,"end":1494397667634364,"diff":12533},{"start":1494397667634411,"end":1494397667646183,"diff":11772},{"start":1494397667646220,"end":1494397667657678,"diff":11458},{"start":1494397667657697,"end":1494397667668069,"diff":10372},{"start":1494397667668093,"end":1494397667679248,"diff":11155},{"start":1494397667697766,"end":1494397667709024,"diff":11258},{"start":1494397667709062,"end":1494397667721636,"diff":12574},{"start":1494397667721660,"end":1494397667734461,"diff":12801},{"start":1494397667734500,"end":1494397667746812,"diff":12312},{"start":1494397667746835,"end":1494397667757921,"diff":11086},{"start":1494397667775523,"end":1494397667788369,"diff":12846},{"start":1494397667788414,"end":1494397667798681,"diff":10267},{"start":1494397667798703,"end":1494397667809101,"diff":10398},{"start":1494397667809120,"end":1494397667820593,"diff":11473},{"start":1494397667820617,"end":1494397667832578,"diff":11961},{"start":1494397667851646,"end":1494397667862009,"diff":10363},{"start":1494397667862116,"end":1494397667873216,"diff":11100},{"start":1494397667873253,"end":1494397667883552,"diff":10299},{"start":1494397667883574,"end":1494397667896331,"diff":12757},{"start":1494397667896369,"end":1494397667907851,"diff":11482},{"start":1494397667926126,"end":1494397667937840,"diff":11714},{"start":1494397667937885,"end":1494397667949170,"diff":11285},{"start":1494397667949194,"end":1494397667961971,"diff":12777},{"start":1494397667961993,"end":1494397667973546,"diff":11553},{"start":1494397667973589,"end":1494397667985180,"diff":11591},{"start":1494397668004352,"end":1494397668014605,"diff":10253},{"start":1494397668014645,"end":1494397668027148,"diff":12503},{"start":1494397668027186,"end":1494397668038351,"diff":11165},{"start":1494397668038374,"end":1494397668051094,"diff":12720},{"start":1494397668051118,"end":1494397668061808,"diff":10690},{"start":1494397668078467,"end":1494397668090783,"diff":12316},{"start":1494397668090809,"end":1494397668101425,"diff":10616},{"start":1494397668101449,"end":1494397668114044,"diff":12595},{"start":1494397668114066,"end":1494397668125756,"diff":11690},{"start":1494397668125780,"end":1494397668135984,"diff":10204},{"start":1494397668155390,"end":1494397668168170,"diff":12780},{"start":1494397668168207,"end":1494397668179522,"diff":11315},{"start":1494397668179542,"end":1494397668190861,"diff":11319},{"start":1494397668190934,"end":1494397668203001,"diff":12067},{"start":1494397668203037,"end":1494397668213999,"diff":10962},{"start":1494397668233892,"end":1494397668244685,"diff":10793},{"start":1494397668244735,"end":1494397668254906,"diff":10171},{"start":1494397668254927,"end":1494397668265570,"diff":10643},{"start":1494397668265591,"end":1494397668278356,"diff":12765},{"start":1494397668278377,"end":1494397668291064,"diff":12687},{"start":1494397668308330,"end":1494397668320982,"diff":12652},{"start":1494397668321035,"end":1494397668333736,"diff":12701},{"start":1494397668333760,"end":1494397668344662,"diff":10902},{"start":1494397668344684,"end":1494397668356879,"diff":12195},{"start":1494397668356901,"end":1494397668367619,"diff":10718},{"start":1494397668384435,"end":1494397668396666,"diff":12231},{"start":1494397668396714,"end":1494397668408119,"diff":11405},{"start":1494397668408144,"end":1494397668418993,"diff":10849},{"start":1494397668419013,"end":1494397668430613,"diff":11600},{"start":1494397668430635,"end":1494397668442868,"diff":12233},{"start":1494397668461177,"end":1494397668472077,"diff":10900},{"start":1494397668472142,"end":1494397668484131,"diff":11989},{"start":1494397668484204,"end":1494397668495731,"diff":11527},{"start":1494397668495773,"end":1494397668506400,"diff":10627},{"start":1494397668506438,"end":1494397668517798,"diff":11360},{"start":1494397668535661,"end":1494397668546873,"diff":11212},{"start":1494397668546953,"end":1494397668557905,"diff":10952},{"start":1494397668557926,"end":1494397668570248,"diff":12322},{"start":1494397668570269,"end":1494397668581785,"diff":11516},{"start":1494397668581826,"end":1494397668593244,"diff":11418},{"start":1494397668611086,"end":1494397668622995,"diff":11909},{"start":1494397668623147,"end":1494397668635451,"diff":12304},{"start":1494397668635476,"end":1494397668647100,"diff":11624},{"start":1494397668647141,"end":1494397668658482,"diff":11341},{"start":1494397668658508,"end":1494397668669110,"diff":10602},{"start":1494397668687272,"end":1494397668696915,"diff":9643},{"start":1494397668697028,"end":1494397668707928,"diff":10900},{"start":1494397668707949,"end":1494397668720229,"diff":12280},{"start":1494397668720269,"end":1494397668729617,"diff":9348},{"start":1494397668729650,"end":1494397668740823,"diff":11173},{"start":1494397668758529,"end":1494397668770121,"diff":11592},{"start":1494397668770161,"end":1494397668782933,"diff":12772},{"start":1494397668782971,"end":1494397668795097,"diff":12126},{"start":1494397668795123,"end":1494397668806234,"diff":11111},{"start":1494397668806258,"end":1494397668817795,"diff":11537},{"start":1494397668834293,"end":1494397668844551,"diff":10258},{"start":1494397668844593,"end":1494397668854802,"diff":10209},{"start":1494397668854824,"end":1494397668867477,"diff":12653},{"start":1494397668867500,"end":1494397668879251,"diff":11751},{"start":1494397668879298,"end":1494397668890987,"diff":11689},{"start":1494397668907831,"end":1494397668917473,"diff":9642},{"start":1494397668917513,"end":1494397668929278,"diff":11765},{"start":1494397668929300,"end":1494397668940935,"diff":11635},{"start":1494397668940961,"end":1494397668952689,"diff":11728},{"start":1494397668952728,"end":1494397668964108,"diff":11380},{"start":1494397668982772,"end":1494397668993892,"diff":11120},{"start":1494397668993946,"end":1494397669004729,"diff":10783},{"start":1494397669004750,"end":1494397669015234,"diff":10484},{"start":1494397669015255,"end":1494397669024437,"diff":9182},{"start":1494397669024461,"end":1494397669035219,"diff":10758},{"start":1494397669052966,"end":1494397669064096,"diff":11130},{"start":1494397669064137,"end":1494397669073403,"diff":9266},{"start":1494397669073419,"end":1494397669086197,"diff":12778},{"start":1494397669086217,"end":1494397669096973,"diff":10756},{"start":1494397669097017,"end":1494397669108882,"diff":11865},{"start":1494397669128486,"end":1494397669141164,"diff":12678},{"start":1494397669141207,"end":1494397669153017,"diff":11810},{"start":1494397669153042,"end":1494397669164014,"diff":10972},{"start":1494397669164039,"end":1494397669176805,"diff":12766},{"start":1494397669176829,"end":1494397669187100,"diff":10271},{"start":1494397669205619,"end":1494397669217573,"diff":11954},{"start":1494397669217672,"end":1494397669228031,"diff":10359},{"start":1494397669228053,"end":1494397669237792,"diff":9739},{"start":1494397669237812,"end":1494397669250522,"diff":12710},{"start":1494397669250563,"end":1494397669260938,"diff":10375},{"start":1494397669278835,"end":1494397669290908,"diff":12073},{"start":1494397669291105,"end":1494397669301470,"diff":10365},{"start":1494397669301516,"end":1494397669313744,"diff":12228},{"start":1494397669313767,"end":1494397669325498,"diff":11731},{"start":1494397669325520,"end":1494397669337974,"diff":12454},{"start":1494397669363429,"end":1494397669374994,"diff":11565},{"start":1494397669375019,"end":1494397669387662,"diff":12643},{"start":1494397669387673,"end":1494397669400421,"diff":12748},{"start":1494397669400441,"end":1494397669412865,"diff":12424},{"start":1494397669412884,"end":1494397669423335,"diff":10451},{"start":1494397669439883,"end":1494397669452111,"diff":12228},{"start":1494397669452159,"end":1494397669463982,"diff":11823},{"start":1494397669464008,"end":1494397669474361,"diff":10353},{"start":1494397669474383,"end":1494397669486278,"diff":11895},{"start":1494397669486298,"end":1494397669496841,"diff":10543},{"start":1494397669514962,"end":1494397669527687,"diff":12725},{"start":1494397669527736,"end":1494397669537957,"diff":10221},{"start":1494397669537981,"end":1494397669548189,"diff":10208},{"start":1494397669548213,"end":1494397669557703,"diff":9490},{"start":1494397669557726,"end":1494397669568071,"diff":10345},{"start":1494397669583424,"end":1494397669596023,"diff":12599},{"start":1494397669596104,"end":1494397669608301,"diff":12197},{"start":1494397669608326,"end":1494397669620011,"diff":11685},{"start":1494397669620035,"end":1494397669632767,"diff":12732},{"start":1494397669632790,"end":1494397669645605,"diff":12815},{"start":1494397669663017,"end":1494397669673693,"diff":10676},{"start":1494397669673753,"end":1494397669685358,"diff":11605},{"start":1494397669685386,"end":1494397669698160,"diff":12774},{"start":1494397669698185,"end":1494397669708483,"diff":10298},{"start":1494397669708507,"end":1494397669718925,"diff":10418},{"start":1494397669735361,"end":1494397669746757,"diff":11396},{"start":1494397669746805,"end":1494397669757825,"diff":11020},{"start":1494397669757846,"end":1494397669770579,"diff":12733},{"start":1494397669770603,"end":1494397669780947,"diff":10344},{"start":1494397669780968,"end":1494397669792824,"diff":11856},{"start":1494397669811174,"end":1494397669822783,"diff":11609},{"start":1494397669822861,"end":1494397669833602,"diff":10741},{"start":1494397669833627,"end":1494397669846395,"diff":12768},{"start":1494397669846434,"end":1494397669857031,"diff":10597},{"start":1494397669857053,"end":1494397669867602,"diff":10549},{"start":1494397669886184,"end":1494397669896626,"diff":10442},{"start":1494397669896674,"end":1494397669907644,"diff":10970},{"start":1494397669907666,"end":1494397669920392,"diff":12726},{"start":1494397669920417,"end":1494397669932005,"diff":11588},{"start":1494397669932031,"end":1494397669942926,"diff":10895},{"start":1494397669959412,"end":1494397669972188,"diff":12776},{"start":1494397669972290,"end":1494397669985130,"diff":12840},{"start":1494397669985153,"end":1494397669996858,"diff":11705},{"start":1494397669996882,"end":1494397670009260,"diff":12378},{"start":1494397670009286,"end":1494397670021046,"diff":11760},{"start":1494397670039541,"end":1494397670051513,"diff":11972},{"start":1494397670051640,"end":1494397670064003,"diff":12363},{"start":1494397670064027,"end":1494397670074186,"diff":10159},{"start":1494397670074210,"end":1494397670085198,"diff":10988},{"start":1494397670085222,"end":1494397670096624,"diff":11402},{"start":1494397670113808,"end":1494397670125724,"diff":11916},{"start":1494397670125776,"end":1494397670136468,"diff":10692},{"start":1494397670136507,"end":1494397670149284,"diff":12777},{"start":1494397670149347,"end":1494397670160386,"diff":11039},{"start":1494397670160420,"end":1494397670171476,"diff":11056},{"start":1494397670190333,"end":1494397670201766,"diff":11433},{"start":1494397670201814,"end":1494397670213991,"diff":12177},{"start":1494397670214013,"end":1494397670223556,"diff":9543},{"start":1494397670223581,"end":1494397670235129,"diff":11548},{"start":1494397670235156,"end":1494397670246242,"diff":11086},{"start":1494397670262914,"end":1494397670273348,"diff":10434},{"start":1494397670273411,"end":1494397670285005,"diff":11594},{"start":1494397670285029,"end":1494397670296717,"diff":11688},{"start":1494397670296742,"end":1494397670307975,"diff":11233},{"start":1494397670307996,"end":1494397670320716,"diff":12720}],"now":1494397670328,"mem":{"start":{"process":{"rss":53198848,"heapTotal":31195136,"heapUsed":24678824,"external":1889462},"os":233902080},"end":{"process":{"rss":65445888,"heapTotal":44322816,"heapUsed":30236504,"external":17476},"os":213512192}},"stats":{"moe":0.00009688315553219888,"rme":0.842669905861672,"sem":0.00004943018139397902,"deviation":0.00043655554165083083,"mean":0.011497165717948716,"sample":[0.0110049358,0.011262863,0.0114084858,0.0119228394,0.0116042838,0.011064730200000001,0.011248045199999999,0.011135131400000001,0.0121489582,0.0114597846,0.0118371094,0.0112118606,0.0113165886,0.0119874604,0.0116273716,0.0120970358,0.0116286402,0.011811271199999999,0.0118913914,0.010968740000000001,0.0114494518,0.0119496378,0.0106679312,0.0105229678,0.010644291,0.0110877396,0.0116590146,0.011710527799999999,0.0107938706,0.01157472,0.0117270098,0.01175611,0.0117632382,0.0113959886,0.0109478376,0.0115535376,0.0118565418,0.011152871200000001,0.0113616434,0.0116259926,0.0123172448,0.0126567612,0.0115035236,0.012046949,0.0114266366,0.0112578168,0.0118366158,0.0115273836,0.0115189276,0.0117384896,0.0114516588,0.0118736178,0.0117030306,0.011340925,0.0115366934,0.0116224862,0.0107274786,0.0118727608,0.011354425,0.0112745746,0.0105079594,0.0112006868,0.01173699,0.0110813788,0.0118430222,0.0120003578,0.011424674999999999,0.0106350258,0.012448994,0.0111962686,0.011507952200000001,0.0113008172,0.0113655066,0.0123423692,0.011433365,0.0115516226,0.0112009564,0.0115745294],"variance":1.905807409460503e-7},"count":5,"hz":86.9779582666063,"time":11.497165717948716,"cycles":2,"battery":{"amperage":-2489,"currentCapacity":3822,"percent":51,"charging":"","temp":3105}},{"msg":"zoomzoom x 86.98 ops/sec ±0.84% (78 runs sampled)","name":"zoomzoom","num":86.98,"sampled":"78","variation":"0.84","suite":["/Users/james/code/fluents/chain/packages/bench-chain/example/math/async-first-faster.json"],"timesFor":[{"start":1494397664417798,"end":1494397664429575,"diff":11777},{"start":1494397664435944,"end":1494397664446626,"diff":10682},{"start":1494397664446905,"end":1494397664457627,"diff":10722},{"start":1494397664457653,"end":1494397664467894,"diff":10241},{"start":1494397664467911,"end":1494397664478100,"diff":10189},{"start":1494397664478121,"end":1494397664490880,"diff":12759},{"start":1494397664519043,"end":1494397664529556,"diff":10513},{"start":1494397664529649,"end":1494397664541039,"diff":11390},{"start":1494397664541278,"end":1494397664551489,"diff":10211},{"start":1494397664551511,"end":1494397664564164,"diff":12653},{"start":1494397664564183,"end":1494397664575255,"diff":11072},{"start":1494397664600255,"end":1494397664610842,"diff":10587},{"start":1494397664610888,"end":1494397664622440,"diff":11552},{"start":1494397664622463,"end":1494397664635110,"diff":12647},{"start":1494397664635124,"end":1494397664646990,"diff":11866},{"start":1494397664647014,"end":1494397664657221,"diff":10207},{"start":1494397664677901,"end":1494397664690324,"diff":12423},{"start":1494397664690351,"end":1494397664702874,"diff":12523},{"start":1494397664702893,"end":1494397664714360,"diff":11467},{"start":1494397664714377,"end":1494397664726316,"diff":11939},{"start":1494397664726339,"end":1494397664737436,"diff":11097},{"start":1494397664756227,"end":1494397664768004,"diff":11777},{"start":1494397664768043,"end":1494397664779487,"diff":11444},{"start":1494397664779509,"end":1494397664791186,"diff":11677},{"start":1494397664791206,"end":1494397664802934,"diff":11728},{"start":1494397664802957,"end":1494397664814168,"diff":11211},{"start":1494397664836071,"end":1494397664846997,"diff":10926},{"start":1494397664847057,"end":1494397664857905,"diff":10848},{"start":1494397664857925,"end":1494397664868195,"diff":10270},{"start":1494397664868215,"end":1494397664879610,"diff":11395},{"start":1494397664879635,"end":1494397664891265,"diff":11630},{"start":1494397664912225,"end":1494397664923844,"diff":11619},{"start":1494397664923886,"end":1494397664934310,"diff":10424},{"start":1494397664934326,"end":1494397664947021,"diff":12695},{"start":1494397664947044,"end":1494397664957952,"diff":10908},{"start":1494397664957972,"end":1494397664968380,"diff":10408},{"start":1494397664991447,"end":1494397665000812,"diff":9365},{"start":1494397665000865,"end":1494397665012217,"diff":11352},{"start":1494397665012240,"end":1494397665023925,"diff":11685},{"start":1494397665023947,"end":1494397665035361,"diff":11414},{"start":1494397665035385,"end":1494397665047045,"diff":11660},{"start":1494397665066474,"end":1494397665079234,"diff":12760},{"start":1494397665079312,"end":1494397665091343,"diff":12031},{"start":1494397665091367,"end":1494397665102014,"diff":10647},{"start":1494397665102038,"end":1494397665114291,"diff":12253},{"start":1494397665114310,"end":1494397665126991,"diff":12681},{"start":1494397665143860,"end":1494397665154918,"diff":11058},{"start":1494397665154974,"end":1494397665165115,"diff":10141},{"start":1494397665165136,"end":1494397665176677,"diff":11541},{"start":1494397665176700,"end":1494397665188262,"diff":11562},{"start":1494397665188285,"end":1494397665201075,"diff":12790},{"start":1494397665217879,"end":1494397665229294,"diff":11415},{"start":1494397665229451,"end":1494397665240941,"diff":11490},{"start":1494397665240966,"end":1494397665252985,"diff":12019},{"start":1494397665253027,"end":1494397665264152,"diff":11125},{"start":1494397665264175,"end":1494397665276927,"diff":12752},{"start":1494397665296608,"end":1494397665308154,"diff":11546},{"start":1494397665308215,"end":1494397665319329,"diff":11114},{"start":1494397665319351,"end":1494397665329562,"diff":10211},{"start":1494397665329583,"end":1494397665340039,"diff":10456},{"start":1494397665340057,"end":1494397665352583,"diff":12526},{"start":1494397665368708,"end":1494397665379396,"diff":10688},{"start":1494397665379423,"end":1494397665391052,"diff":11629},{"start":1494397665391078,"end":1494397665402939,"diff":11861},{"start":1494397665402963,"end":1494397665414151,"diff":11188},{"start":1494397665414187,"end":1494397665425219,"diff":11032},{"start":1494397665443861,"end":1494397665454955,"diff":11094},{"start":1494397665454993,"end":1494397665466214,"diff":11221},{"start":1494397665466235,"end":1494397665478951,"diff":12716},{"start":1494397665478976,"end":1494397665491088,"diff":12112},{"start":1494397665491152,"end":1494397665503721,"diff":12569},{"start":1494397665520521,"end":1494397665531094,"diff":10573},{"start":1494397665531140,"end":1494397665542992,"diff":11852},{"start":1494397665543010,"end":1494397665554765,"diff":11755},{"start":1494397665554800,"end":1494397665565911,"diff":11111},{"start":1494397665565930,"end":1494397665578581,"diff":12651},{"start":1494397665597037,"end":1494397665607588,"diff":10551},{"start":1494397665607616,"end":1494397665620263,"diff":12647},{"start":1494397665620285,"end":1494397665634009,"diff":13724},{"start":1494397665634028,"end":1494397665646329,"diff":12301},{"start":1494397665646352,"end":1494397665657462,"diff":11110},{"start":1494397665677329,"end":1494397665688056,"diff":10727},{"start":1494397665688097,"end":1494397665700892,"diff":12795},{"start":1494397665700928,"end":1494397665712040,"diff":11112},{"start":1494397665712060,"end":1494397665722731,"diff":10671},{"start":1494397665722752,"end":1494397665735328,"diff":12576},{"start":1494397665755122,"end":1494397665768723,"diff":13601},{"start":1494397665768758,"end":1494397665779641,"diff":10883},{"start":1494397665779660,"end":1494397665790947,"diff":11287},{"start":1494397665790967,"end":1494397665801992,"diff":11025},{"start":1494397665802014,"end":1494397665814098,"diff":12084},{"start":1494397665833631,"end":1494397665846367,"diff":12736},{"start":1494397665846413,"end":1494397665858117,"diff":11704},{"start":1494397665858156,"end":1494397665870921,"diff":12765},{"start":1494397665870944,"end":1494397665882207,"diff":11263},{"start":1494397665882229,"end":1494397665892999,"diff":10770},{"start":1494397665909305,"end":1494397665918952,"diff":9647},{"start":1494397665918976,"end":1494397665929126,"diff":10150},{"start":1494397665929182,"end":1494397665940775,"diff":11593},{"start":1494397665940834,"end":1494397665951737,"diff":10903},{"start":1494397665951750,"end":1494397665964050,"diff":12300},{"start":1494397665983942,"end":1494397665995100,"diff":11158},{"start":1494397665995141,"end":1494397666006784,"diff":11643},{"start":1494397666006806,"end":1494397666017814,"diff":11008},{"start":1494397666017839,"end":1494397666029292,"diff":11453},{"start":1494397666029352,"end":1494397666041118,"diff":11766},{"start":1494397666057978,"end":1494397666070432,"diff":12454},{"start":1494397666070476,"end":1494397666082352,"diff":11876},{"start":1494397666082375,"end":1494397666093077,"diff":10702},{"start":1494397666093097,"end":1494397666104811,"diff":11714},{"start":1494397666104880,"end":1494397666117641,"diff":12761},{"start":1494397666134358,"end":1494397666144245,"diff":9887},{"start":1494397666144335,"end":1494397666153834,"diff":9499},{"start":1494397666153853,"end":1494397666164189,"diff":10336},{"start":1494397666164211,"end":1494397666176159,"diff":11948},{"start":1494397666176179,"end":1494397666187614,"diff":11435},{"start":1494397666205358,"end":1494397666214644,"diff":9286},{"start":1494397666214683,"end":1494397666225616,"diff":10933},{"start":1494397666225652,"end":1494397666235907,"diff":10255},{"start":1494397666235927,"end":1494397666246898,"diff":10971},{"start":1494397666246922,"end":1494397666257885,"diff":10963},{"start":1494397666276389,"end":1494397666285562,"diff":9173},{"start":1494397666285602,"end":1494397666296879,"diff":11277},{"start":1494397666296904,"end":1494397666308286,"diff":11382},{"start":1494397666308310,"end":1494397666317519,"diff":9209},{"start":1494397666317535,"end":1494397666329529,"diff":11994},{"start":1494397666347633,"end":1494397666358317,"diff":10684},{"start":1494397666358367,"end":1494397666369629,"diff":11262},{"start":1494397666369644,"end":1494397666382301,"diff":12657},{"start":1494397666382325,"end":1494397666393060,"diff":10735},{"start":1494397666393081,"end":1494397666402982,"diff":9901},{"start":1494397666421126,"end":1494397666433943,"diff":12817},{"start":1494397666433991,"end":1494397666446872,"diff":12881},{"start":1494397666446895,"end":1494397666457960,"diff":11065},{"start":1494397666457980,"end":1494397666468156,"diff":10176},{"start":1494397666468175,"end":1494397666479354,"diff":11179},{"start":1494397666499932,"end":1494397666511151,"diff":11219},{"start":1494397666511191,"end":1494397666523663,"diff":12472},{"start":1494397666523702,"end":1494397666535262,"diff":11560},{"start":1494397666535286,"end":1494397666546823,"diff":11537},{"start":1494397666546849,"end":1494397666558400,"diff":11551},{"start":1494397666575701,"end":1494397666586214,"diff":10513},{"start":1494397666586255,"end":1494397666596829,"diff":10574},{"start":1494397666596852,"end":1494397666607985,"diff":11133},{"start":1494397666608003,"end":1494397666618211,"diff":10208},{"start":1494397666618233,"end":1494397666629585,"diff":11352},{"start":1494397666645673,"end":1494397666656293,"diff":10620},{"start":1494397666656335,"end":1494397666667793,"diff":11458},{"start":1494397666667820,"end":1494397666679433,"diff":11613},{"start":1494397666679458,"end":1494397666691021,"diff":11563},{"start":1494397666691045,"end":1494397666703406,"diff":12361},{"start":1494397666719571,"end":1494397666731152,"diff":11581},{"start":1494397666731187,"end":1494397666742932,"diff":11745},{"start":1494397666742950,"end":1494397666754691,"diff":11741},{"start":1494397666754715,"end":1494397666767424,"diff":12709},{"start":1494397666767489,"end":1494397666778145,"diff":10656},{"start":1494397666794835,"end":1494397666805606,"diff":10771},{"start":1494397666805642,"end":1494397666817903,"diff":12261},{"start":1494397666817924,"end":1494397666829841,"diff":11917},{"start":1494397666829859,"end":1494397666841112,"diff":11253},{"start":1494397666841145,"end":1494397666853545,"diff":12400},{"start":1494397666870751,"end":1494397666883384,"diff":12633},{"start":1494397666883420,"end":1494397666895163,"diff":11743},{"start":1494397666895184,"end":1494397666906247,"diff":11063},{"start":1494397666906271,"end":1494397666918138,"diff":11867},{"start":1494397666918155,"end":1494397666929494,"diff":11339},{"start":1494397666945406,"end":1494397666958034,"diff":12628},{"start":1494397666958073,"end":1494397666967780,"diff":9707},{"start":1494397666967794,"end":1494397666979362,"diff":11568},{"start":1494397666979383,"end":1494397666991121,"diff":11738},{"start":1494397666991161,"end":1494397667002311,"diff":11150},{"start":1494397667018895,"end":1494397667029437,"diff":10542},{"start":1494397667029478,"end":1494397667041304,"diff":11826},{"start":1494397667041324,"end":1494397667051195,"diff":9871},{"start":1494397667051235,"end":1494397667062295,"diff":11060},{"start":1494397667062315,"end":1494397667073538,"diff":11223},{"start":1494397667089704,"end":1494397667100159,"diff":10455},{"start":1494397667100206,"end":1494397667112474,"diff":12268},{"start":1494397667112494,"end":1494397667123805,"diff":11311},{"start":1494397667123829,"end":1494397667136380,"diff":12551},{"start":1494397667136403,"end":1494397667147394,"diff":10991},{"start":1494397667165550,"end":1494397667178299,"diff":12749},{"start":1494397667178380,"end":1494397667190961,"diff":12581},{"start":1494397667190984,"end":1494397667202919,"diff":11935},{"start":1494397667202942,"end":1494397667214112,"diff":11170},{"start":1494397667214143,"end":1494397667224756,"diff":10613},{"start":1494397667240799,"end":1494397667252242,"diff":11443},{"start":1494397667252265,"end":1494397667263993,"diff":11728},{"start":1494397667264014,"end":1494397667275341,"diff":11327},{"start":1494397667275361,"end":1494397667286176,"diff":10815},{"start":1494397667286186,"end":1494397667296497,"diff":10311},{"start":1494397667314204,"end":1494397667326078,"diff":11874},{"start":1494397667326192,"end":1494397667337625,"diff":11433},{"start":1494397667337645,"end":1494397667349712,"diff":12067},{"start":1494397667349727,"end":1494397667360879,"diff":11152},{"start":1494397667360905,"end":1494397667370943,"diff":10038},{"start":1494397667387436,"end":1494397667398267,"diff":10831},{"start":1494397667398335,"end":1494397667409002,"diff":10667},{"start":1494397667409040,"end":1494397667421817,"diff":12777},{"start":1494397667421840,"end":1494397667434602,"diff":12762},{"start":1494397667434642,"end":1494397667445485,"diff":10843},{"start":1494397667462287,"end":1494397667472785,"diff":10498},{"start":1494397667472948,"end":1494397667485297,"diff":12349},{"start":1494397667485351,"end":1494397667498142,"diff":12791},{"start":1494397667498181,"end":1494397667510980,"diff":12799},{"start":1494397667511003,"end":1494397667523756,"diff":12753},{"start":1494397667540018,"end":1494397667552807,"diff":12789},{"start":1494397667552902,"end":1494397667564933,"diff":12031},{"start":1494397667564955,"end":1494397667577679,"diff":12724},{"start":1494397667577703,"end":1494397667590445,"diff":12742},{"start":1494397667590469,"end":1494397667603215,"diff":12746},{"start":1494397667621831,"end":1494397667634364,"diff":12533},{"start":1494397667634411,"end":1494397667646183,"diff":11772},{"start":1494397667646220,"end":1494397667657678,"diff":11458},{"start":1494397667657697,"end":1494397667668069,"diff":10372},{"start":1494397667668093,"end":1494397667679248,"diff":11155},{"start":1494397667697766,"end":1494397667709024,"diff":11258},{"start":1494397667709062,"end":1494397667721636,"diff":12574},{"start":1494397667721660,"end":1494397667734461,"diff":12801},{"start":1494397667734500,"end":1494397667746812,"diff":12312},{"start":1494397667746835,"end":1494397667757921,"diff":11086},{"start":1494397667775523,"end":1494397667788369,"diff":12846},{"start":1494397667788414,"end":1494397667798681,"diff":10267},{"start":1494397667798703,"end":1494397667809101,"diff":10398},{"start":1494397667809120,"end":1494397667820593,"diff":11473},{"start":1494397667820617,"end":1494397667832578,"diff":11961},{"start":1494397667851646,"end":1494397667862009,"diff":10363},{"start":1494397667862116,"end":1494397667873216,"diff":11100},{"start":1494397667873253,"end":1494397667883552,"diff":10299},{"start":1494397667883574,"end":1494397667896331,"diff":12757},{"start":1494397667896369,"end":1494397667907851,"diff":11482},{"start":1494397667926126,"end":1494397667937840,"diff":11714},{"start":1494397667937885,"end":1494397667949170,"diff":11285},{"start":1494397667949194,"end":1494397667961971,"diff":12777},{"start":1494397667961993,"end":1494397667973546,"diff":11553},{"start":1494397667973589,"end":1494397667985180,"diff":11591},{"start":1494397668004352,"end":1494397668014605,"diff":10253},{"start":1494397668014645,"end":1494397668027148,"diff":12503},{"start":1494397668027186,"end":1494397668038351,"diff":11165},{"start":1494397668038374,"end":1494397668051094,"diff":12720},{"start":1494397668051118,"end":1494397668061808,"diff":10690},{"start":1494397668078467,"end":1494397668090783,"diff":12316},{"start":1494397668090809,"end":1494397668101425,"diff":10616},{"start":1494397668101449,"end":1494397668114044,"diff":12595},{"start":1494397668114066,"end":1494397668125756,"diff":11690},{"start":1494397668125780,"end":1494397668135984,"diff":10204},{"start":1494397668155390,"end":1494397668168170,"diff":12780},{"start":1494397668168207,"end":1494397668179522,"diff":11315},{"start":1494397668179542,"end":1494397668190861,"diff":11319},{"start":1494397668190934,"end":1494397668203001,"diff":12067},{"start":1494397668203037,"end":1494397668213999,"diff":10962},{"start":1494397668233892,"end":1494397668244685,"diff":10793},{"start":1494397668244735,"end":1494397668254906,"diff":10171},{"start":1494397668254927,"end":1494397668265570,"diff":10643},{"start":1494397668265591,"end":1494397668278356,"diff":12765},{"start":1494397668278377,"end":1494397668291064,"diff":12687},{"start":1494397668308330,"end":1494397668320982,"diff":12652},{"start":1494397668321035,"end":1494397668333736,"diff":12701},{"start":1494397668333760,"end":1494397668344662,"diff":10902},{"start":1494397668344684,"end":1494397668356879,"diff":12195},{"start":1494397668356901,"end":1494397668367619,"diff":10718},{"start":1494397668384435,"end":1494397668396666,"diff":12231},{"start":1494397668396714,"end":1494397668408119,"diff":11405},{"start":1494397668408144,"end":1494397668418993,"diff":10849},{"start":1494397668419013,"end":1494397668430613,"diff":11600},{"start":1494397668430635,"end":1494397668442868,"diff":12233},{"start":1494397668461177,"end":1494397668472077,"diff":10900},{"start":1494397668472142,"end":1494397668484131,"diff":11989},{"start":1494397668484204,"end":1494397668495731,"diff":11527},{"start":1494397668495773,"end":1494397668506400,"diff":10627},{"start":1494397668506438,"end":1494397668517798,"diff":11360},{"start":1494397668535661,"end":1494397668546873,"diff":11212},{"start":1494397668546953,"end":1494397668557905,"diff":10952},{"start":1494397668557926,"end":1494397668570248,"diff":12322},{"start":1494397668570269,"end":1494397668581785,"diff":11516},{"start":1494397668581826,"end":1494397668593244,"diff":11418},{"start":1494397668611086,"end":1494397668622995,"diff":11909},{"start":1494397668623147,"end":1494397668635451,"diff":12304},{"start":1494397668635476,"end":1494397668647100,"diff":11624},{"start":1494397668647141,"end":1494397668658482,"diff":11341},{"start":1494397668658508,"end":1494397668669110,"diff":10602},{"start":1494397668687272,"end":1494397668696915,"diff":9643},{"start":1494397668697028,"end":1494397668707928,"diff":10900},{"start":1494397668707949,"end":1494397668720229,"diff":12280},{"start":1494397668720269,"end":1494397668729617,"diff":9348},{"start":1494397668729650,"end":1494397668740823,"diff":11173},{"start":1494397668758529,"end":1494397668770121,"diff":11592},{"start":1494397668770161,"end":1494397668782933,"diff":12772},{"start":1494397668782971,"end":1494397668795097,"diff":12126},{"start":1494397668795123,"end":1494397668806234,"diff":11111},{"start":1494397668806258,"end":1494397668817795,"diff":11537},{"start":1494397668834293,"end":1494397668844551,"diff":10258},{"start":1494397668844593,"end":1494397668854802,"diff":10209},{"start":1494397668854824,"end":1494397668867477,"diff":12653},{"start":1494397668867500,"end":1494397668879251,"diff":11751},{"start":1494397668879298,"end":1494397668890987,"diff":11689},{"start":1494397668907831,"end":1494397668917473,"diff":9642},{"start":1494397668917513,"end":1494397668929278,"diff":11765},{"start":1494397668929300,"end":1494397668940935,"diff":11635},{"start":1494397668940961,"end":1494397668952689,"diff":11728},{"start":1494397668952728,"end":1494397668964108,"diff":11380},{"start":1494397668982772,"end":1494397668993892,"diff":11120},{"start":1494397668993946,"end":1494397669004729,"diff":10783},{"start":1494397669004750,"end":1494397669015234,"diff":10484},{"start":1494397669015255,"end":1494397669024437,"diff":9182},{"start":1494397669024461,"end":1494397669035219,"diff":10758},{"start":1494397669052966,"end":1494397669064096,"diff":11130},{"start":1494397669064137,"end":1494397669073403,"diff":9266},{"start":1494397669073419,"end":1494397669086197,"diff":12778},{"start":1494397669086217,"end":1494397669096973,"diff":10756},{"start":1494397669097017,"end":1494397669108882,"diff":11865},{"start":1494397669128486,"end":1494397669141164,"diff":12678},{"start":1494397669141207,"end":1494397669153017,"diff":11810},{"start":1494397669153042,"end":1494397669164014,"diff":10972},{"start":1494397669164039,"end":1494397669176805,"diff":12766},{"start":1494397669176829,"end":1494397669187100,"diff":10271},{"start":1494397669205619,"end":1494397669217573,"diff":11954},{"start":1494397669217672,"end":1494397669228031,"diff":10359},{"start":1494397669228053,"end":1494397669237792,"diff":9739},{"start":1494397669237812,"end":1494397669250522,"diff":12710},{"start":1494397669250563,"end":1494397669260938,"diff":10375},{"start":1494397669278835,"end":1494397669290908,"diff":12073},{"start":1494397669291105,"end":1494397669301470,"diff":10365},{"start":1494397669301516,"end":1494397669313744,"diff":12228},{"start":1494397669313767,"end":1494397669325498,"diff":11731},{"start":1494397669325520,"end":1494397669337974,"diff":12454},{"start":1494397669363429,"end":1494397669374994,"diff":11565},{"start":1494397669375019,"end":1494397669387662,"diff":12643},{"start":1494397669387673,"end":1494397669400421,"diff":12748},{"start":1494397669400441,"end":1494397669412865,"diff":12424},{"start":1494397669412884,"end":1494397669423335,"diff":10451},{"start":1494397669439883,"end":1494397669452111,"diff":12228},{"start":1494397669452159,"end":1494397669463982,"diff":11823},{"start":1494397669464008,"end":1494397669474361,"diff":10353},{"start":1494397669474383,"end":1494397669486278,"diff":11895},{"start":1494397669486298,"end":1494397669496841,"diff":10543},{"start":1494397669514962,"end":1494397669527687,"diff":12725},{"start":1494397669527736,"end":1494397669537957,"diff":10221},{"start":1494397669537981,"end":1494397669548189,"diff":10208},{"start":1494397669548213,"end":1494397669557703,"diff":9490},{"start":1494397669557726,"end":1494397669568071,"diff":10345},{"start":1494397669583424,"end":1494397669596023,"diff":12599},{"start":1494397669596104,"end":1494397669608301,"diff":12197},{"start":1494397669608326,"end":1494397669620011,"diff":11685},{"start":1494397669620035,"end":1494397669632767,"diff":12732},{"start":1494397669632790,"end":1494397669645605,"diff":12815},{"start":1494397669663017,"end":1494397669673693,"diff":10676},{"start":1494397669673753,"end":1494397669685358,"diff":11605},{"start":1494397669685386,"end":1494397669698160,"diff":12774},{"start":1494397669698185,"end":1494397669708483,"diff":10298},{"start":1494397669708507,"end":1494397669718925,"diff":10418},{"start":1494397669735361,"end":1494397669746757,"diff":11396},{"start":1494397669746805,"end":1494397669757825,"diff":11020},{"start":1494397669757846,"end":1494397669770579,"diff":12733},{"start":1494397669770603,"end":1494397669780947,"diff":10344},{"start":1494397669780968,"end":1494397669792824,"diff":11856},{"start":1494397669811174,"end":1494397669822783,"diff":11609},{"start":1494397669822861,"end":1494397669833602,"diff":10741},{"start":1494397669833627,"end":1494397669846395,"diff":12768},{"start":1494397669846434,"end":1494397669857031,"diff":10597},{"start":1494397669857053,"end":1494397669867602,"diff":10549},{"start":1494397669886184,"end":1494397669896626,"diff":10442},{"start":1494397669896674,"end":1494397669907644,"diff":10970},{"start":1494397669907666,"end":1494397669920392,"diff":12726},{"start":1494397669920417,"end":1494397669932005,"diff":11588},{"start":1494397669932031,"end":1494397669942926,"diff":10895},{"start":1494397669959412,"end":1494397669972188,"diff":12776},{"start":1494397669972290,"end":1494397669985130,"diff":12840},{"start":1494397669985153,"end":1494397669996858,"diff":11705},{"start":1494397669996882,"end":1494397670009260,"diff":12378},{"start":1494397670009286,"end":1494397670021046,"diff":11760},{"start":1494397670039541,"end":1494397670051513,"diff":11972},{"start":1494397670051640,"end":1494397670064003,"diff":12363},{"start":1494397670064027,"end":1494397670074186,"diff":10159},{"start":1494397670074210,"end":1494397670085198,"diff":10988},{"start":1494397670085222,"end":1494397670096624,"diff":11402},{"start":1494397670113808,"end":1494397670125724,"diff":11916},{"start":1494397670125776,"end":1494397670136468,"diff":10692},{"start":1494397670136507,"end":1494397670149284,"diff":12777},{"start":1494397670149347,"end":1494397670160386,"diff":11039},{"start":1494397670160420,"end":1494397670171476,"diff":11056},{"start":1494397670190333,"end":1494397670201766,"diff":11433},{"start":1494397670201814,"end":1494397670213991,"diff":12177},{"start":1494397670214013,"end":1494397670223556,"diff":9543},{"start":1494397670223581,"end":1494397670235129,"diff":11548},{"start":1494397670235156,"end":1494397670246242,"diff":11086},{"start":1494397670262914,"end":1494397670273348,"diff":10434},{"start":1494397670273411,"end":1494397670285005,"diff":11594},{"start":1494397670285029,"end":1494397670296717,"diff":11688},{"start":1494397670296742,"end":1494397670307975,"diff":11233},{"start":1494397670307996,"end":1494397670320716,"diff":12720}],"now":1494397670329,"mem":{"start":{"process":{"rss":53198848,"heapTotal":31195136,"heapUsed":24678824,"external":1889462},"os":233902080},"end":{"process":{"rss":65474560,"heapTotal":44322816,"heapUsed":30264584,"external":17476},"os":213512192}},"stats":{"moe":0.00009688315553219888,"rme":0.842669905861672,"sem":0.00004943018139397902,"deviation":0.00043655554165083083,"mean":0.011497165717948716,"sample":[0.0110049358,0.011262863,0.0114084858,0.0119228394,0.0116042838,0.011064730200000001,0.011248045199999999,0.011135131400000001,0.0121489582,0.0114597846,0.0118371094,0.0112118606,0.0113165886,0.0119874604,0.0116273716,0.0120970358,0.0116286402,0.011811271199999999,0.0118913914,0.010968740000000001,0.0114494518,0.0119496378,0.0106679312,0.0105229678,0.010644291,0.0110877396,0.0116590146,0.011710527799999999,0.0107938706,0.01157472,0.0117270098,0.01175611,0.0117632382,0.0113959886,0.0109478376,0.0115535376,0.0118565418,0.011152871200000001,0.0113616434,0.0116259926,0.0123172448,0.0126567612,0.0115035236,0.012046949,0.0114266366,0.0112578168,0.0118366158,0.0115273836,0.0115189276,0.0117384896,0.0114516588,0.0118736178,0.0117030306,0.011340925,0.0115366934,0.0116224862,0.0107274786,0.0118727608,0.011354425,0.0112745746,0.0105079594,0.0112006868,0.01173699,0.0110813788,0.0118430222,0.0120003578,0.011424674999999999,0.0106350258,0.012448994,0.0111962686,0.011507952200000001,0.0113008172,0.0113655066,0.0123423692,0.011433365,0.0115516226,0.0112009564,0.0115745294],"variance":1.905807409460503e-7},"count":5,"hz":86.9779582666063,"time":11.497165717948716,"cycles":2,"battery":{"amperage":-2489,"currentCapacity":3822,"percent":51,"charging":"","temp":3105}},{"msg":"zoomzoom x 87.83 ops/sec ±0.88% (78 runs sampled)","name":"zoomzoom","num":87.83,"sampled":"78","variation":"0.88","suite":["/Users/james/code/fluents/chain/packages/bench-chain/example/math/async-first-faster.json"],"timesFor":[{"start":1494397785984311,"end":1494397785995496,"diff":11185},{"start":1494397786003059,"end":1494397786013501,"diff":10442},{"start":1494397786013705,"end":1494397786024163,"diff":10458},{"start":1494397786024217,"end":1494397786036999,"diff":12782},{"start":1494397786037020,"end":1494397786048849,"diff":11829},{"start":1494397786048871,"end":1494397786060577,"diff":11706},{"start":1494397786090254,"end":1494397786100465,"diff":10211},{"start":1494397786100559,"end":1494397786111263,"diff":10704},{"start":1494397786111416,"end":1494397786123371,"diff":11955},{"start":1494397786123443,"end":1494397786136241,"diff":12798},{"start":1494397786136282,"end":1494397786148322,"diff":12040},{"start":1494397786170641,"end":1494397786184240,"diff":13599},{"start":1494397786184276,"end":1494397786196218,"diff":11942},{"start":1494397786196259,"end":1494397786208135,"diff":11876},{"start":1494397786208155,"end":1494397786219693,"diff":11538},{"start":1494397786219715,"end":1494397786231357,"diff":11642},{"start":1494397786250943,"end":1494397786262224,"diff":11281},{"start":1494397786262306,"end":1494397786273229,"diff":10923},{"start":1494397786273251,"end":1494397786283610,"diff":10359},{"start":1494397786283636,"end":1494397786295049,"diff":11413},{"start":1494397786295161,"end":1494397786306587,"diff":11426},{"start":1494397786324902,"end":1494397786335596,"diff":10694},{"start":1494397786335638,"end":1494397786348378,"diff":12740},{"start":1494397786348402,"end":1494397786360282,"diff":11880},{"start":1494397786360317,"end":1494397786370701,"diff":10384},{"start":1494397786370732,"end":1494397786382157,"diff":11425},{"start":1494397786401978,"end":1494397786414147,"diff":12169},{"start":1494397786414200,"end":1494397786424448,"diff":10248},{"start":1494397786424472,"end":1494397786433737,"diff":9265},{"start":1494397786433758,"end":1494397786444991,"diff":11233},{"start":1494397786445021,"end":1494397786456532,"diff":11511},{"start":1494397786477128,"end":1494397786489290,"diff":12162},{"start":1494397786489335,"end":1494397786499863,"diff":10528},{"start":1494397786499884,"end":1494397786512533,"diff":12649},{"start":1494397786512554,"end":1494397786523388,"diff":10834},{"start":1494397786523414,"end":1494397786536154,"diff":12740},{"start":1494397786558728,"end":1494397786571483,"diff":12755},{"start":1494397786571528,"end":1494397786583368,"diff":11840},{"start":1494397786583390,"end":1494397786595031,"diff":11641},{"start":1494397786595070,"end":1494397786606897,"diff":11827},{"start":1494397786606926,"end":1494397786619713,"diff":12787},{"start":1494397786637500,"end":1494397786648374,"diff":10874},{"start":1494397786648410,"end":1494397786657748,"diff":9338},{"start":1494397786657789,"end":1494397786670211,"diff":12422},{"start":1494397786670235,"end":1494397786682981,"diff":12746},{"start":1494397786683005,"end":1494397786695052,"diff":12047},{"start":1494397786713980,"end":1494397786725613,"diff":11633},{"start":1494397786725665,"end":1494397786738227,"diff":12562},{"start":1494397786738248,"end":1494397786749022,"diff":10774},{"start":1494397786749043,"end":1494397786760220,"diff":11177},{"start":1494397786760244,"end":1494397786771926,"diff":11682},{"start":1494397786789570,"end":1494397786801380,"diff":11810},{"start":1494397786801492,"end":1494397786812283,"diff":10791},{"start":1494397786812304,"end":1494397786822687,"diff":10383},{"start":1494397786822710,"end":1494397786834555,"diff":11845},{"start":1494397786834577,"end":1494397786845069,"diff":10492},{"start":1494397786862045,"end":1494397786873827,"diff":11782},{"start":1494397786873860,"end":1494397786886500,"diff":12640},{"start":1494397786886517,"end":1494397786896079,"diff":9562},{"start":1494397786896098,"end":1494397786906673,"diff":10575},{"start":1494397786906696,"end":1494397786919389,"diff":12693},{"start":1494397786937591,"end":1494397786948339,"diff":10748},{"start":1494397786948420,"end":1494397786960038,"diff":11618},{"start":1494397786960058,"end":1494397786971697,"diff":11639},{"start":1494397786971738,"end":1494397786982006,"diff":10268},{"start":1494397786982036,"end":1494397786993556,"diff":11520},{"start":1494397787011567,"end":1494397787022304,"diff":10737},{"start":1494397787022345,"end":1494397787035104,"diff":12759},{"start":1494397787035129,"end":1494397787045448,"diff":10319},{"start":1494397787045472,"end":1494397787055295,"diff":9823},{"start":1494397787055318,"end":1494397787066216,"diff":10898},{"start":1494397787084044,"end":1494397787094862,"diff":10818},{"start":1494397787094913,"end":1494397787106929,"diff":12016},{"start":1494397787106951,"end":1494397787119594,"diff":12643},{"start":1494397787119613,"end":1494397787129864,"diff":10251},{"start":1494397787129895,"end":1494397787140289,"diff":10394},{"start":1494397787156833,"end":1494397787167092,"diff":10259},{"start":1494397787167115,"end":1494397787177433,"diff":10318},{"start":1494397787177466,"end":1494397787189263,"diff":11797},{"start":1494397787189285,"end":1494397787202242,"diff":12957},{"start":1494397787202253,"end":1494397787213472,"diff":11219},{"start":1494397787231201,"end":1494397787242164,"diff":10963},{"start":1494397787242188,"end":1494397787253933,"diff":11745},{"start":1494397787253995,"end":1494397787265395,"diff":11400},{"start":1494397787265413,"end":1494397787277048,"diff":11635},{"start":1494397787277095,"end":1494397787289746,"diff":12651},{"start":1494397787308515,"end":1494397787327227,"diff":18712},{"start":1494397787327256,"end":1494397787339307,"diff":12051},{"start":1494397787339319,"end":1494397787352185,"diff":12866},{"start":1494397787352199,"end":1494397787364431,"diff":12232},{"start":1494397787364448,"end":1494397787375641,"diff":11193},{"start":1494397787395314,"end":1494397787405604,"diff":10290},{"start":1494397787405628,"end":1494397787416253,"diff":10625},{"start":1494397787416267,"end":1494397787427866,"diff":11599},{"start":1494397787427880,"end":1494397787439476,"diff":11596},{"start":1494397787439506,"end":1494397787451087,"diff":11581},{"start":1494397787469561,"end":1494397787480107,"diff":10546},{"start":1494397787480134,"end":1494397787491717,"diff":11583},{"start":1494397787491731,"end":1494397787503339,"diff":11608},{"start":1494397787503356,"end":1494397787514953,"diff":11597},{"start":1494397787514967,"end":1494397787526551,"diff":11584},{"start":1494397787550731,"end":1494397787562403,"diff":11672},{"start":1494397787562436,"end":1494397787572873,"diff":10437},{"start":1494397787572889,"end":1494397787587153,"diff":14264},{"start":1494397787587381,"end":1494397787598819,"diff":11438},{"start":1494397787598834,"end":1494397787610634,"diff":11800},{"start":1494397787630180,"end":1494397787640937,"diff":10757},{"start":1494397787640961,"end":1494397787653549,"diff":12588},{"start":1494397787653564,"end":1494397787666023,"diff":12459},{"start":1494397787666039,"end":1494397787677513,"diff":11474},{"start":1494397787677541,"end":1494397787688792,"diff":11251},{"start":1494397787706382,"end":1494397787718173,"diff":11791},{"start":1494397787718203,"end":1494397787729742,"diff":11539},{"start":1494397787729757,"end":1494397787739914,"diff":10157},{"start":1494397787739929,"end":1494397787750156,"diff":10227},{"start":1494397787750187,"end":1494397787760404,"diff":10217},{"start":1494397787784205,"end":1494397787795882,"diff":11677},{"start":1494397787795919,"end":1494397787805968,"diff":10049},{"start":1494397787805996,"end":1494397787817103,"diff":11107},{"start":1494397787817122,"end":1494397787828223,"diff":11101},{"start":1494397787828265,"end":1494397787838652,"diff":10387},{"start":1494397787862980,"end":1494397787873956,"diff":10976},{"start":1494397787873989,"end":1494397787884493,"diff":10504},{"start":1494397787884517,"end":1494397787894773,"diff":10256},{"start":1494397787894799,"end":1494397787908333,"diff":13534},{"start":1494397787908407,"end":1494397787918035,"diff":9628},{"start":1494397787937760,"end":1494397787948952,"diff":11192},{"start":1494397787948986,"end":1494397787959199,"diff":10213},{"start":1494397787959214,"end":1494397787969819,"diff":10605},{"start":1494397787969833,"end":1494397787980235,"diff":10402},{"start":1494397787980251,"end":1494397787991066,"diff":10815},{"start":1494397788009092,"end":1494397788020256,"diff":11164},{"start":1494397788020283,"end":1494397788031655,"diff":11372},{"start":1494397788031668,"end":1494397788042076,"diff":10408},{"start":1494397788042125,"end":1494397788053648,"diff":11523},{"start":1494397788053666,"end":1494397788065825,"diff":12159},{"start":1494397788083023,"end":1494397788095493,"diff":12470},{"start":1494397788095535,"end":1494397788107091,"diff":11556},{"start":1494397788107119,"end":1494397788117302,"diff":10183},{"start":1494397788117316,"end":1494397788127728,"diff":10412},{"start":1494397788127769,"end":1494397788138900,"diff":11131},{"start":1494397788155050,"end":1494397788165309,"diff":10259},{"start":1494397788165332,"end":1494397788176203,"diff":10871},{"start":1494397788176229,"end":1494397788188436,"diff":12207},{"start":1494397788188469,"end":1494397788200106,"diff":11637},{"start":1494397788200119,"end":1494397788210505,"diff":10386},{"start":1494397788228306,"end":1494397788240609,"diff":12303},{"start":1494397788240646,"end":1494397788252263,"diff":11617},{"start":1494397788252317,"end":1494397788263973,"diff":11656},{"start":1494397788263985,"end":1494397788275676,"diff":11691},{"start":1494397788275720,"end":1494397788288078,"diff":12358},{"start":1494397788303470,"end":1494397788312675,"diff":9205},{"start":1494397788312783,"end":1494397788323244,"diff":10461},{"start":1494397788323256,"end":1494397788334612,"diff":11356},{"start":1494397788334630,"end":1494397788345014,"diff":10384},{"start":1494397788345060,"end":1494397788355637,"diff":10577},{"start":1494397788372815,"end":1494397788383114,"diff":10299},{"start":1494397788383149,"end":1494397788395320,"diff":12171},{"start":1494397788395333,"end":1494397788405624,"diff":10291},{"start":1494397788405639,"end":1494397788416358,"diff":10719},{"start":1494397788416377,"end":1494397788427798,"diff":11421},{"start":1494397788443673,"end":1494397788454196,"diff":10523},{"start":1494397788454217,"end":1494397788465390,"diff":11173},{"start":1494397788465401,"end":1494397788477143,"diff":11742},{"start":1494397788477155,"end":1494397788489028,"diff":11873},{"start":1494397788489041,"end":1494397788500952,"diff":11911},{"start":1494397788517043,"end":1494397788529258,"diff":12215},{"start":1494397788529281,"end":1494397788540399,"diff":11118},{"start":1494397788540440,"end":1494397788551850,"diff":11410},{"start":1494397788551873,"end":1494397788563398,"diff":11525},{"start":1494397788563416,"end":1494397788572888,"diff":9472},{"start":1494397788591201,"end":1494397788603941,"diff":12740},{"start":1494397788604002,"end":1494397788615694,"diff":11692},{"start":1494397788615716,"end":1494397788626791,"diff":11075},{"start":1494397788626811,"end":1494397788638144,"diff":11333},{"start":1494397788638170,"end":1494397788650532,"diff":12362},{"start":1494397788666734,"end":1494397788677810,"diff":11076},{"start":1494397788677847,"end":1494397788689155,"diff":11308},{"start":1494397788689176,"end":1494397788699550,"diff":10374},{"start":1494397788699568,"end":1494397788710571,"diff":11003},{"start":1494397788710592,"end":1494397788722441,"diff":11849},{"start":1494397788737783,"end":1494397788748124,"diff":10341},{"start":1494397788748190,"end":1494397788760751,"diff":12561},{"start":1494397788760777,"end":1494397788770748,"diff":9971},{"start":1494397788770761,"end":1494397788781175,"diff":10414},{"start":1494397788781198,"end":1494397788793851,"diff":12653},{"start":1494397788814258,"end":1494397788824912,"diff":10654},{"start":1494397788825013,"end":1494397788836169,"diff":11156},{"start":1494397788836182,"end":1494397788849320,"diff":13138},{"start":1494397788849351,"end":1494397788859544,"diff":10193},{"start":1494397788859591,"end":1494397788871017,"diff":11426},{"start":1494397788887663,"end":1494397788899675,"diff":12012},{"start":1494397788899716,"end":1494397788911072,"diff":11356},{"start":1494397788911100,"end":1494397788922388,"diff":11288},{"start":1494397788922401,"end":1494397788932061,"diff":9660},{"start":1494397788932075,"end":1494397788942526,"diff":10451},{"start":1494397788958757,"end":1494397788971531,"diff":12774},{"start":1494397788971553,"end":1494397788982957,"diff":11404},{"start":1494397788982981,"end":1494397788994866,"diff":11885},{"start":1494397788994887,"end":1494397789005806,"diff":10919},{"start":1494397789005827,"end":1494397789016496,"diff":10669},{"start":1494397789033285,"end":1494397789044814,"diff":11529},{"start":1494397789044853,"end":1494397789056350,"diff":11497},{"start":1494397789056372,"end":1494397789065922,"diff":9550},{"start":1494397789065949,"end":1494397789077485,"diff":11536},{"start":1494397789077519,"end":1494397789089302,"diff":11783},{"start":1494397789104525,"end":1494397789114879,"diff":10354},{"start":1494397789114922,"end":1494397789125156,"diff":10234},{"start":1494397789125225,"end":1494397789136997,"diff":11772},{"start":1494397789137019,"end":1494397789149239,"diff":12220},{"start":1494397789149272,"end":1494397789160030,"diff":10758},{"start":1494397789180193,"end":1494397789190882,"diff":10689},{"start":1494397789190982,"end":1494397789201623,"diff":10641},{"start":1494397789201679,"end":1494397789213251,"diff":11572},{"start":1494397789213344,"end":1494397789223915,"diff":10571},{"start":1494397789223948,"end":1494397789236450,"diff":12502},{"start":1494397789252962,"end":1494397789262462,"diff":9500},{"start":1494397789262505,"end":1494397789273927,"diff":11422},{"start":1494397789273943,"end":1494397789284982,"diff":11039},{"start":1494397789284997,"end":1494397789295480,"diff":10483},{"start":1494397789295567,"end":1494397789307453,"diff":11886},{"start":1494397789324252,"end":1494397789336960,"diff":12708},{"start":1494397789337100,"end":1494397789346625,"diff":9525},{"start":1494397789346652,"end":1494397789358289,"diff":11637},{"start":1494397789358310,"end":1494397789368578,"diff":10268},{"start":1494397789368595,"end":1494397789379212,"diff":10617},{"start":1494397789400630,"end":1494397789411280,"diff":10650},{"start":1494397789411323,"end":1494397789423600,"diff":12277},{"start":1494397789423623,"end":1494397789434430,"diff":10807},{"start":1494397789434450,"end":1494397789444777,"diff":10327},{"start":1494397789444796,"end":1494397789457018,"diff":12222},{"start":1494397789474475,"end":1494397789484810,"diff":10335},{"start":1494397789484845,"end":1494397789494984,"diff":10139},{"start":1494397789495005,"end":1494397789505472,"diff":10467},{"start":1494397789505490,"end":1494397789516223,"diff":10733},{"start":1494397789516272,"end":1494397789528222,"diff":11950},{"start":1494397789544327,"end":1494397789556491,"diff":12164},{"start":1494397789556524,"end":1494397789569204,"diff":12680},{"start":1494397789569224,"end":1494397789580126,"diff":10902},{"start":1494397789580165,"end":1494397789591127,"diff":10962},{"start":1494397789591154,"end":1494397789601511,"diff":10357},{"start":1494397789618895,"end":1494397789630293,"diff":11398},{"start":1494397789630316,"end":1494397789642920,"diff":12604},{"start":1494397789642942,"end":1494397789655138,"diff":12196},{"start":1494397789655152,"end":1494397789665351,"diff":10199},{"start":1494397789665365,"end":1494397789677385,"diff":12020},{"start":1494397789696649,"end":1494397789708621,"diff":11972},{"start":1494397789708764,"end":1494397789721079,"diff":12315},{"start":1494397789721098,"end":1494397789731340,"diff":10242},{"start":1494397789731361,"end":1494397789743125,"diff":11764},{"start":1494397789743162,"end":1494397789753976,"diff":10814},{"start":1494397789770632,"end":1494397789782820,"diff":12188},{"start":1494397789782864,"end":1494397789794825,"diff":11961},{"start":1494397789794848,"end":1494397789806467,"diff":11619},{"start":1494397789806491,"end":1494397789819242,"diff":12751},{"start":1494397789819303,"end":1494397789829020,"diff":9717},{"start":1494397789846450,"end":1494397789857946,"diff":11496},{"start":1494397789858028,"end":1494397789868325,"diff":10297},{"start":1494397789868350,"end":1494397789877488,"diff":9138},{"start":1494397789877502,"end":1494397789889135,"diff":11633},{"start":1494397789889155,"end":1494397789900694,"diff":11539},{"start":1494397789917907,"end":1494397789928182,"diff":10275},{"start":1494397789928290,"end":1494397789939207,"diff":10917},{"start":1494397789939218,"end":1494397789949352,"diff":10134},{"start":1494397789949368,"end":1494397789959564,"diff":10196},{"start":1494397789959707,"end":1494397789972497,"diff":12790},{"start":1494397789987390,"end":1494397789996673,"diff":9283},{"start":1494397789996700,"end":1494397790007030,"diff":10330},{"start":1494397790007052,"end":1494397790019246,"diff":12194},{"start":1494397790019290,"end":1494397790030984,"diff":11694},{"start":1494397790031166,"end":1494397790042433,"diff":11267},{"start":1494397790060790,"end":1494397790071113,"diff":10323},{"start":1494397790071176,"end":1494397790083162,"diff":11986},{"start":1494397790083186,"end":1494397790095479,"diff":12293},{"start":1494397790095501,"end":1494397790107746,"diff":12245},{"start":1494397790107792,"end":1494397790120549,"diff":12757},{"start":1494397790137167,"end":1494397790148399,"diff":11232},{"start":1494397790148439,"end":1494397790159948,"diff":11509},{"start":1494397790159971,"end":1494397790171664,"diff":11693},{"start":1494397790171690,"end":1494397790183315,"diff":11625},{"start":1494397790183356,"end":1494397790194844,"diff":11488},{"start":1494397790212140,"end":1494397790222639,"diff":10499},{"start":1494397790222679,"end":1494397790232720,"diff":10041},{"start":1494397790232740,"end":1494397790244724,"diff":11984},{"start":1494397790244745,"end":1494397790255888,"diff":11143},{"start":1494397790255906,"end":1494397790266025,"diff":10119},{"start":1494397790281320,"end":1494397790291889,"diff":10569},{"start":1494397790292056,"end":1494397790303066,"diff":11010},{"start":1494397790303087,"end":1494397790312914,"diff":9827},{"start":1494397790312923,"end":1494397790324688,"diff":11765},{"start":1494397790324731,"end":1494397790335907,"diff":11176},{"start":1494397790352837,"end":1494397790363191,"diff":10354},{"start":1494397790363255,"end":1494397790373946,"diff":10691},{"start":1494397790373959,"end":1494397790386601,"diff":12642},{"start":1494397790386616,"end":1494397790397763,"diff":11147},{"start":1494397790397785,"end":1494397790410515,"diff":12730},{"start":1494397790428731,"end":1494397790440115,"diff":11384},{"start":1494397790440167,"end":1494397790452897,"diff":12730},{"start":1494397790452921,"end":1494397790464397,"diff":11476},{"start":1494397790464421,"end":1494397790474619,"diff":10198},{"start":1494397790474644,"end":1494397790487816,"diff":13172},{"start":1494397790506386,"end":1494397790519096,"diff":12710},{"start":1494397790519169,"end":1494397790530968,"diff":11799},{"start":1494397790531015,"end":1494397790542823,"diff":11808},{"start":1494397790542845,"end":1494397790555147,"diff":12302},{"start":1494397790555170,"end":1494397790565878,"diff":10708},{"start":1494397790582103,"end":1494397790594779,"diff":12676},{"start":1494397790594823,"end":1494397790606075,"diff":11252},{"start":1494397790606098,"end":1494397790618861,"diff":12763},{"start":1494397790618901,"end":1494397790631050,"diff":12149},{"start":1494397790631085,"end":1494397790641287,"diff":10202},{"start":1494397790659661,"end":1494397790671853,"diff":12192},{"start":1494397790671895,"end":1494397790683440,"diff":11545},{"start":1494397790683463,"end":1494397790694783,"diff":11320},{"start":1494397790694810,"end":1494397790707305,"diff":12495},{"start":1494397790707364,"end":1494397790719217,"diff":11853},{"start":1494397790734232,"end":1494397790744724,"diff":10492},{"start":1494397790744765,"end":1494397790755974,"diff":11209},{"start":1494397790755988,"end":1494397790767447,"diff":11459},{"start":1494397790767476,"end":1494397790777942,"diff":10466},{"start":1494397790777974,"end":1494397790790324,"diff":12350},{"start":1494397790806172,"end":1494397790816488,"diff":10316},{"start":1494397790816512,"end":1494397790829106,"diff":12594},{"start":1494397790829119,"end":1494397790839400,"diff":10281},{"start":1494397790839412,"end":1494397790852074,"diff":12662},{"start":1494397790852092,"end":1494397790863756,"diff":11664},{"start":1494397790887193,"end":1494397790899974,"diff":12781},{"start":1494397790900003,"end":1494397790911974,"diff":11971},{"start":1494397790912054,"end":1494397790924917,"diff":12863},{"start":1494397790924981,"end":1494397790935267,"diff":10286},{"start":1494397790935286,"end":1494397790946579,"diff":11293},{"start":1494397790964033,"end":1494397790973600,"diff":9567},{"start":1494397790973632,"end":1494397790983753,"diff":10121},{"start":1494397790983769,"end":1494397790994872,"diff":11103},{"start":1494397790994985,"end":1494397791006979,"diff":11994},{"start":1494397791007003,"end":1494397791019814,"diff":12811},{"start":1494397791036821,"end":1494397791048847,"diff":12026},{"start":1494397791048881,"end":1494397791061231,"diff":12350},{"start":1494397791061272,"end":1494397791072188,"diff":10916},{"start":1494397791072210,"end":1494397791083760,"diff":11550},{"start":1494397791083780,"end":1494397791094962,"diff":11182},{"start":1494397791112544,"end":1494397791125244,"diff":12700},{"start":1494397791125378,"end":1494397791135540,"diff":10162},{"start":1494397791135568,"end":1494397791147091,"diff":11523},{"start":1494397791147111,"end":1494397791158457,"diff":11346},{"start":1494397791158561,"end":1494397791169546,"diff":10985},{"start":1494397791186108,"end":1494397791197958,"diff":11850},{"start":1494397791198017,"end":1494397791208900,"diff":10883},{"start":1494397791208964,"end":1494397791220934,"diff":11970},{"start":1494397791220968,"end":1494397791232943,"diff":11975},{"start":1494397791232964,"end":1494397791244723,"diff":11759},{"start":1494397791263099,"end":1494397791273420,"diff":10321},{"start":1494397791273464,"end":1494397791286156,"diff":12692},{"start":1494397791286177,"end":1494397791296041,"diff":9864},{"start":1494397791296059,"end":1494397791306705,"diff":10646},{"start":1494397791306727,"end":1494397791319441,"diff":12714},{"start":1494397791336151,"end":1494397791347655,"diff":11504},{"start":1494397791347679,"end":1494397791358444,"diff":10765},{"start":1494397791358505,"end":1494397791369168,"diff":10663},{"start":1494397791369181,"end":1494397791380071,"diff":10890},{"start":1494397791380098,"end":1494397791392357,"diff":12259},{"start":1494397791412000,"end":1494397791422697,"diff":10697},{"start":1494397791422727,"end":1494397791432977,"diff":10250},{"start":1494397791433011,"end":1494397791444750,"diff":11739},{"start":1494397791444779,"end":1494397791455074,"diff":10295},{"start":1494397791455089,"end":1494397791465364,"diff":10275},{"start":1494397791481667,"end":1494397791492589,"diff":10922},{"start":1494397791492625,"end":1494397791505163,"diff":12538},{"start":1494397791505186,"end":1494397791515366,"diff":10180},{"start":1494397791515391,"end":1494397791527077,"diff":11686},{"start":1494397791527098,"end":1494397791537898,"diff":10800},{"start":1494397791555064,"end":1494397791565354,"diff":10290},{"start":1494397791565378,"end":1494397791575658,"diff":10280},{"start":1494397791575723,"end":1494397791588017,"diff":12294},{"start":1494397791588037,"end":1494397791599508,"diff":11471},{"start":1494397791599531,"end":1494397791610727,"diff":11196},{"start":1494397791629805,"end":1494397791642092,"diff":12287},{"start":1494397791642220,"end":1494397791651882,"diff":9662},{"start":1494397791651906,"end":1494397791663390,"diff":11484},{"start":1494397791663417,"end":1494397791675039,"diff":11622},{"start":1494397791675059,"end":1494397791686823,"diff":11764},{"start":1494397791701624,"end":1494397791711713,"diff":10089},{"start":1494397791711737,"end":1494397791722706,"diff":10969},{"start":1494397791722720,"end":1494397791733101,"diff":10381},{"start":1494397791733114,"end":1494397791744675,"diff":11561},{"start":1494397791744700,"end":1494397791756221,"diff":11521},{"start":1494397791773698,"end":1494397791786375,"diff":12677},{"start":1494397791786452,"end":1494397791798401,"diff":11949},{"start":1494397791798423,"end":1494397791809890,"diff":11467},{"start":1494397791809940,"end":1494397791821553,"diff":11613},{"start":1494397791821584,"end":1494397791833218,"diff":11634}],"now":1494397791839,"mem":{"start":{"process":{"rss":53710848,"heapTotal":31719424,"heapUsed":24946328,"external":1890675},"os":290672640},"end":{"process":{"rss":69365760,"heapTotal":44847104,"heapUsed":27303760,"external":17476},"os":276770816}},"stats":{"moe":0.00009994687731155257,"rme":0.8778229347688533,"sem":0.000050993304750792125,"deviation":0.0004503606733427758,"mean":0.011385767374358976,"sample":[0.0115191426,0.011634762199999999,0.012156885400000001,0.011144387,0.011467886200000001,0.0109341474,0.0118188772,0.0122152918,0.0115347944,0.0116069688,0.0111162608,0.0114849956,0.0112095576,0.010947316799999999,0.011266454200000001,0.0113486062,0.011732779,0.013446894000000001,0.0111705256,0.0114111562,0.0119977792,0.0117380834,0.010826951599999999,0.0109184464,0.0110501222,0.0106776022,0.0113650564,0.011187525600000001,0.0111049158,0.011969487,0.0104455658,0.0110114186,0.0114683342,0.011183422799999999,0.011896095800000001,0.011165557199999999,0.011227772,0.0113674812,0.0109943542,0.0115674266,0.0112199108,0.0111143642,0.011277929,0.0109120742,0.0110104596,0.011292366600000001,0.010763170399999999,0.011451527,0.0117225702,0.011519056599999999,0.0116924186,0.0108632958,0.0109330194,0.0110220324,0.011972226800000001,0.0115634982,0.0107914862,0.0109301808,0.011554595400000001,0.0118315544,0.0119144716,0.0118521668,0.011951017599999999,0.011233389600000001,0.0115292956,0.0118902146,0.0111805672,0.011655431400000001,0.0114142316,0.0117424468,0.0113081084,0.011255714,0.010692838999999999,0.0112596108,0.011165741,0.011419255,0.0109345176,0.0119220128],"variance":2.028247360937584e-7},"count":5,"hz":87.82895057666681,"time":11.385767374358975,"cycles":2,"battery":{"amperage":-2801,"currentCapacity":3751,"percent":50,"charging":"","temp":3105}},{"msg":"zoomzoom x 87.83 ops/sec ±0.88% (78 runs sampled)","name":"zoomzoom","num":87.83,"sampled":"78","variation":"0.88","suite":["/Users/james/code/fluents/chain/packages/bench-chain/example/math/async-first-faster.json"],"timesFor":[{"start":1494397785984311,"end":1494397785995496,"diff":11185},{"start":1494397786003059,"end":1494397786013501,"diff":10442},{"start":1494397786013705,"end":1494397786024163,"diff":10458},{"start":1494397786024217,"end":1494397786036999,"diff":12782},{"start":1494397786037020,"end":1494397786048849,"diff":11829},{"start":1494397786048871,"end":1494397786060577,"diff":11706},{"start":1494397786090254,"end":1494397786100465,"diff":10211},{"start":1494397786100559,"end":1494397786111263,"diff":10704},{"start":1494397786111416,"end":1494397786123371,"diff":11955},{"start":1494397786123443,"end":1494397786136241,"diff":12798},{"start":1494397786136282,"end":1494397786148322,"diff":12040},{"start":1494397786170641,"end":1494397786184240,"diff":13599},{"start":1494397786184276,"end":1494397786196218,"diff":11942},{"start":1494397786196259,"end":1494397786208135,"diff":11876},{"start":1494397786208155,"end":1494397786219693,"diff":11538},{"start":1494397786219715,"end":1494397786231357,"diff":11642},{"start":1494397786250943,"end":1494397786262224,"diff":11281},{"start":1494397786262306,"end":1494397786273229,"diff":10923},{"start":1494397786273251,"end":1494397786283610,"diff":10359},{"start":1494397786283636,"end":1494397786295049,"diff":11413},{"start":1494397786295161,"end":1494397786306587,"diff":11426},{"start":1494397786324902,"end":1494397786335596,"diff":10694},{"start":1494397786335638,"end":1494397786348378,"diff":12740},{"start":1494397786348402,"end":1494397786360282,"diff":11880},{"start":1494397786360317,"end":1494397786370701,"diff":10384},{"start":1494397786370732,"end":1494397786382157,"diff":11425},{"start":1494397786401978,"end":1494397786414147,"diff":12169},{"start":1494397786414200,"end":1494397786424448,"diff":10248},{"start":1494397786424472,"end":1494397786433737,"diff":9265},{"start":1494397786433758,"end":1494397786444991,"diff":11233},{"start":1494397786445021,"end":1494397786456532,"diff":11511},{"start":1494397786477128,"end":1494397786489290,"diff":12162},{"start":1494397786489335,"end":1494397786499863,"diff":10528},{"start":1494397786499884,"end":1494397786512533,"diff":12649},{"start":1494397786512554,"end":1494397786523388,"diff":10834},{"start":1494397786523414,"end":1494397786536154,"diff":12740},{"start":1494397786558728,"end":1494397786571483,"diff":12755},{"start":1494397786571528,"end":1494397786583368,"diff":11840},{"start":1494397786583390,"end":1494397786595031,"diff":11641},{"start":1494397786595070,"end":1494397786606897,"diff":11827},{"start":1494397786606926,"end":1494397786619713,"diff":12787},{"start":1494397786637500,"end":1494397786648374,"diff":10874},{"start":1494397786648410,"end":1494397786657748,"diff":9338},{"start":1494397786657789,"end":1494397786670211,"diff":12422},{"start":1494397786670235,"end":1494397786682981,"diff":12746},{"start":1494397786683005,"end":1494397786695052,"diff":12047},{"start":1494397786713980,"end":1494397786725613,"diff":11633},{"start":1494397786725665,"end":1494397786738227,"diff":12562},{"start":1494397786738248,"end":1494397786749022,"diff":10774},{"start":1494397786749043,"end":1494397786760220,"diff":11177},{"start":1494397786760244,"end":1494397786771926,"diff":11682},{"start":1494397786789570,"end":1494397786801380,"diff":11810},{"start":1494397786801492,"end":1494397786812283,"diff":10791},{"start":1494397786812304,"end":1494397786822687,"diff":10383},{"start":1494397786822710,"end":1494397786834555,"diff":11845},{"start":1494397786834577,"end":1494397786845069,"diff":10492},{"start":1494397786862045,"end":1494397786873827,"diff":11782},{"start":1494397786873860,"end":1494397786886500,"diff":12640},{"start":1494397786886517,"end":1494397786896079,"diff":9562},{"start":1494397786896098,"end":1494397786906673,"diff":10575},{"start":1494397786906696,"end":1494397786919389,"diff":12693},{"start":1494397786937591,"end":1494397786948339,"diff":10748},{"start":1494397786948420,"end":1494397786960038,"diff":11618},{"start":1494397786960058,"end":1494397786971697,"diff":11639},{"start":1494397786971738,"end":1494397786982006,"diff":10268},{"start":1494397786982036,"end":1494397786993556,"diff":11520},{"start":1494397787011567,"end":1494397787022304,"diff":10737},{"start":1494397787022345,"end":1494397787035104,"diff":12759},{"start":1494397787035129,"end":1494397787045448,"diff":10319},{"start":1494397787045472,"end":1494397787055295,"diff":9823},{"start":1494397787055318,"end":1494397787066216,"diff":10898},{"start":1494397787084044,"end":1494397787094862,"diff":10818},{"start":1494397787094913,"end":1494397787106929,"diff":12016},{"start":1494397787106951,"end":1494397787119594,"diff":12643},{"start":1494397787119613,"end":1494397787129864,"diff":10251},{"start":1494397787129895,"end":1494397787140289,"diff":10394},{"start":1494397787156833,"end":1494397787167092,"diff":10259},{"start":1494397787167115,"end":1494397787177433,"diff":10318},{"start":1494397787177466,"end":1494397787189263,"diff":11797},{"start":1494397787189285,"end":1494397787202242,"diff":12957},{"start":1494397787202253,"end":1494397787213472,"diff":11219},{"start":1494397787231201,"end":1494397787242164,"diff":10963},{"start":1494397787242188,"end":1494397787253933,"diff":11745},{"start":1494397787253995,"end":1494397787265395,"diff":11400},{"start":1494397787265413,"end":1494397787277048,"diff":11635},{"start":1494397787277095,"end":1494397787289746,"diff":12651},{"start":1494397787308515,"end":1494397787327227,"diff":18712},{"start":1494397787327256,"end":1494397787339307,"diff":12051},{"start":1494397787339319,"end":1494397787352185,"diff":12866},{"start":1494397787352199,"end":1494397787364431,"diff":12232},{"start":1494397787364448,"end":1494397787375641,"diff":11193},{"start":1494397787395314,"end":1494397787405604,"diff":10290},{"start":1494397787405628,"end":1494397787416253,"diff":10625},{"start":1494397787416267,"end":1494397787427866,"diff":11599},{"start":1494397787427880,"end":1494397787439476,"diff":11596},{"start":1494397787439506,"end":1494397787451087,"diff":11581},{"start":1494397787469561,"end":1494397787480107,"diff":10546},{"start":1494397787480134,"end":1494397787491717,"diff":11583},{"start":1494397787491731,"end":1494397787503339,"diff":11608},{"start":1494397787503356,"end":1494397787514953,"diff":11597},{"start":1494397787514967,"end":1494397787526551,"diff":11584},{"start":1494397787550731,"end":1494397787562403,"diff":11672},{"start":1494397787562436,"end":1494397787572873,"diff":10437},{"start":1494397787572889,"end":1494397787587153,"diff":14264},{"start":1494397787587381,"end":1494397787598819,"diff":11438},{"start":1494397787598834,"end":1494397787610634,"diff":11800},{"start":1494397787630180,"end":1494397787640937,"diff":10757},{"start":1494397787640961,"end":1494397787653549,"diff":12588},{"start":1494397787653564,"end":1494397787666023,"diff":12459},{"start":1494397787666039,"end":1494397787677513,"diff":11474},{"start":1494397787677541,"end":1494397787688792,"diff":11251},{"start":1494397787706382,"end":1494397787718173,"diff":11791},{"start":1494397787718203,"end":1494397787729742,"diff":11539},{"start":1494397787729757,"end":1494397787739914,"diff":10157},{"start":1494397787739929,"end":1494397787750156,"diff":10227},{"start":1494397787750187,"end":1494397787760404,"diff":10217},{"start":1494397787784205,"end":1494397787795882,"diff":11677},{"start":1494397787795919,"end":1494397787805968,"diff":10049},{"start":1494397787805996,"end":1494397787817103,"diff":11107},{"start":1494397787817122,"end":1494397787828223,"diff":11101},{"start":1494397787828265,"end":1494397787838652,"diff":10387},{"start":1494397787862980,"end":1494397787873956,"diff":10976},{"start":1494397787873989,"end":1494397787884493,"diff":10504},{"start":1494397787884517,"end":1494397787894773,"diff":10256},{"start":1494397787894799,"end":1494397787908333,"diff":13534},{"start":1494397787908407,"end":1494397787918035,"diff":9628},{"start":1494397787937760,"end":1494397787948952,"diff":11192},{"start":1494397787948986,"end":1494397787959199,"diff":10213},{"start":1494397787959214,"end":1494397787969819,"diff":10605},{"start":1494397787969833,"end":1494397787980235,"diff":10402},{"start":1494397787980251,"end":1494397787991066,"diff":10815},{"start":1494397788009092,"end":1494397788020256,"diff":11164},{"start":1494397788020283,"end":1494397788031655,"diff":11372},{"start":1494397788031668,"end":1494397788042076,"diff":10408},{"start":1494397788042125,"end":1494397788053648,"diff":11523},{"start":1494397788053666,"end":1494397788065825,"diff":12159},{"start":1494397788083023,"end":1494397788095493,"diff":12470},{"start":1494397788095535,"end":1494397788107091,"diff":11556},{"start":1494397788107119,"end":1494397788117302,"diff":10183},{"start":1494397788117316,"end":1494397788127728,"diff":10412},{"start":1494397788127769,"end":1494397788138900,"diff":11131},{"start":1494397788155050,"end":1494397788165309,"diff":10259},{"start":1494397788165332,"end":1494397788176203,"diff":10871},{"start":1494397788176229,"end":1494397788188436,"diff":12207},{"start":1494397788188469,"end":1494397788200106,"diff":11637},{"start":1494397788200119,"end":1494397788210505,"diff":10386},{"start":1494397788228306,"end":1494397788240609,"diff":12303},{"start":1494397788240646,"end":1494397788252263,"diff":11617},{"start":1494397788252317,"end":1494397788263973,"diff":11656},{"start":1494397788263985,"end":1494397788275676,"diff":11691},{"start":1494397788275720,"end":1494397788288078,"diff":12358},{"start":1494397788303470,"end":1494397788312675,"diff":9205},{"start":1494397788312783,"end":1494397788323244,"diff":10461},{"start":1494397788323256,"end":1494397788334612,"diff":11356},{"start":1494397788334630,"end":1494397788345014,"diff":10384},{"start":1494397788345060,"end":1494397788355637,"diff":10577},{"start":1494397788372815,"end":1494397788383114,"diff":10299},{"start":1494397788383149,"end":1494397788395320,"diff":12171},{"start":1494397788395333,"end":1494397788405624,"diff":10291},{"start":1494397788405639,"end":1494397788416358,"diff":10719},{"start":1494397788416377,"end":1494397788427798,"diff":11421},{"start":1494397788443673,"end":1494397788454196,"diff":10523},{"start":1494397788454217,"end":1494397788465390,"diff":11173},{"start":1494397788465401,"end":1494397788477143,"diff":11742},{"start":1494397788477155,"end":1494397788489028,"diff":11873},{"start":1494397788489041,"end":1494397788500952,"diff":11911},{"start":1494397788517043,"end":1494397788529258,"diff":12215},{"start":1494397788529281,"end":1494397788540399,"diff":11118},{"start":1494397788540440,"end":1494397788551850,"diff":11410},{"start":1494397788551873,"end":1494397788563398,"diff":11525},{"start":1494397788563416,"end":1494397788572888,"diff":9472},{"start":1494397788591201,"end":1494397788603941,"diff":12740},{"start":1494397788604002,"end":1494397788615694,"diff":11692},{"start":1494397788615716,"end":1494397788626791,"diff":11075},{"start":1494397788626811,"end":1494397788638144,"diff":11333},{"start":1494397788638170,"end":1494397788650532,"diff":12362},{"start":1494397788666734,"end":1494397788677810,"diff":11076},{"start":1494397788677847,"end":1494397788689155,"diff":11308},{"start":1494397788689176,"end":1494397788699550,"diff":10374},{"start":1494397788699568,"end":1494397788710571,"diff":11003},{"start":1494397788710592,"end":1494397788722441,"diff":11849},{"start":1494397788737783,"end":1494397788748124,"diff":10341},{"start":1494397788748190,"end":1494397788760751,"diff":12561},{"start":1494397788760777,"end":1494397788770748,"diff":9971},{"start":1494397788770761,"end":1494397788781175,"diff":10414},{"start":1494397788781198,"end":1494397788793851,"diff":12653},{"start":1494397788814258,"end":1494397788824912,"diff":10654},{"start":1494397788825013,"end":1494397788836169,"diff":11156},{"start":1494397788836182,"end":1494397788849320,"diff":13138},{"start":1494397788849351,"end":1494397788859544,"diff":10193},{"start":1494397788859591,"end":1494397788871017,"diff":11426},{"start":1494397788887663,"end":1494397788899675,"diff":12012},{"start":1494397788899716,"end":1494397788911072,"diff":11356},{"start":1494397788911100,"end":1494397788922388,"diff":11288},{"start":1494397788922401,"end":1494397788932061,"diff":9660},{"start":1494397788932075,"end":1494397788942526,"diff":10451},{"start":1494397788958757,"end":1494397788971531,"diff":12774},{"start":1494397788971553,"end":1494397788982957,"diff":11404},{"start":1494397788982981,"end":1494397788994866,"diff":11885},{"start":1494397788994887,"end":1494397789005806,"diff":10919},{"start":1494397789005827,"end":1494397789016496,"diff":10669},{"start":1494397789033285,"end":1494397789044814,"diff":11529},{"start":1494397789044853,"end":1494397789056350,"diff":11497},{"start":1494397789056372,"end":1494397789065922,"diff":9550},{"start":1494397789065949,"end":1494397789077485,"diff":11536},{"start":1494397789077519,"end":1494397789089302,"diff":11783},{"start":1494397789104525,"end":1494397789114879,"diff":10354},{"start":1494397789114922,"end":1494397789125156,"diff":10234},{"start":1494397789125225,"end":1494397789136997,"diff":11772},{"start":1494397789137019,"end":1494397789149239,"diff":12220},{"start":1494397789149272,"end":1494397789160030,"diff":10758},{"start":1494397789180193,"end":1494397789190882,"diff":10689},{"start":1494397789190982,"end":1494397789201623,"diff":10641},{"start":1494397789201679,"end":1494397789213251,"diff":11572},{"start":1494397789213344,"end":1494397789223915,"diff":10571},{"start":1494397789223948,"end":1494397789236450,"diff":12502},{"start":1494397789252962,"end":1494397789262462,"diff":9500},{"start":1494397789262505,"end":1494397789273927,"diff":11422},{"start":1494397789273943,"end":1494397789284982,"diff":11039},{"start":1494397789284997,"end":1494397789295480,"diff":10483},{"start":1494397789295567,"end":1494397789307453,"diff":11886},{"start":1494397789324252,"end":1494397789336960,"diff":12708},{"start":1494397789337100,"end":1494397789346625,"diff":9525},{"start":1494397789346652,"end":1494397789358289,"diff":11637},{"start":1494397789358310,"end":1494397789368578,"diff":10268},{"start":1494397789368595,"end":1494397789379212,"diff":10617},{"start":1494397789400630,"end":1494397789411280,"diff":10650},{"start":1494397789411323,"end":1494397789423600,"diff":12277},{"start":1494397789423623,"end":1494397789434430,"diff":10807},{"start":1494397789434450,"end":1494397789444777,"diff":10327},{"start":1494397789444796,"end":1494397789457018,"diff":12222},{"start":1494397789474475,"end":1494397789484810,"diff":10335},{"start":1494397789484845,"end":1494397789494984,"diff":10139},{"start":1494397789495005,"end":1494397789505472,"diff":10467},{"start":1494397789505490,"end":1494397789516223,"diff":10733},{"start":1494397789516272,"end":1494397789528222,"diff":11950},{"start":1494397789544327,"end":1494397789556491,"diff":12164},{"start":1494397789556524,"end":1494397789569204,"diff":12680},{"start":1494397789569224,"end":1494397789580126,"diff":10902},{"start":1494397789580165,"end":1494397789591127,"diff":10962},{"start":1494397789591154,"end":1494397789601511,"diff":10357},{"start":1494397789618895,"end":1494397789630293,"diff":11398},{"start":1494397789630316,"end":1494397789642920,"diff":12604},{"start":1494397789642942,"end":1494397789655138,"diff":12196},{"start":1494397789655152,"end":1494397789665351,"diff":10199},{"start":1494397789665365,"end":1494397789677385,"diff":12020},{"start":1494397789696649,"end":1494397789708621,"diff":11972},{"start":1494397789708764,"end":1494397789721079,"diff":12315},{"start":1494397789721098,"end":1494397789731340,"diff":10242},{"start":1494397789731361,"end":1494397789743125,"diff":11764},{"start":1494397789743162,"end":1494397789753976,"diff":10814},{"start":1494397789770632,"end":1494397789782820,"diff":12188},{"start":1494397789782864,"end":1494397789794825,"diff":11961},{"start":1494397789794848,"end":1494397789806467,"diff":11619},{"start":1494397789806491,"end":1494397789819242,"diff":12751},{"start":1494397789819303,"end":1494397789829020,"diff":9717},{"start":1494397789846450,"end":1494397789857946,"diff":11496},{"start":1494397789858028,"end":1494397789868325,"diff":10297},{"start":1494397789868350,"end":1494397789877488,"diff":9138},{"start":1494397789877502,"end":1494397789889135,"diff":11633},{"start":1494397789889155,"end":1494397789900694,"diff":11539},{"start":1494397789917907,"end":1494397789928182,"diff":10275},{"start":1494397789928290,"end":1494397789939207,"diff":10917},{"start":1494397789939218,"end":1494397789949352,"diff":10134},{"start":1494397789949368,"end":1494397789959564,"diff":10196},{"start":1494397789959707,"end":1494397789972497,"diff":12790},{"start":1494397789987390,"end":1494397789996673,"diff":9283},{"start":1494397789996700,"end":1494397790007030,"diff":10330},{"start":1494397790007052,"end":1494397790019246,"diff":12194},{"start":1494397790019290,"end":1494397790030984,"diff":11694},{"start":1494397790031166,"end":1494397790042433,"diff":11267},{"start":1494397790060790,"end":1494397790071113,"diff":10323},{"start":1494397790071176,"end":1494397790083162,"diff":11986},{"start":1494397790083186,"end":1494397790095479,"diff":12293},{"start":1494397790095501,"end":1494397790107746,"diff":12245},{"start":1494397790107792,"end":1494397790120549,"diff":12757},{"start":1494397790137167,"end":1494397790148399,"diff":11232},{"start":1494397790148439,"end":1494397790159948,"diff":11509},{"start":1494397790159971,"end":1494397790171664,"diff":11693},{"start":1494397790171690,"end":1494397790183315,"diff":11625},{"start":1494397790183356,"end":1494397790194844,"diff":11488},{"start":1494397790212140,"end":1494397790222639,"diff":10499},{"start":1494397790222679,"end":1494397790232720,"diff":10041},{"start":1494397790232740,"end":1494397790244724,"diff":11984},{"start":1494397790244745,"end":1494397790255888,"diff":11143},{"start":1494397790255906,"end":1494397790266025,"diff":10119},{"start":1494397790281320,"end":1494397790291889,"diff":10569},{"start":1494397790292056,"end":1494397790303066,"diff":11010},{"start":1494397790303087,"end":1494397790312914,"diff":9827},{"start":1494397790312923,"end":1494397790324688,"diff":11765},{"start":1494397790324731,"end":1494397790335907,"diff":11176},{"start":1494397790352837,"end":1494397790363191,"diff":10354},{"start":1494397790363255,"end":1494397790373946,"diff":10691},{"start":1494397790373959,"end":1494397790386601,"diff":12642},{"start":1494397790386616,"end":1494397790397763,"diff":11147},{"start":1494397790397785,"end":1494397790410515,"diff":12730},{"start":1494397790428731,"end":1494397790440115,"diff":11384},{"start":1494397790440167,"end":1494397790452897,"diff":12730},{"start":1494397790452921,"end":1494397790464397,"diff":11476},{"start":1494397790464421,"end":1494397790474619,"diff":10198},{"start":1494397790474644,"end":1494397790487816,"diff":13172},{"start":1494397790506386,"end":1494397790519096,"diff":12710},{"start":1494397790519169,"end":1494397790530968,"diff":11799},{"start":1494397790531015,"end":1494397790542823,"diff":11808},{"start":1494397790542845,"end":1494397790555147,"diff":12302},{"start":1494397790555170,"end":1494397790565878,"diff":10708},{"start":1494397790582103,"end":1494397790594779,"diff":12676},{"start":1494397790594823,"end":1494397790606075,"diff":11252},{"start":1494397790606098,"end":1494397790618861,"diff":12763},{"start":1494397790618901,"end":1494397790631050,"diff":12149},{"start":1494397790631085,"end":1494397790641287,"diff":10202},{"start":1494397790659661,"end":1494397790671853,"diff":12192},{"start":1494397790671895,"end":1494397790683440,"diff":11545},{"start":1494397790683463,"end":1494397790694783,"diff":11320},{"start":1494397790694810,"end":1494397790707305,"diff":12495},{"start":1494397790707364,"end":1494397790719217,"diff":11853},{"start":1494397790734232,"end":1494397790744724,"diff":10492},{"start":1494397790744765,"end":1494397790755974,"diff":11209},{"start":1494397790755988,"end":1494397790767447,"diff":11459},{"start":1494397790767476,"end":1494397790777942,"diff":10466},{"start":1494397790777974,"end":1494397790790324,"diff":12350},{"start":1494397790806172,"end":1494397790816488,"diff":10316},{"start":1494397790816512,"end":1494397790829106,"diff":12594},{"start":1494397790829119,"end":1494397790839400,"diff":10281},{"start":1494397790839412,"end":1494397790852074,"diff":12662},{"start":1494397790852092,"end":1494397790863756,"diff":11664},{"start":1494397790887193,"end":1494397790899974,"diff":12781},{"start":1494397790900003,"end":1494397790911974,"diff":11971},{"start":1494397790912054,"end":1494397790924917,"diff":12863},{"start":1494397790924981,"end":1494397790935267,"diff":10286},{"start":1494397790935286,"end":1494397790946579,"diff":11293},{"start":1494397790964033,"end":1494397790973600,"diff":9567},{"start":1494397790973632,"end":1494397790983753,"diff":10121},{"start":1494397790983769,"end":1494397790994872,"diff":11103},{"start":1494397790994985,"end":1494397791006979,"diff":11994},{"start":1494397791007003,"end":1494397791019814,"diff":12811},{"start":1494397791036821,"end":1494397791048847,"diff":12026},{"start":1494397791048881,"end":1494397791061231,"diff":12350},{"start":1494397791061272,"end":1494397791072188,"diff":10916},{"start":1494397791072210,"end":1494397791083760,"diff":11550},{"start":1494397791083780,"end":1494397791094962,"diff":11182},{"start":1494397791112544,"end":1494397791125244,"diff":12700},{"start":1494397791125378,"end":1494397791135540,"diff":10162},{"start":1494397791135568,"end":1494397791147091,"diff":11523},{"start":1494397791147111,"end":1494397791158457,"diff":11346},{"start":1494397791158561,"end":1494397791169546,"diff":10985},{"start":1494397791186108,"end":1494397791197958,"diff":11850},{"start":1494397791198017,"end":1494397791208900,"diff":10883},{"start":1494397791208964,"end":1494397791220934,"diff":11970},{"start":1494397791220968,"end":1494397791232943,"diff":11975},{"start":1494397791232964,"end":1494397791244723,"diff":11759},{"start":1494397791263099,"end":1494397791273420,"diff":10321},{"start":1494397791273464,"end":1494397791286156,"diff":12692},{"start":1494397791286177,"end":1494397791296041,"diff":9864},{"start":1494397791296059,"end":1494397791306705,"diff":10646},{"start":1494397791306727,"end":1494397791319441,"diff":12714},{"start":1494397791336151,"end":1494397791347655,"diff":11504},{"start":1494397791347679,"end":1494397791358444,"diff":10765},{"start":1494397791358505,"end":1494397791369168,"diff":10663},{"start":1494397791369181,"end":1494397791380071,"diff":10890},{"start":1494397791380098,"end":1494397791392357,"diff":12259},{"start":1494397791412000,"end":1494397791422697,"diff":10697},{"start":1494397791422727,"end":1494397791432977,"diff":10250},{"start":1494397791433011,"end":1494397791444750,"diff":11739},{"start":1494397791444779,"end":1494397791455074,"diff":10295},{"start":1494397791455089,"end":1494397791465364,"diff":10275},{"start":1494397791481667,"end":1494397791492589,"diff":10922},{"start":1494397791492625,"end":1494397791505163,"diff":12538},{"start":1494397791505186,"end":1494397791515366,"diff":10180},{"start":1494397791515391,"end":1494397791527077,"diff":11686},{"start":1494397791527098,"end":1494397791537898,"diff":10800},{"start":1494397791555064,"end":1494397791565354,"diff":10290},{"start":1494397791565378,"end":1494397791575658,"diff":10280},{"start":1494397791575723,"end":1494397791588017,"diff":12294},{"start":1494397791588037,"end":1494397791599508,"diff":11471},{"start":1494397791599531,"end":1494397791610727,"diff":11196},{"start":1494397791629805,"end":1494397791642092,"diff":12287},{"start":1494397791642220,"end":1494397791651882,"diff":9662},{"start":1494397791651906,"end":1494397791663390,"diff":11484},{"start":1494397791663417,"end":1494397791675039,"diff":11622},{"start":1494397791675059,"end":1494397791686823,"diff":11764},{"start":1494397791701624,"end":1494397791711713,"diff":10089},{"start":1494397791711737,"end":1494397791722706,"diff":10969},{"start":1494397791722720,"end":1494397791733101,"diff":10381},{"start":1494397791733114,"end":1494397791744675,"diff":11561},{"start":1494397791744700,"end":1494397791756221,"diff":11521},{"start":1494397791773698,"end":1494397791786375,"diff":12677},{"start":1494397791786452,"end":1494397791798401,"diff":11949},{"start":1494397791798423,"end":1494397791809890,"diff":11467},{"start":1494397791809940,"end":1494397791821553,"diff":11613},{"start":1494397791821584,"end":1494397791833218,"diff":11634}],"now":1494397791840,"mem":{"start":{"process":{"rss":53710848,"heapTotal":31719424,"heapUsed":24946328,"external":1890675},"os":290672640},"end":{"process":{"rss":69378048,"heapTotal":44847104,"heapUsed":27331856,"external":17476},"os":276787200}},"stats":{"moe":0.00009994687731155257,"rme":0.8778229347688533,"sem":0.000050993304750792125,"deviation":0.0004503606733427758,"mean":0.011385767374358976,"sample":[0.0115191426,0.011634762199999999,0.012156885400000001,0.011144387,0.011467886200000001,0.0109341474,0.0118188772,0.0122152918,0.0115347944,0.0116069688,0.0111162608,0.0114849956,0.0112095576,0.010947316799999999,0.011266454200000001,0.0113486062,0.011732779,0.013446894000000001,0.0111705256,0.0114111562,0.0119977792,0.0117380834,0.010826951599999999,0.0109184464,0.0110501222,0.0106776022,0.0113650564,0.011187525600000001,0.0111049158,0.011969487,0.0104455658,0.0110114186,0.0114683342,0.011183422799999999,0.011896095800000001,0.011165557199999999,0.011227772,0.0113674812,0.0109943542,0.0115674266,0.0112199108,0.0111143642,0.011277929,0.0109120742,0.0110104596,0.011292366600000001,0.010763170399999999,0.011451527,0.0117225702,0.011519056599999999,0.0116924186,0.0108632958,0.0109330194,0.0110220324,0.011972226800000001,0.0115634982,0.0107914862,0.0109301808,0.011554595400000001,0.0118315544,0.0119144716,0.0118521668,0.011951017599999999,0.011233389600000001,0.0115292956,0.0118902146,0.0111805672,0.011655431400000001,0.0114142316,0.0117424468,0.0113081084,0.011255714,0.010692838999999999,0.0112596108,0.011165741,0.011419255,0.0109345176,0.0119220128],"variance":2.028247360937584e-7},"count":5,"hz":87.82895057666681,"time":11.385767374358975,"cycles":2,"battery":{"amperage":-2801,"currentCapacity":3751,"percent":50,"charging":"","temp":3105}}],"snail":[{"msg":"snail x 4.94 ops/sec ±0.31% (28 runs sampled)","name":"snail","num":4.94,"sampled":"28","variation":"0.31","suite":["/Users/james/code/fluents/chain/packages/bench-chain/example/math/async-first-faster.json"],"timesFor":[{"start":1494397670348776,"end":1494397670549598,"diff":200822},{"start":1494397670570692,"end":1494397670773394,"diff":202702},{"start":1494397670790382,"end":1494397670991330,"diff":200948},{"start":1494397671011351,"end":1494397671213967,"diff":202616},{"start":1494397671234720,"end":1494397671435307,"diff":200587},{"start":1494397671464177,"end":1494397671668707,"diff":204530},{"start":1494397671686370,"end":1494397671887960,"diff":201590},{"start":1494397671903884,"end":1494397672108049,"diff":204165},{"start":1494397672123770,"end":1494397672323964,"diff":200194},{"start":1494397672340176,"end":1494397672540847,"diff":200671},{"start":1494397672559517,"end":1494397672764143,"diff":204626},{"start":1494397672781617,"end":1494397672981390,"diff":199773},{"start":1494397672998494,"end":1494397673203907,"diff":205413},{"start":1494397673225641,"end":1494397673430348,"diff":204707},{"start":1494397673447402,"end":1494397673649539,"diff":202137},{"start":1494397673666251,"end":1494397673870717,"diff":204466},{"start":1494397673885960,"end":1494397674088517,"diff":202557},{"start":1494397674105890,"end":1494397674307304,"diff":201414},{"start":1494397674324680,"end":1494397674526456,"diff":201776},{"start":1494397674543950,"end":1494397674747364,"diff":203414},{"start":1494397674764820,"end":1494397674966569,"diff":201749},{"start":1494397674982330,"end":1494397675185012,"diff":202682},{"start":1494397675204604,"end":1494397675405296,"diff":200692},{"start":1494397675421845,"end":1494397675623438,"diff":201593},{"start":1494397675640878,"end":1494397675846013,"diff":205135},{"start":1494397675863988,"end":1494397676067437,"diff":203449},{"start":1494397676082598,"end":1494397676285911,"diff":203313},{"start":1494397676303409,"end":1494397676505703,"diff":202294}],"now":1494397676512,"mem":{"start":{"process":{"rss":53198848,"heapTotal":31195136,"heapUsed":24678824,"external":1889462},"os":233902080},"end":{"process":{"rss":73232384,"heapTotal":48517120,"heapUsed":35419024,"external":71568},"os":246063104}},"stats":{"moe":0.000624051038384802,"rme":0.30802726261806856,"sem":0.0003041184397586754,"deviation":0.0016092435214208666,"mean":0.20259604071428572,"sample":[0.200965339,0.202864004,0.201117272,0.202685093,0.200688131,0.204622502,0.201685023,0.204232864,0.200326573,0.200759253,0.204721849,0.199838402,0.205516018,0.204784609,0.202215852,0.204557694,0.202630694,0.201507098,0.201856626,0.203496069,0.201821625,0.202809231,0.200772915,0.201699037,0.205224653,0.203541255,0.20337827,0.202371189],"variance":0.0000025896647112350313},"count":1,"hz":4.935930615792565,"time":202.59604071428572,"cycles":1,"battery":{"amperage":-2489,"currentCapacity":3822,"percent":51,"charging":"","temp":3105}},{"msg":"snail x 4.94 ops/sec ±0.31% (28 runs sampled)","name":"snail","num":4.94,"sampled":"28","variation":"0.31","suite":["/Users/james/code/fluents/chain/packages/bench-chain/example/math/async-first-faster.json"],"timesFor":[{"start":1494397670348776,"end":1494397670549598,"diff":200822},{"start":1494397670570692,"end":1494397670773394,"diff":202702},{"start":1494397670790382,"end":1494397670991330,"diff":200948},{"start":1494397671011351,"end":1494397671213967,"diff":202616},{"start":1494397671234720,"end":1494397671435307,"diff":200587},{"start":1494397671464177,"end":1494397671668707,"diff":204530},{"start":1494397671686370,"end":1494397671887960,"diff":201590},{"start":1494397671903884,"end":1494397672108049,"diff":204165},{"start":1494397672123770,"end":1494397672323964,"diff":200194},{"start":1494397672340176,"end":1494397672540847,"diff":200671},{"start":1494397672559517,"end":1494397672764143,"diff":204626},{"start":1494397672781617,"end":1494397672981390,"diff":199773},{"start":1494397672998494,"end":1494397673203907,"diff":205413},{"start":1494397673225641,"end":1494397673430348,"diff":204707},{"start":1494397673447402,"end":1494397673649539,"diff":202137},{"start":1494397673666251,"end":1494397673870717,"diff":204466},{"start":1494397673885960,"end":1494397674088517,"diff":202557},{"start":1494397674105890,"end":1494397674307304,"diff":201414},{"start":1494397674324680,"end":1494397674526456,"diff":201776},{"start":1494397674543950,"end":1494397674747364,"diff":203414},{"start":1494397674764820,"end":1494397674966569,"diff":201749},{"start":1494397674982330,"end":1494397675185012,"diff":202682},{"start":1494397675204604,"end":1494397675405296,"diff":200692},{"start":1494397675421845,"end":1494397675623438,"diff":201593},{"start":1494397675640878,"end":1494397675846013,"diff":205135},{"start":1494397675863988,"end":1494397676067437,"diff":203449},{"start":1494397676082598,"end":1494397676285911,"diff":203313},{"start":1494397676303409,"end":1494397676505703,"diff":202294}],"now":1494397676512,"mem":{"start":{"process":{"rss":53198848,"heapTotal":31195136,"heapUsed":24678824,"external":1889462},"os":233902080},"end":{"process":{"rss":73232384,"heapTotal":48517120,"heapUsed":35423360,"external":71568},"os":246063104}},"stats":{"moe":0.000624051038384802,"rme":0.30802726261806856,"sem":0.0003041184397586754,"deviation":0.0016092435214208666,"mean":0.20259604071428572,"sample":[0.200965339,0.202864004,0.201117272,0.202685093,0.200688131,0.204622502,0.201685023,0.204232864,0.200326573,0.200759253,0.204721849,0.199838402,0.205516018,0.204784609,0.202215852,0.204557694,0.202630694,0.201507098,0.201856626,0.203496069,0.201821625,0.202809231,0.200772915,0.201699037,0.205224653,0.203541255,0.20337827,0.202371189],"variance":0.0000025896647112350313},"count":1,"hz":4.935930615792565,"time":202.59604071428572,"cycles":1,"battery":{"amperage":-2489,"currentCapacity":3822,"percent":51,"charging":"","temp":3105}},{"msg":"snail x 4.93 ops/sec ±0.33% (28 runs sampled)","name":"snail","num":4.93,"sampled":"28","variation":"0.33","suite":["/Users/james/code/fluents/chain/packages/bench-chain/example/math/async-first-faster.json"],"timesFor":[{"start":1494397791859346,"end":1494397792064709,"diff":205363},{"start":1494397792085677,"end":1494397792287949,"diff":202272},{"start":1494397792304040,"end":1494397792508905,"diff":204865},{"start":1494397792525379,"end":1494397792726798,"diff":201419},{"start":1494397792745302,"end":1494397792944945,"diff":199643},{"start":1494397792962738,"end":1494397793164045,"diff":201307},{"start":1494397793181061,"end":1494397793385848,"diff":204787},{"start":1494397793405261,"end":1494397793608012,"diff":202751},{"start":1494397793626820,"end":1494397793827604,"diff":200784},{"start":1494397793845465,"end":1494397794047534,"diff":202069},{"start":1494397794064580,"end":1494397794264892,"diff":200312},{"start":1494397794281510,"end":1494397794483968,"diff":202458},{"start":1494397794501878,"end":1494397794705032,"diff":203154},{"start":1494397794722432,"end":1494397794923330,"diff":200898},{"start":1494397794940837,"end":1494397795144586,"diff":203749},{"start":1494397795167025,"end":1494397795371370,"diff":204345},{"start":1494397795387816,"end":1494397795592457,"diff":204641},{"start":1494397795610755,"end":1494397795811860,"diff":201105},{"start":1494397795827397,"end":1494397796027775,"diff":200378},{"start":1494397796045709,"end":1494397796248777,"diff":203068},{"start":1494397796267709,"end":1494397796468404,"diff":200695},{"start":1494397796484963,"end":1494397796688786,"diff":203823},{"start":1494397796709057,"end":1494397796909440,"diff":200383},{"start":1494397796927658,"end":1494397797130659,"diff":203001},{"start":1494397797146512,"end":1494397797349833,"diff":203321},{"start":1494397797367073,"end":1494397797571386,"diff":204313},{"start":1494397797589605,"end":1494397797794426,"diff":204821},{"start":1494397797810764,"end":1494397798015438,"diff":204674}],"now":1494397798021,"mem":{"start":{"process":{"rss":53710848,"heapTotal":31719424,"heapUsed":24946328,"external":1890675},"os":290672640},"end":{"process":{"rss":73895936,"heapTotal":49041408,"heapUsed":32619448,"external":25668},"os":283922432}},"stats":{"moe":0.0006716281612569823,"rme":0.3312277795982944,"sem":0.0003273041721525255,"deviation":0.0017319308851789098,"mean":0.2027692731785715,"sample":[0.205486337,0.202358386,0.204988853,0.201556298,0.199721452,0.201474778,0.204881648,0.202834218,0.200897409,0.202165936,0.20037992,0.202592744,0.203224876,0.20098562,0.203838054,0.204480031,0.204961127,0.201226714,0.20050568,0.203165026,0.200762147,0.203891299,0.200547334,0.203081047,0.203433096,0.204412059,0.204914123,0.204773437],"variance":0.000002999584591036602},"count":1,"hz":4.931713687799909,"time":202.7692731785715,"cycles":1,"battery":{"amperage":-2801,"currentCapacity":3751,"percent":50,"charging":"","temp":3105}},{"msg":"snail x 4.93 ops/sec ±0.33% (28 runs sampled)","name":"snail","num":4.93,"sampled":"28","variation":"0.33","suite":["/Users/james/code/fluents/chain/packages/bench-chain/example/math/async-first-faster.json"],"timesFor":[{"start":1494397791859346,"end":1494397792064709,"diff":205363},{"start":1494397792085677,"end":1494397792287949,"diff":202272},{"start":1494397792304040,"end":1494397792508905,"diff":204865},{"start":1494397792525379,"end":1494397792726798,"diff":201419},{"start":1494397792745302,"end":1494397792944945,"diff":199643},{"start":1494397792962738,"end":1494397793164045,"diff":201307},{"start":1494397793181061,"end":1494397793385848,"diff":204787},{"start":1494397793405261,"end":1494397793608012,"diff":202751},{"start":1494397793626820,"end":1494397793827604,"diff":200784},{"start":1494397793845465,"end":1494397794047534,"diff":202069},{"start":1494397794064580,"end":1494397794264892,"diff":200312},{"start":1494397794281510,"end":1494397794483968,"diff":202458},{"start":1494397794501878,"end":1494397794705032,"diff":203154},{"start":1494397794722432,"end":1494397794923330,"diff":200898},{"start":1494397794940837,"end":1494397795144586,"diff":203749},{"start":1494397795167025,"end":1494397795371370,"diff":204345},{"start":1494397795387816,"end":1494397795592457,"diff":204641},{"start":1494397795610755,"end":1494397795811860,"diff":201105},{"start":1494397795827397,"end":1494397796027775,"diff":200378},{"start":1494397796045709,"end":1494397796248777,"diff":203068},{"start":1494397796267709,"end":1494397796468404,"diff":200695},{"start":1494397796484963,"end":1494397796688786,"diff":203823},{"start":1494397796709057,"end":1494397796909440,"diff":200383},{"start":1494397796927658,"end":1494397797130659,"diff":203001},{"start":1494397797146512,"end":1494397797349833,"diff":203321},{"start":1494397797367073,"end":1494397797571386,"diff":204313},{"start":1494397797589605,"end":1494397797794426,"diff":204821},{"start":1494397797810764,"end":1494397798015438,"diff":204674}],"now":1494397798021,"mem":{"start":{"process":{"rss":53710848,"heapTotal":31719424,"heapUsed":24946328,"external":1890675},"os":290672640},"end":{"process":{"rss":73895936,"heapTotal":49041408,"heapUsed":32623752,"external":25668},"os":283922432}},"stats":{"moe":0.0006716281612569823,"rme":0.3312277795982944,"sem":0.0003273041721525255,"deviation":0.0017319308851789098,"mean":0.2027692731785715,"sample":[0.205486337,0.202358386,0.204988853,0.201556298,0.199721452,0.201474778,0.204881648,0.202834218,0.200897409,0.202165936,0.20037992,0.202592744,0.203224876,0.20098562,0.203838054,0.204480031,0.204961127,0.201226714,0.20050568,0.203165026,0.200762147,0.203891299,0.200547334,0.203081047,0.203433096,0.204412059,0.204914123,0.204773437],"variance":0.000002999584591036602},"count":1,"hz":4.931713687799909,"time":202.7692731785715,"cycles":1,"battery":{"amperage":-2801,"currentCapacity":3751,"percent":50,"charging":"","temp":3105}}]}}
\ No newline at end of file
diff --git a/_modules/bench-chain/example/math/async-first-faster2.json b/_modules/bench-chain/example/math/async-first-faster2.json
new file mode 100644
index 0000000..4cb4ba1
--- /dev/null
+++ b/_modules/bench-chain/example/math/async-first-faster2.json
@@ -0,0 +1 @@
+{"/Users/james/code/fluents/chain/packages/bench-chain/example/math/async-first-faster2.json":{"snail2":[{"msg":"snail2 x 4.93 ops/sec ±0.31% (28 runs sampled)","name":"snail2","num":4.93,"sampled":"28","variation":"0.31","suite":["/Users/james/code/fluents/chain/packages/bench-chain/example/math/async-first-faster2.json"],"timesFor":[{"start":1494397896913641,"end":1494397897116498,"diff":202857},{"start":1494397897145256,"end":1494397897348421,"diff":203165},{"start":1494397897365328,"end":1494397897567696,"diff":202368},{"start":1494397897589000,"end":1494397897791782,"diff":202782},{"start":1494397897810003,"end":1494397898012384,"diff":202381},{"start":1494397898033203,"end":1494397898238728,"diff":205525},{"start":1494397898258595,"end":1494397898463367,"diff":204772},{"start":1494397898483748,"end":1494397898685773,"diff":202025},{"start":1494397898700946,"end":1494397898904318,"diff":203372},{"start":1494397898923596,"end":1494397899124047,"diff":200451},{"start":1494397899142012,"end":1494397899341864,"diff":199852},{"start":1494397899358385,"end":1494397899558798,"diff":200413},{"start":1494397899576401,"end":1494397899778630,"diff":202229},{"start":1494397899799072,"end":1494397900003539,"diff":204467},{"start":1494397900020023,"end":1494397900223973,"diff":203950},{"start":1494397900243215,"end":1494397900444999,"diff":201784},{"start":1494397900464266,"end":1494397900665430,"diff":201164},{"start":1494397900683340,"end":1494397900888852,"diff":205512},{"start":1494397900907058,"end":1494397901107862,"diff":200804},{"start":1494397901125461,"end":1494397901326301,"diff":200840},{"start":1494397901348206,"end":1494397901553158,"diff":204952},{"start":1494397901569486,"end":1494397901773499,"diff":204013},{"start":1494397901791283,"end":1494397901993386,"diff":202103},{"start":1494397902011098,"end":1494397902213266,"diff":202168},{"start":1494397902230976,"end":1494397902435569,"diff":204593},{"start":1494397902453102,"end":1494397902655281,"diff":202179},{"start":1494397902672261,"end":1494397902876906,"diff":204645},{"start":1494397902892805,"end":1494397903095504,"diff":202699}],"now":1494397903103,"mem":{"start":{"process":{"rss":53481472,"heapTotal":30670848,"heapUsed":24698264,"external":1891128},"os":353452032},"end":{"process":{"rss":54755328,"heapTotal":30167040,"heapUsed":20044088,"external":17476},"os":279932928}},"stats":{"moe":0.0006251613088772928,"rme":0.30811168216191426,"sem":0.0003046595072501427,"deviation":0.0016121065814707143,"mean":0.20290087817857141,"sample":[0.203139569,0.203407338,0.202513143,0.202976712,0.20246721,0.205612705,0.204893549,0.202086278,0.203539818,0.200525328,0.199934643,0.200518552,0.202346477,0.204555037,0.204029312,0.20186821,0.201236552,0.20558115,0.200879534,0.200979789,0.205048844,0.204079484,0.202239051,0.202246397,0.204670737,0.202292901,0.204771729,0.20278454],"variance":0.000002598887630021193},"count":1,"hz":4.928514893463931,"time":202.90087817857142,"cycles":1,"battery":{"amperage":-2155,"currentCapacity":3701,"percent":49,"charging":"","temp":3105}},{"msg":"snail2 x 4.93 ops/sec ±0.31% (28 runs sampled)","name":"snail2","num":4.93,"sampled":"28","variation":"0.31","suite":["/Users/james/code/fluents/chain/packages/bench-chain/example/math/async-first-faster2.json"],"timesFor":[{"start":1494397896913641,"end":1494397897116498,"diff":202857},{"start":1494397897145256,"end":1494397897348421,"diff":203165},{"start":1494397897365328,"end":1494397897567696,"diff":202368},{"start":1494397897589000,"end":1494397897791782,"diff":202782},{"start":1494397897810003,"end":1494397898012384,"diff":202381},{"start":1494397898033203,"end":1494397898238728,"diff":205525},{"start":1494397898258595,"end":1494397898463367,"diff":204772},{"start":1494397898483748,"end":1494397898685773,"diff":202025},{"start":1494397898700946,"end":1494397898904318,"diff":203372},{"start":1494397898923596,"end":1494397899124047,"diff":200451},{"start":1494397899142012,"end":1494397899341864,"diff":199852},{"start":1494397899358385,"end":1494397899558798,"diff":200413},{"start":1494397899576401,"end":1494397899778630,"diff":202229},{"start":1494397899799072,"end":1494397900003539,"diff":204467},{"start":1494397900020023,"end":1494397900223973,"diff":203950},{"start":1494397900243215,"end":1494397900444999,"diff":201784},{"start":1494397900464266,"end":1494397900665430,"diff":201164},{"start":1494397900683340,"end":1494397900888852,"diff":205512},{"start":1494397900907058,"end":1494397901107862,"diff":200804},{"start":1494397901125461,"end":1494397901326301,"diff":200840},{"start":1494397901348206,"end":1494397901553158,"diff":204952},{"start":1494397901569486,"end":1494397901773499,"diff":204013},{"start":1494397901791283,"end":1494397901993386,"diff":202103},{"start":1494397902011098,"end":1494397902213266,"diff":202168},{"start":1494397902230976,"end":1494397902435569,"diff":204593},{"start":1494397902453102,"end":1494397902655281,"diff":202179},{"start":1494397902672261,"end":1494397902876906,"diff":204645},{"start":1494397902892805,"end":1494397903095504,"diff":202699}],"now":1494397903106,"mem":{"start":{"process":{"rss":53481472,"heapTotal":30670848,"heapUsed":24698264,"external":1891128},"os":353452032},"end":{"process":{"rss":54767616,"heapTotal":30167040,"heapUsed":20072128,"external":17476},"os":279937024}},"stats":{"moe":0.0006251613088772928,"rme":0.30811168216191426,"sem":0.0003046595072501427,"deviation":0.0016121065814707143,"mean":0.20290087817857141,"sample":[0.203139569,0.203407338,0.202513143,0.202976712,0.20246721,0.205612705,0.204893549,0.202086278,0.203539818,0.200525328,0.199934643,0.200518552,0.202346477,0.204555037,0.204029312,0.20186821,0.201236552,0.20558115,0.200879534,0.200979789,0.205048844,0.204079484,0.202239051,0.202246397,0.204670737,0.202292901,0.204771729,0.20278454],"variance":0.000002598887630021193},"count":1,"hz":4.928514893463931,"time":202.90087817857142,"cycles":1,"battery":{"amperage":-2155,"currentCapacity":3701,"percent":49,"charging":"","temp":3105}}],"zoomzoom2":[{"msg":"zoomzoom2 x 86.17 ops/sec ±2.07% (77 runs sampled)","name":"zoomzoom2","num":86.17,"sampled":"77","variation":"2.07","suite":["/Users/james/code/fluents/chain/packages/bench-chain/example/math/async-first-faster2.json"],"timesFor":[{"start":1494397903127220,"end":1494397903138647,"diff":11427},{"start":1494397903144533,"end":1494397903155461,"diff":10928},{"start":1494397903155647,"end":1494397903168154,"diff":12507},{"start":1494397903168182,"end":1494397903178685,"diff":10503},{"start":1494397903178705,"end":1494397903188981,"diff":10276},{"start":1494397903189006,"end":1494397903201790,"diff":12784},{"start":1494397903219223,"end":1494397903230758,"diff":11535},{"start":1494397903230827,"end":1494397903242510,"diff":11683},{"start":1494397903242552,"end":1494397903254696,"diff":12144},{"start":1494397903254717,"end":1494397903265740,"diff":11023},{"start":1494397903265762,"end":1494397903277528,"diff":11766},{"start":1494397903297477,"end":1494397903310330,"diff":12853},{"start":1494397903310378,"end":1494397903320890,"diff":10512},{"start":1494397903320912,"end":1494397903330799,"diff":9887},{"start":1494397903330836,"end":1494397903341261,"diff":10425},{"start":1494397903341284,"end":1494397903352717,"diff":11433},{"start":1494397903368401,"end":1494397903379553,"diff":11152},{"start":1494397903379587,"end":1494397903392335,"diff":12748},{"start":1494397903392378,"end":1494397903404924,"diff":12546},{"start":1494397903404952,"end":1494397903414232,"diff":9280},{"start":1494397903414257,"end":1494397903425664,"diff":11407},{"start":1494397903443793,"end":1494397903454829,"diff":11036},{"start":1494397903454871,"end":1494397903465376,"diff":10505},{"start":1494397903465402,"end":1494397903475899,"diff":10497},{"start":1494397903475934,"end":1494397903486518,"diff":10584},{"start":1494397903486541,"end":1494397903497155,"diff":10614},{"start":1494397903516668,"end":1494397903528745,"diff":12077},{"start":1494397903528787,"end":1494397903540746,"diff":11959},{"start":1494397903540772,"end":1494397903550675,"diff":9903},{"start":1494397903550699,"end":1494397903562244,"diff":11545},{"start":1494397903562266,"end":1494397903573242,"diff":10976},{"start":1494397903589121,"end":1494397903599480,"diff":10359},{"start":1494397903599525,"end":1494397903612221,"diff":12696},{"start":1494397903612248,"end":1494397903625178,"diff":12930},{"start":1494397903625196,"end":1494397903637254,"diff":12058},{"start":1494397903637297,"end":1494397903647576,"diff":10279},{"start":1494397903666183,"end":1494397903677982,"diff":11799},{"start":1494397903678060,"end":1494397903689625,"diff":11565},{"start":1494397903689645,"end":1494397903701442,"diff":11797},{"start":1494397903701466,"end":1494397903713299,"diff":11833},{"start":1494397903713323,"end":1494397903726121,"diff":12798},{"start":1494397903746482,"end":1494397903758836,"diff":12354},{"start":1494397903758948,"end":1494397903768129,"diff":9181},{"start":1494397903768154,"end":1494397903779004,"diff":10850},{"start":1494397903779025,"end":1494397903789535,"diff":10510},{"start":1494397903789552,"end":1494397903799956,"diff":10404},{"start":1494397903817746,"end":1494397903828745,"diff":10999},{"start":1494397903828869,"end":1494397903840295,"diff":11426},{"start":1494397903840316,"end":1494397903851835,"diff":11519},{"start":1494397903851847,"end":1494397903863517,"diff":11670},{"start":1494397903863553,"end":1494397903877162,"diff":13609},{"start":1494397903895393,"end":1494397903906670,"diff":11277},{"start":1494397903906733,"end":1494397903916940,"diff":10207},{"start":1494397903916985,"end":1494397903927418,"diff":10433},{"start":1494397903927441,"end":1494397903938962,"diff":11521},{"start":1494397903939050,"end":1494397903951163,"diff":12113},{"start":1494397903968492,"end":1494397903979790,"diff":11298},{"start":1494397903979924,"end":1494397903989241,"diff":9317},{"start":1494397903989267,"end":1494397903999512,"diff":10245},{"start":1494397903999535,"end":1494397904012280,"diff":12745},{"start":1494397904012304,"end":1494397904025821,"diff":13517},{"start":1494397904043225,"end":1494397904053998,"diff":10773},{"start":1494397904054044,"end":1494397904067286,"diff":13242},{"start":1494397904067306,"end":1494397904077851,"diff":10545},{"start":1494397904077888,"end":1494397904090313,"diff":12425},{"start":1494397904090333,"end":1494397904102130,"diff":11797},{"start":1494397904118264,"end":1494397904130854,"diff":12590},{"start":1494397904130895,"end":1494397904142086,"diff":11191},{"start":1494397904142111,"end":1494397904153689,"diff":11578},{"start":1494397904153709,"end":1494397904163901,"diff":10192},{"start":1494397904164061,"end":1494397904176984,"diff":12923},{"start":1494397904196411,"end":1494397904209242,"diff":12831},{"start":1494397904209288,"end":1494397904222067,"diff":12779},{"start":1494397904222107,"end":1494397904233577,"diff":11470},{"start":1494397904233601,"end":1494397904246348,"diff":12747},{"start":1494397904246372,"end":1494397904257661,"diff":11289},{"start":1494397904273452,"end":1494397904284724,"diff":11272},{"start":1494397904284769,"end":1494397904296250,"diff":11481},{"start":1494397904296269,"end":1494397904308738,"diff":12469},{"start":1494397904308761,"end":1494397904321541,"diff":12780},{"start":1494397904321581,"end":1494397904333690,"diff":12109},{"start":1494397904350619,"end":1494397904360991,"diff":10372},{"start":1494397904361031,"end":1494397904373663,"diff":12632},{"start":1494397904373693,"end":1494397904386114,"diff":12421},{"start":1494397904386135,"end":1494397904397633,"diff":11498},{"start":1494397904397676,"end":1494397904408751,"diff":11075},{"start":1494397904424848,"end":1494397904435526,"diff":10678},{"start":1494397904435662,"end":1494397904446632,"diff":10970},{"start":1494397904446679,"end":1494397904456859,"diff":10180},{"start":1494397904456873,"end":1494397904467137,"diff":10264},{"start":1494397904467216,"end":1494397904479760,"diff":12544},{"start":1494397904496450,"end":1494397904508113,"diff":11663},{"start":1494397904508143,"end":1494397904518776,"diff":10633},{"start":1494397904518788,"end":1494397904528262,"diff":9474},{"start":1494397904528279,"end":1494397904538493,"diff":10214},{"start":1494397904538510,"end":1494397904549740,"diff":11230},{"start":1494397904569099,"end":1494397904581701,"diff":12602},{"start":1494397904581749,"end":1494397904593636,"diff":11887},{"start":1494397904593651,"end":1494397904603708,"diff":10057},{"start":1494397904603722,"end":1494397904614066,"diff":10344},{"start":1494397904614082,"end":1494397904625041,"diff":10959},{"start":1494397904640989,"end":1494397904652936,"diff":11947},{"start":1494397904652972,"end":1494397904663440,"diff":10468},{"start":1494397904663463,"end":1494397904674991,"diff":11528},{"start":1494397904675007,"end":1494397904685365,"diff":10358},{"start":1494397904685388,"end":1494397904696036,"diff":10648},{"start":1494397904714971,"end":1494397904725487,"diff":10516},{"start":1494397904725529,"end":1494397904736125,"diff":10596},{"start":1494397904736142,"end":1494397904746836,"diff":10694},{"start":1494397904746855,"end":1494397904757361,"diff":10506},{"start":1494397904757376,"end":1494397904767523,"diff":10147},{"start":1494397904785810,"end":1494397904796644,"diff":10834},{"start":1494397904796724,"end":1494397904810539,"diff":13815},{"start":1494397904810564,"end":1494397904820935,"diff":10371},{"start":1494397904820955,"end":1494397904831297,"diff":10342},{"start":1494397904831315,"end":1494397904842098,"diff":10783},{"start":1494397904860509,"end":1494397904872361,"diff":11852},{"start":1494397904872392,"end":1494397904883701,"diff":11309},{"start":1494397904883717,"end":1494397904895402,"diff":11685},{"start":1494397904895418,"end":1494397904908041,"diff":12623},{"start":1494397904908057,"end":1494397904918644,"diff":10587},{"start":1494397904937373,"end":1494397904948524,"diff":11151},{"start":1494397904948558,"end":1494397904959842,"diff":11284},{"start":1494397904959861,"end":1494397904969794,"diff":9933},{"start":1494397904969811,"end":1494397904979364,"diff":9553},{"start":1494397904979382,"end":1494397904990222,"diff":10840},{"start":1494397905009047,"end":1494397905021463,"diff":12416},{"start":1494397905021530,"end":1494397905032784,"diff":11254},{"start":1494397905032839,"end":1494397905044495,"diff":11656},{"start":1494397905044510,"end":1494397905055047,"diff":10537},{"start":1494397905055063,"end":1494397905067894,"diff":12831},{"start":1494397905089938,"end":1494397905101646,"diff":11708},{"start":1494397905101685,"end":1494397905112721,"diff":11036},{"start":1494397905112736,"end":1494397905123104,"diff":10368},{"start":1494397905123164,"end":1494397905134706,"diff":11542},{"start":1494397905134728,"end":1494397905145423,"diff":10695},{"start":1494397905167261,"end":1494397905177975,"diff":10714},{"start":1494397905178013,"end":1494397905189162,"diff":11149},{"start":1494397905189179,"end":1494397905199949,"diff":10770},{"start":1494397905199970,"end":1494397905210118,"diff":10148},{"start":1494397905210133,"end":1494397905221842,"diff":11709},{"start":1494397905241139,"end":1494397905251608,"diff":10469},{"start":1494397905251641,"end":1494397905262576,"diff":10935},{"start":1494397905262589,"end":1494397905273994,"diff":11405},{"start":1494397905274013,"end":1494397905284367,"diff":10354},{"start":1494397905284385,"end":1494397905295494,"diff":11109},{"start":1494397905312768,"end":1494397905325395,"diff":12627},{"start":1494397905325424,"end":1494397905336549,"diff":11125},{"start":1494397905336561,"end":1494397905347731,"diff":11170},{"start":1494397905347838,"end":1494397905358178,"diff":10340},{"start":1494397905358196,"end":1494397905368747,"diff":10551},{"start":1494397905384338,"end":1494397905397008,"diff":12670},{"start":1494397905397045,"end":1494397905407774,"diff":10729},{"start":1494397905407796,"end":1494397905417781,"diff":9985},{"start":1494397905417811,"end":1494397905431246,"diff":13435},{"start":1494397905431275,"end":1494397905442479,"diff":11204},{"start":1494397905461161,"end":1494397905471514,"diff":10353},{"start":1494397905471571,"end":1494397905482954,"diff":11383},{"start":1494397905482999,"end":1494397905494955,"diff":11956},{"start":1494397905494983,"end":1494397905506202,"diff":11219},{"start":1494397905506240,"end":1494397905517890,"diff":11650},{"start":1494397905537213,"end":1494397905549253,"diff":12040},{"start":1494397905549294,"end":1494397905559546,"diff":10252},{"start":1494397905559568,"end":1494397905570124,"diff":10556},{"start":1494397905570147,"end":1494397905580568,"diff":10421},{"start":1494397905580590,"end":1494397905590851,"diff":10261},{"start":1494397905605534,"end":1494397905616497,"diff":10963},{"start":1494397905616560,"end":1494397905628161,"diff":11601},{"start":1494397905628189,"end":1494397905639925,"diff":11736},{"start":1494397905639952,"end":1494397905651323,"diff":11371},{"start":1494397905651351,"end":1494397905662449,"diff":11098},{"start":1494397905679719,"end":1494397905689653,"diff":9934},{"start":1494397905689726,"end":1494397905700300,"diff":10574},{"start":1494397905700325,"end":1494397905711938,"diff":11613},{"start":1494397905711968,"end":1494397905730268,"diff":18300},{"start":1494397905730339,"end":1494397905740176,"diff":9837},{"start":1494397905760084,"end":1494397905772138,"diff":12054},{"start":1494397905772208,"end":1494397905784862,"diff":12654},{"start":1494397905784933,"end":1494397905796166,"diff":11233},{"start":1494397905796197,"end":1494397905808368,"diff":12171},{"start":1494397905808390,"end":1494397905819645,"diff":11255},{"start":1494397905839625,"end":1494397905851558,"diff":11933},{"start":1494397905851639,"end":1494397905862700,"diff":11061},{"start":1494397905862723,"end":1494397905873152,"diff":10429},{"start":1494397905873177,"end":1494397905884769,"diff":11592},{"start":1494397905884814,"end":1494397905895707,"diff":10893},{"start":1494397905915210,"end":1494397905925456,"diff":10246},{"start":1494397905925483,"end":1494397905935791,"diff":10308},{"start":1494397905935824,"end":1494397905946862,"diff":11038},{"start":1494397905946884,"end":1494397905959012,"diff":12128},{"start":1494397905959035,"end":1494397905970667,"diff":11632},{"start":1494397905988599,"end":1494397905999754,"diff":11155},{"start":1494397905999960,"end":1494397906011249,"diff":11289},{"start":1494397906011268,"end":1494397906022833,"diff":11565},{"start":1494397906022852,"end":1494397906033989,"diff":11137},{"start":1494397906034061,"end":1494397906046113,"diff":12052},{"start":1494397906064781,"end":1494397906075154,"diff":10373},{"start":1494397906075184,"end":1494397906086903,"diff":11719},{"start":1494397906086988,"end":1494397906099409,"diff":12421},{"start":1494397906099473,"end":1494397906110001,"diff":10528},{"start":1494397906110025,"end":1494397906120301,"diff":10276},{"start":1494397906139947,"end":1494397906151052,"diff":11105},{"start":1494397906151112,"end":1494397906162522,"diff":11410},{"start":1494397906162549,"end":1494397906173814,"diff":11265},{"start":1494397906173849,"end":1494397906185455,"diff":11606},{"start":1494397906185506,"end":1494397906196930,"diff":11424},{"start":1494397906212846,"end":1494397906225364,"diff":12518},{"start":1494397906227540,"end":1494397906238587,"diff":11047},{"start":1494397906238599,"end":1494397906249223,"diff":10624},{"start":1494397906249234,"end":1494397906260840,"diff":11606},{"start":1494397906260854,"end":1494397906272412,"diff":11558},{"start":1494397906289241,"end":1494397906299895,"diff":10654},{"start":1494397906299918,"end":1494397906310774,"diff":10856},{"start":1494397906310788,"end":1494397906321380,"diff":10592},{"start":1494397906321406,"end":1494397906333548,"diff":12142},{"start":1494397906333573,"end":1494397906345184,"diff":11611},{"start":1494397906361587,"end":1494397906372577,"diff":10990},{"start":1494397906372606,"end":1494397906383508,"diff":10902},{"start":1494397906383533,"end":1494397906393510,"diff":9977},{"start":1494397906393535,"end":1494397906405649,"diff":12114},{"start":1494397906405701,"end":1494397906417756,"diff":12055},{"start":1494397906435770,"end":1494397906446760,"diff":10990},{"start":1494397906446933,"end":1494397906458390,"diff":11457},{"start":1494397906458421,"end":1494397906471175,"diff":12754},{"start":1494397906471195,"end":1494397906483507,"diff":12312},{"start":1494397906483529,"end":1494397906495855,"diff":12326},{"start":1494397906515977,"end":1494397906527833,"diff":11856},{"start":1494397906527896,"end":1494397906539437,"diff":11541},{"start":1494397906539449,"end":1494397906551045,"diff":11596},{"start":1494397906551096,"end":1494397906563172,"diff":12076},{"start":1494397906563185,"end":1494397906574384,"diff":11199},{"start":1494397906590990,"end":1494397906603526,"diff":12536},{"start":1494397906603581,"end":1494397906616309,"diff":12728},{"start":1494397906616351,"end":1494397906626782,"diff":10431},{"start":1494397906626823,"end":1494397906637580,"diff":10757},{"start":1494397906637621,"end":1494397906649419,"diff":11798},{"start":1494397906669429,"end":1494397906682150,"diff":12721},{"start":1494397906682206,"end":1494397906694993,"diff":12787},{"start":1494397906695018,"end":1494397906707122,"diff":12104},{"start":1494397906707148,"end":1494397906718989,"diff":11841},{"start":1494397906719030,"end":1494397906731335,"diff":12305},{"start":1494397906747722,"end":1494397906760205,"diff":12483},{"start":1494397906760311,"end":1494397906771908,"diff":11597},{"start":1494397906771930,"end":1494397906783456,"diff":11526},{"start":1494397906783477,"end":1494397906795273,"diff":11796},{"start":1494397906795292,"end":1494397906806753,"diff":11461},{"start":1494397906823496,"end":1494397906835535,"diff":12039},{"start":1494397906835578,"end":1494397906845851,"diff":10273},{"start":1494397906845876,"end":1494397906857348,"diff":11472},{"start":1494397906857393,"end":1494397906911348,"diff":53955},{"start":1494397906911362,"end":1494397906923803,"diff":12441},{"start":1494397906941757,"end":1494397906951721,"diff":9964},{"start":1494397906951744,"end":1494397906963260,"diff":11516},{"start":1494397906963285,"end":1494397906975075,"diff":11790},{"start":1494397906975096,"end":1494397906987844,"diff":12748},{"start":1494397906987868,"end":1494397906998256,"diff":10388},{"start":1494397907015038,"end":1494397907026371,"diff":11333},{"start":1494397907026411,"end":1494397907038736,"diff":12325},{"start":1494397907038758,"end":1494397907050276,"diff":11518},{"start":1494397907050299,"end":1494397907061847,"diff":11548},{"start":1494397907061870,"end":1494397907073594,"diff":11724},{"start":1494397907090080,"end":1494397907102639,"diff":12559},{"start":1494397907102733,"end":1494397907113017,"diff":10284},{"start":1494397907113041,"end":1494397907125820,"diff":12779},{"start":1494397907125844,"end":1494397907138576,"diff":12732},{"start":1494397907138597,"end":1494397907152363,"diff":13766},{"start":1494397907169144,"end":1494397907180557,"diff":11413},{"start":1494397907180657,"end":1494397907193413,"diff":12756},{"start":1494397907193438,"end":1494397907204585,"diff":11147},{"start":1494397907204610,"end":1494397907214907,"diff":10297},{"start":1494397907214928,"end":1494397907227575,"diff":12647},{"start":1494397907245187,"end":1494397907255509,"diff":10322},{"start":1494397907255550,"end":1494397907267601,"diff":12051},{"start":1494397907267624,"end":1494397907277922,"diff":10298},{"start":1494397907277945,"end":1494397907288474,"diff":10529},{"start":1494397907288497,"end":1494397907299943,"diff":11446},{"start":1494397907315998,"end":1494397907327637,"diff":11639},{"start":1494397907327738,"end":1494397907338548,"diff":10810},{"start":1494397907338568,"end":1494397907350709,"diff":12141},{"start":1494397907350730,"end":1494397907363032,"diff":12302},{"start":1494397907363051,"end":1494397907374680,"diff":11629},{"start":1494397907391999,"end":1494397907404472,"diff":12473},{"start":1494397907404517,"end":1494397907416219,"diff":11702},{"start":1494397907416242,"end":1494397907426470,"diff":10228},{"start":1494397907426494,"end":1494397907439116,"diff":12622},{"start":1494397907439137,"end":1494397907450633,"diff":11496},{"start":1494397907468009,"end":1494397907479405,"diff":11396},{"start":1494397907479448,"end":1494397907491613,"diff":12165},{"start":1494397907491656,"end":1494397907503158,"diff":11502},{"start":1494397907503184,"end":1494397907514812,"diff":11628},{"start":1494397907514834,"end":1494397907526469,"diff":11635},{"start":1494397907543128,"end":1494397907555400,"diff":12272},{"start":1494397907555502,"end":1494397907566988,"diff":11486},{"start":1494397907567013,"end":1494397907578682,"diff":11669},{"start":1494397907578721,"end":1494397907588576,"diff":9855},{"start":1494397907588597,"end":1494397907599324,"diff":10727},{"start":1494397907617211,"end":1494397907629975,"diff":12764},{"start":1494397907630049,"end":1494397907642572,"diff":12523},{"start":1494397907642594,"end":1494397907654142,"diff":11548},{"start":1494397907654184,"end":1494397907665712,"diff":11528},{"start":1494397907665737,"end":1494397907677443,"diff":11706},{"start":1494397907693879,"end":1494397907706370,"diff":12491},{"start":1494397907706509,"end":1494397907719297,"diff":12788},{"start":1494397907719335,"end":1494397907729713,"diff":10378},{"start":1494397907729734,"end":1494397907741156,"diff":11422},{"start":1494397907741180,"end":1494397907752947,"diff":11767},{"start":1494397907773209,"end":1494397907785755,"diff":12546},{"start":1494397907785789,"end":1494397907796690,"diff":10901},{"start":1494397907796714,"end":1494397907809503,"diff":12789},{"start":1494397907809542,"end":1494397907822362,"diff":12820},{"start":1494397907822387,"end":1494397907834230,"diff":11843},{"start":1494397907850247,"end":1494397907860694,"diff":10447},{"start":1494397907860714,"end":1494397907873291,"diff":12577},{"start":1494397907873302,"end":1494397907884559,"diff":11257},{"start":1494397907884567,"end":1494397907896035,"diff":11468},{"start":1494397907896058,"end":1494397907908651,"diff":12593},{"start":1494397907928328,"end":1494397907938529,"diff":10201},{"start":1494397907938574,"end":1494397907949381,"diff":10807},{"start":1494397907949460,"end":1494397907962269,"diff":12809},{"start":1494397907962311,"end":1494397907973575,"diff":11264},{"start":1494397907973597,"end":1494397907984636,"diff":11039},{"start":1494397908001302,"end":1494397908013981,"diff":12679},{"start":1494397908014037,"end":1494397908025698,"diff":11661},{"start":1494397908025722,"end":1494397908037344,"diff":11622},{"start":1494397908037364,"end":1494397908049280,"diff":11916},{"start":1494397908049302,"end":1494397908060471,"diff":11169},{"start":1494397908077350,"end":1494397908088583,"diff":11233},{"start":1494397908088643,"end":1494397908100988,"diff":12345},{"start":1494397908101030,"end":1494397908112993,"diff":11963},{"start":1494397908113025,"end":1494397908124376,"diff":11351},{"start":1494397908124412,"end":1494397908135936,"diff":11524},{"start":1494397908152151,"end":1494397908163246,"diff":11095},{"start":1494397908163307,"end":1494397908176086,"diff":12779},{"start":1494397908176127,"end":1494397908188499,"diff":12372},{"start":1494397908188520,"end":1494397908200023,"diff":11503},{"start":1494397908200046,"end":1494397908211662,"diff":11616},{"start":1494397908228862,"end":1494397908240358,"diff":11496},{"start":1494397908240417,"end":1494397908251975,"diff":11558},{"start":1494397908252067,"end":1494397908263274,"diff":11207},{"start":1494397908263363,"end":1494397908275248,"diff":11885},{"start":1494397908275301,"end":1494397908286836,"diff":11535},{"start":1494397908304442,"end":1494397908315888,"diff":11446},{"start":1494397908315942,"end":1494397908328695,"diff":12753},{"start":1494397908328760,"end":1494397908339673,"diff":10913},{"start":1494397908339706,"end":1494397908348900,"diff":9194},{"start":1494397908348954,"end":1494397908359189,"diff":10235},{"start":1494397908378225,"end":1494397908388355,"diff":10130},{"start":1494397908388384,"end":1494397908399946,"diff":11562},{"start":1494397908399957,"end":1494397908411573,"diff":11616},{"start":1494397908411595,"end":1494397908424329,"diff":12734},{"start":1494397908424352,"end":1494397908434871,"diff":10519},{"start":1494397908452753,"end":1494397908463097,"diff":10344},{"start":1494397908463148,"end":1494397908475883,"diff":12735},{"start":1494397908475906,"end":1494397908488454,"diff":12548},{"start":1494397908488477,"end":1494397908501124,"diff":12647},{"start":1494397908501147,"end":1494397908513230,"diff":12083},{"start":1494397908531395,"end":1494397908542192,"diff":10797},{"start":1494397908542288,"end":1494397908553797,"diff":11509},{"start":1494397908553823,"end":1494397908565378,"diff":11555},{"start":1494397908565398,"end":1494397908577183,"diff":11785},{"start":1494397908577208,"end":1494397908588522,"diff":11314},{"start":1494397908607616,"end":1494397908618092,"diff":10476},{"start":1494397908618136,"end":1494397908628541,"diff":10405},{"start":1494397908628565,"end":1494397908638711,"diff":10146},{"start":1494397908638732,"end":1494397908649213,"diff":10481},{"start":1494397908649234,"end":1494397908660876,"diff":11642},{"start":1494397908679029,"end":1494397908690589,"diff":11560},{"start":1494397908690634,"end":1494397908703391,"diff":12757},{"start":1494397908703413,"end":1494397908714557,"diff":11144},{"start":1494397908714578,"end":1494397908724808,"diff":10230},{"start":1494397908724827,"end":1494397908737538,"diff":12711},{"start":1494397908755981,"end":1494397908768757,"diff":12776},{"start":1494397908768795,"end":1494397908779988,"diff":11193},{"start":1494397908780009,"end":1494397908791013,"diff":11004},{"start":1494397908791034,"end":1494397908803612,"diff":12578},{"start":1494397908803634,"end":1494397908816397,"diff":12763},{"start":1494397908833213,"end":1494397908844220,"diff":11007},{"start":1494397908844260,"end":1494397908855729,"diff":11469},{"start":1494397908855749,"end":1494397908867337,"diff":11588},{"start":1494397908867356,"end":1494397908877830,"diff":10474},{"start":1494397908877850,"end":1494397908888509,"diff":10659},{"start":1494397908906273,"end":1494397908919029,"diff":12756},{"start":1494397908919103,"end":1494397908929697,"diff":10594},{"start":1494397908929716,"end":1494397908941188,"diff":11472},{"start":1494397908941225,"end":1494397908951599,"diff":10374},{"start":1494397908951622,"end":1494397908962351,"diff":10729}],"now":1494397908969,"mem":{"start":{"process":{"rss":53481472,"heapTotal":30670848,"heapUsed":24698264,"external":1891128},"os":353452032},"end":{"process":{"rss":51159040,"heapTotal":24924160,"heapUsed":18558624,"external":17476},"os":342634496}},"stats":{"moe":0.0002405410466237888,"rme":2.0727179201337336,"sem":0.00012272502378764735,"deviation":0.0010769077131784566,"mean":0.01160510285974026,"sample":[0.011467463,0.0116833162,0.0110667986,0.0114649296,0.0106894188,0.0113355634,0.011706378600000001,0.012012353,0.010710911600000001,0.011895782,0.011171711400000001,0.0114941526,0.0118087994,0.011764206000000001,0.0122733626,0.0120636172,0.011644141399999999,0.0109948232,0.0106830832,0.0112067242,0.0110229152,0.010528214800000001,0.0112750804,0.0116450236,0.010590902400000001,0.0117883798,0.0111215244,0.010934747,0.0108886886,0.011212129999999999,0.011645420600000001,0.0113731656,0.0107421604,0.0113989206,0.012110639,0.011928167600000001,0.0112285916,0.0111169406,0.0115185852,0.011128334600000001,0.0114127614,0.0119272068,0.011207295,0.0112760802,0.012035436600000001,0.0117016614,0.0117024192,0.012397311599999999,0.0118235306,0.0200884698,0.0113174864,0.011727395,0.012470336,0.0117018898,0.0109666452,0.0117500418,0.0117435844,0.011707255199999999,0.011253771999999999,0.0120616948,0.0118412792,0.012220146599999999,0.0116964134,0.011278997,0.011853991599999999,0.011737397600000001,0.011917730999999999,0.011631884,0.0109658168,0.0113459804,0.0121109982,0.0114423954,0.010815898000000001,0.0117182946,0.0121013318,0.0110752382,0.0112307852],"variance":0.000001159730222703253},"count":5,"hz":86.16899066609234,"time":11.60510285974026,"cycles":2,"battery":{"amperage":-2155,"currentCapacity":3701,"percent":49,"charging":"","temp":3105}},{"msg":"zoomzoom2 x 86.17 ops/sec ±2.07% (77 runs sampled)","name":"zoomzoom2","num":86.17,"sampled":"77","variation":"2.07","suite":["/Users/james/code/fluents/chain/packages/bench-chain/example/math/async-first-faster2.json"],"timesFor":[{"start":1494397903127220,"end":1494397903138647,"diff":11427},{"start":1494397903144533,"end":1494397903155461,"diff":10928},{"start":1494397903155647,"end":1494397903168154,"diff":12507},{"start":1494397903168182,"end":1494397903178685,"diff":10503},{"start":1494397903178705,"end":1494397903188981,"diff":10276},{"start":1494397903189006,"end":1494397903201790,"diff":12784},{"start":1494397903219223,"end":1494397903230758,"diff":11535},{"start":1494397903230827,"end":1494397903242510,"diff":11683},{"start":1494397903242552,"end":1494397903254696,"diff":12144},{"start":1494397903254717,"end":1494397903265740,"diff":11023},{"start":1494397903265762,"end":1494397903277528,"diff":11766},{"start":1494397903297477,"end":1494397903310330,"diff":12853},{"start":1494397903310378,"end":1494397903320890,"diff":10512},{"start":1494397903320912,"end":1494397903330799,"diff":9887},{"start":1494397903330836,"end":1494397903341261,"diff":10425},{"start":1494397903341284,"end":1494397903352717,"diff":11433},{"start":1494397903368401,"end":1494397903379553,"diff":11152},{"start":1494397903379587,"end":1494397903392335,"diff":12748},{"start":1494397903392378,"end":1494397903404924,"diff":12546},{"start":1494397903404952,"end":1494397903414232,"diff":9280},{"start":1494397903414257,"end":1494397903425664,"diff":11407},{"start":1494397903443793,"end":1494397903454829,"diff":11036},{"start":1494397903454871,"end":1494397903465376,"diff":10505},{"start":1494397903465402,"end":1494397903475899,"diff":10497},{"start":1494397903475934,"end":1494397903486518,"diff":10584},{"start":1494397903486541,"end":1494397903497155,"diff":10614},{"start":1494397903516668,"end":1494397903528745,"diff":12077},{"start":1494397903528787,"end":1494397903540746,"diff":11959},{"start":1494397903540772,"end":1494397903550675,"diff":9903},{"start":1494397903550699,"end":1494397903562244,"diff":11545},{"start":1494397903562266,"end":1494397903573242,"diff":10976},{"start":1494397903589121,"end":1494397903599480,"diff":10359},{"start":1494397903599525,"end":1494397903612221,"diff":12696},{"start":1494397903612248,"end":1494397903625178,"diff":12930},{"start":1494397903625196,"end":1494397903637254,"diff":12058},{"start":1494397903637297,"end":1494397903647576,"diff":10279},{"start":1494397903666183,"end":1494397903677982,"diff":11799},{"start":1494397903678060,"end":1494397903689625,"diff":11565},{"start":1494397903689645,"end":1494397903701442,"diff":11797},{"start":1494397903701466,"end":1494397903713299,"diff":11833},{"start":1494397903713323,"end":1494397903726121,"diff":12798},{"start":1494397903746482,"end":1494397903758836,"diff":12354},{"start":1494397903758948,"end":1494397903768129,"diff":9181},{"start":1494397903768154,"end":1494397903779004,"diff":10850},{"start":1494397903779025,"end":1494397903789535,"diff":10510},{"start":1494397903789552,"end":1494397903799956,"diff":10404},{"start":1494397903817746,"end":1494397903828745,"diff":10999},{"start":1494397903828869,"end":1494397903840295,"diff":11426},{"start":1494397903840316,"end":1494397903851835,"diff":11519},{"start":1494397903851847,"end":1494397903863517,"diff":11670},{"start":1494397903863553,"end":1494397903877162,"diff":13609},{"start":1494397903895393,"end":1494397903906670,"diff":11277},{"start":1494397903906733,"end":1494397903916940,"diff":10207},{"start":1494397903916985,"end":1494397903927418,"diff":10433},{"start":1494397903927441,"end":1494397903938962,"diff":11521},{"start":1494397903939050,"end":1494397903951163,"diff":12113},{"start":1494397903968492,"end":1494397903979790,"diff":11298},{"start":1494397903979924,"end":1494397903989241,"diff":9317},{"start":1494397903989267,"end":1494397903999512,"diff":10245},{"start":1494397903999535,"end":1494397904012280,"diff":12745},{"start":1494397904012304,"end":1494397904025821,"diff":13517},{"start":1494397904043225,"end":1494397904053998,"diff":10773},{"start":1494397904054044,"end":1494397904067286,"diff":13242},{"start":1494397904067306,"end":1494397904077851,"diff":10545},{"start":1494397904077888,"end":1494397904090313,"diff":12425},{"start":1494397904090333,"end":1494397904102130,"diff":11797},{"start":1494397904118264,"end":1494397904130854,"diff":12590},{"start":1494397904130895,"end":1494397904142086,"diff":11191},{"start":1494397904142111,"end":1494397904153689,"diff":11578},{"start":1494397904153709,"end":1494397904163901,"diff":10192},{"start":1494397904164061,"end":1494397904176984,"diff":12923},{"start":1494397904196411,"end":1494397904209242,"diff":12831},{"start":1494397904209288,"end":1494397904222067,"diff":12779},{"start":1494397904222107,"end":1494397904233577,"diff":11470},{"start":1494397904233601,"end":1494397904246348,"diff":12747},{"start":1494397904246372,"end":1494397904257661,"diff":11289},{"start":1494397904273452,"end":1494397904284724,"diff":11272},{"start":1494397904284769,"end":1494397904296250,"diff":11481},{"start":1494397904296269,"end":1494397904308738,"diff":12469},{"start":1494397904308761,"end":1494397904321541,"diff":12780},{"start":1494397904321581,"end":1494397904333690,"diff":12109},{"start":1494397904350619,"end":1494397904360991,"diff":10372},{"start":1494397904361031,"end":1494397904373663,"diff":12632},{"start":1494397904373693,"end":1494397904386114,"diff":12421},{"start":1494397904386135,"end":1494397904397633,"diff":11498},{"start":1494397904397676,"end":1494397904408751,"diff":11075},{"start":1494397904424848,"end":1494397904435526,"diff":10678},{"start":1494397904435662,"end":1494397904446632,"diff":10970},{"start":1494397904446679,"end":1494397904456859,"diff":10180},{"start":1494397904456873,"end":1494397904467137,"diff":10264},{"start":1494397904467216,"end":1494397904479760,"diff":12544},{"start":1494397904496450,"end":1494397904508113,"diff":11663},{"start":1494397904508143,"end":1494397904518776,"diff":10633},{"start":1494397904518788,"end":1494397904528262,"diff":9474},{"start":1494397904528279,"end":1494397904538493,"diff":10214},{"start":1494397904538510,"end":1494397904549740,"diff":11230},{"start":1494397904569099,"end":1494397904581701,"diff":12602},{"start":1494397904581749,"end":1494397904593636,"diff":11887},{"start":1494397904593651,"end":1494397904603708,"diff":10057},{"start":1494397904603722,"end":1494397904614066,"diff":10344},{"start":1494397904614082,"end":1494397904625041,"diff":10959},{"start":1494397904640989,"end":1494397904652936,"diff":11947},{"start":1494397904652972,"end":1494397904663440,"diff":10468},{"start":1494397904663463,"end":1494397904674991,"diff":11528},{"start":1494397904675007,"end":1494397904685365,"diff":10358},{"start":1494397904685388,"end":1494397904696036,"diff":10648},{"start":1494397904714971,"end":1494397904725487,"diff":10516},{"start":1494397904725529,"end":1494397904736125,"diff":10596},{"start":1494397904736142,"end":1494397904746836,"diff":10694},{"start":1494397904746855,"end":1494397904757361,"diff":10506},{"start":1494397904757376,"end":1494397904767523,"diff":10147},{"start":1494397904785810,"end":1494397904796644,"diff":10834},{"start":1494397904796724,"end":1494397904810539,"diff":13815},{"start":1494397904810564,"end":1494397904820935,"diff":10371},{"start":1494397904820955,"end":1494397904831297,"diff":10342},{"start":1494397904831315,"end":1494397904842098,"diff":10783},{"start":1494397904860509,"end":1494397904872361,"diff":11852},{"start":1494397904872392,"end":1494397904883701,"diff":11309},{"start":1494397904883717,"end":1494397904895402,"diff":11685},{"start":1494397904895418,"end":1494397904908041,"diff":12623},{"start":1494397904908057,"end":1494397904918644,"diff":10587},{"start":1494397904937373,"end":1494397904948524,"diff":11151},{"start":1494397904948558,"end":1494397904959842,"diff":11284},{"start":1494397904959861,"end":1494397904969794,"diff":9933},{"start":1494397904969811,"end":1494397904979364,"diff":9553},{"start":1494397904979382,"end":1494397904990222,"diff":10840},{"start":1494397905009047,"end":1494397905021463,"diff":12416},{"start":1494397905021530,"end":1494397905032784,"diff":11254},{"start":1494397905032839,"end":1494397905044495,"diff":11656},{"start":1494397905044510,"end":1494397905055047,"diff":10537},{"start":1494397905055063,"end":1494397905067894,"diff":12831},{"start":1494397905089938,"end":1494397905101646,"diff":11708},{"start":1494397905101685,"end":1494397905112721,"diff":11036},{"start":1494397905112736,"end":1494397905123104,"diff":10368},{"start":1494397905123164,"end":1494397905134706,"diff":11542},{"start":1494397905134728,"end":1494397905145423,"diff":10695},{"start":1494397905167261,"end":1494397905177975,"diff":10714},{"start":1494397905178013,"end":1494397905189162,"diff":11149},{"start":1494397905189179,"end":1494397905199949,"diff":10770},{"start":1494397905199970,"end":1494397905210118,"diff":10148},{"start":1494397905210133,"end":1494397905221842,"diff":11709},{"start":1494397905241139,"end":1494397905251608,"diff":10469},{"start":1494397905251641,"end":1494397905262576,"diff":10935},{"start":1494397905262589,"end":1494397905273994,"diff":11405},{"start":1494397905274013,"end":1494397905284367,"diff":10354},{"start":1494397905284385,"end":1494397905295494,"diff":11109},{"start":1494397905312768,"end":1494397905325395,"diff":12627},{"start":1494397905325424,"end":1494397905336549,"diff":11125},{"start":1494397905336561,"end":1494397905347731,"diff":11170},{"start":1494397905347838,"end":1494397905358178,"diff":10340},{"start":1494397905358196,"end":1494397905368747,"diff":10551},{"start":1494397905384338,"end":1494397905397008,"diff":12670},{"start":1494397905397045,"end":1494397905407774,"diff":10729},{"start":1494397905407796,"end":1494397905417781,"diff":9985},{"start":1494397905417811,"end":1494397905431246,"diff":13435},{"start":1494397905431275,"end":1494397905442479,"diff":11204},{"start":1494397905461161,"end":1494397905471514,"diff":10353},{"start":1494397905471571,"end":1494397905482954,"diff":11383},{"start":1494397905482999,"end":1494397905494955,"diff":11956},{"start":1494397905494983,"end":1494397905506202,"diff":11219},{"start":1494397905506240,"end":1494397905517890,"diff":11650},{"start":1494397905537213,"end":1494397905549253,"diff":12040},{"start":1494397905549294,"end":1494397905559546,"diff":10252},{"start":1494397905559568,"end":1494397905570124,"diff":10556},{"start":1494397905570147,"end":1494397905580568,"diff":10421},{"start":1494397905580590,"end":1494397905590851,"diff":10261},{"start":1494397905605534,"end":1494397905616497,"diff":10963},{"start":1494397905616560,"end":1494397905628161,"diff":11601},{"start":1494397905628189,"end":1494397905639925,"diff":11736},{"start":1494397905639952,"end":1494397905651323,"diff":11371},{"start":1494397905651351,"end":1494397905662449,"diff":11098},{"start":1494397905679719,"end":1494397905689653,"diff":9934},{"start":1494397905689726,"end":1494397905700300,"diff":10574},{"start":1494397905700325,"end":1494397905711938,"diff":11613},{"start":1494397905711968,"end":1494397905730268,"diff":18300},{"start":1494397905730339,"end":1494397905740176,"diff":9837},{"start":1494397905760084,"end":1494397905772138,"diff":12054},{"start":1494397905772208,"end":1494397905784862,"diff":12654},{"start":1494397905784933,"end":1494397905796166,"diff":11233},{"start":1494397905796197,"end":1494397905808368,"diff":12171},{"start":1494397905808390,"end":1494397905819645,"diff":11255},{"start":1494397905839625,"end":1494397905851558,"diff":11933},{"start":1494397905851639,"end":1494397905862700,"diff":11061},{"start":1494397905862723,"end":1494397905873152,"diff":10429},{"start":1494397905873177,"end":1494397905884769,"diff":11592},{"start":1494397905884814,"end":1494397905895707,"diff":10893},{"start":1494397905915210,"end":1494397905925456,"diff":10246},{"start":1494397905925483,"end":1494397905935791,"diff":10308},{"start":1494397905935824,"end":1494397905946862,"diff":11038},{"start":1494397905946884,"end":1494397905959012,"diff":12128},{"start":1494397905959035,"end":1494397905970667,"diff":11632},{"start":1494397905988599,"end":1494397905999754,"diff":11155},{"start":1494397905999960,"end":1494397906011249,"diff":11289},{"start":1494397906011268,"end":1494397906022833,"diff":11565},{"start":1494397906022852,"end":1494397906033989,"diff":11137},{"start":1494397906034061,"end":1494397906046113,"diff":12052},{"start":1494397906064781,"end":1494397906075154,"diff":10373},{"start":1494397906075184,"end":1494397906086903,"diff":11719},{"start":1494397906086988,"end":1494397906099409,"diff":12421},{"start":1494397906099473,"end":1494397906110001,"diff":10528},{"start":1494397906110025,"end":1494397906120301,"diff":10276},{"start":1494397906139947,"end":1494397906151052,"diff":11105},{"start":1494397906151112,"end":1494397906162522,"diff":11410},{"start":1494397906162549,"end":1494397906173814,"diff":11265},{"start":1494397906173849,"end":1494397906185455,"diff":11606},{"start":1494397906185506,"end":1494397906196930,"diff":11424},{"start":1494397906212846,"end":1494397906225364,"diff":12518},{"start":1494397906227540,"end":1494397906238587,"diff":11047},{"start":1494397906238599,"end":1494397906249223,"diff":10624},{"start":1494397906249234,"end":1494397906260840,"diff":11606},{"start":1494397906260854,"end":1494397906272412,"diff":11558},{"start":1494397906289241,"end":1494397906299895,"diff":10654},{"start":1494397906299918,"end":1494397906310774,"diff":10856},{"start":1494397906310788,"end":1494397906321380,"diff":10592},{"start":1494397906321406,"end":1494397906333548,"diff":12142},{"start":1494397906333573,"end":1494397906345184,"diff":11611},{"start":1494397906361587,"end":1494397906372577,"diff":10990},{"start":1494397906372606,"end":1494397906383508,"diff":10902},{"start":1494397906383533,"end":1494397906393510,"diff":9977},{"start":1494397906393535,"end":1494397906405649,"diff":12114},{"start":1494397906405701,"end":1494397906417756,"diff":12055},{"start":1494397906435770,"end":1494397906446760,"diff":10990},{"start":1494397906446933,"end":1494397906458390,"diff":11457},{"start":1494397906458421,"end":1494397906471175,"diff":12754},{"start":1494397906471195,"end":1494397906483507,"diff":12312},{"start":1494397906483529,"end":1494397906495855,"diff":12326},{"start":1494397906515977,"end":1494397906527833,"diff":11856},{"start":1494397906527896,"end":1494397906539437,"diff":11541},{"start":1494397906539449,"end":1494397906551045,"diff":11596},{"start":1494397906551096,"end":1494397906563172,"diff":12076},{"start":1494397906563185,"end":1494397906574384,"diff":11199},{"start":1494397906590990,"end":1494397906603526,"diff":12536},{"start":1494397906603581,"end":1494397906616309,"diff":12728},{"start":1494397906616351,"end":1494397906626782,"diff":10431},{"start":1494397906626823,"end":1494397906637580,"diff":10757},{"start":1494397906637621,"end":1494397906649419,"diff":11798},{"start":1494397906669429,"end":1494397906682150,"diff":12721},{"start":1494397906682206,"end":1494397906694993,"diff":12787},{"start":1494397906695018,"end":1494397906707122,"diff":12104},{"start":1494397906707148,"end":1494397906718989,"diff":11841},{"start":1494397906719030,"end":1494397906731335,"diff":12305},{"start":1494397906747722,"end":1494397906760205,"diff":12483},{"start":1494397906760311,"end":1494397906771908,"diff":11597},{"start":1494397906771930,"end":1494397906783456,"diff":11526},{"start":1494397906783477,"end":1494397906795273,"diff":11796},{"start":1494397906795292,"end":1494397906806753,"diff":11461},{"start":1494397906823496,"end":1494397906835535,"diff":12039},{"start":1494397906835578,"end":1494397906845851,"diff":10273},{"start":1494397906845876,"end":1494397906857348,"diff":11472},{"start":1494397906857393,"end":1494397906911348,"diff":53955},{"start":1494397906911362,"end":1494397906923803,"diff":12441},{"start":1494397906941757,"end":1494397906951721,"diff":9964},{"start":1494397906951744,"end":1494397906963260,"diff":11516},{"start":1494397906963285,"end":1494397906975075,"diff":11790},{"start":1494397906975096,"end":1494397906987844,"diff":12748},{"start":1494397906987868,"end":1494397906998256,"diff":10388},{"start":1494397907015038,"end":1494397907026371,"diff":11333},{"start":1494397907026411,"end":1494397907038736,"diff":12325},{"start":1494397907038758,"end":1494397907050276,"diff":11518},{"start":1494397907050299,"end":1494397907061847,"diff":11548},{"start":1494397907061870,"end":1494397907073594,"diff":11724},{"start":1494397907090080,"end":1494397907102639,"diff":12559},{"start":1494397907102733,"end":1494397907113017,"diff":10284},{"start":1494397907113041,"end":1494397907125820,"diff":12779},{"start":1494397907125844,"end":1494397907138576,"diff":12732},{"start":1494397907138597,"end":1494397907152363,"diff":13766},{"start":1494397907169144,"end":1494397907180557,"diff":11413},{"start":1494397907180657,"end":1494397907193413,"diff":12756},{"start":1494397907193438,"end":1494397907204585,"diff":11147},{"start":1494397907204610,"end":1494397907214907,"diff":10297},{"start":1494397907214928,"end":1494397907227575,"diff":12647},{"start":1494397907245187,"end":1494397907255509,"diff":10322},{"start":1494397907255550,"end":1494397907267601,"diff":12051},{"start":1494397907267624,"end":1494397907277922,"diff":10298},{"start":1494397907277945,"end":1494397907288474,"diff":10529},{"start":1494397907288497,"end":1494397907299943,"diff":11446},{"start":1494397907315998,"end":1494397907327637,"diff":11639},{"start":1494397907327738,"end":1494397907338548,"diff":10810},{"start":1494397907338568,"end":1494397907350709,"diff":12141},{"start":1494397907350730,"end":1494397907363032,"diff":12302},{"start":1494397907363051,"end":1494397907374680,"diff":11629},{"start":1494397907391999,"end":1494397907404472,"diff":12473},{"start":1494397907404517,"end":1494397907416219,"diff":11702},{"start":1494397907416242,"end":1494397907426470,"diff":10228},{"start":1494397907426494,"end":1494397907439116,"diff":12622},{"start":1494397907439137,"end":1494397907450633,"diff":11496},{"start":1494397907468009,"end":1494397907479405,"diff":11396},{"start":1494397907479448,"end":1494397907491613,"diff":12165},{"start":1494397907491656,"end":1494397907503158,"diff":11502},{"start":1494397907503184,"end":1494397907514812,"diff":11628},{"start":1494397907514834,"end":1494397907526469,"diff":11635},{"start":1494397907543128,"end":1494397907555400,"diff":12272},{"start":1494397907555502,"end":1494397907566988,"diff":11486},{"start":1494397907567013,"end":1494397907578682,"diff":11669},{"start":1494397907578721,"end":1494397907588576,"diff":9855},{"start":1494397907588597,"end":1494397907599324,"diff":10727},{"start":1494397907617211,"end":1494397907629975,"diff":12764},{"start":1494397907630049,"end":1494397907642572,"diff":12523},{"start":1494397907642594,"end":1494397907654142,"diff":11548},{"start":1494397907654184,"end":1494397907665712,"diff":11528},{"start":1494397907665737,"end":1494397907677443,"diff":11706},{"start":1494397907693879,"end":1494397907706370,"diff":12491},{"start":1494397907706509,"end":1494397907719297,"diff":12788},{"start":1494397907719335,"end":1494397907729713,"diff":10378},{"start":1494397907729734,"end":1494397907741156,"diff":11422},{"start":1494397907741180,"end":1494397907752947,"diff":11767},{"start":1494397907773209,"end":1494397907785755,"diff":12546},{"start":1494397907785789,"end":1494397907796690,"diff":10901},{"start":1494397907796714,"end":1494397907809503,"diff":12789},{"start":1494397907809542,"end":1494397907822362,"diff":12820},{"start":1494397907822387,"end":1494397907834230,"diff":11843},{"start":1494397907850247,"end":1494397907860694,"diff":10447},{"start":1494397907860714,"end":1494397907873291,"diff":12577},{"start":1494397907873302,"end":1494397907884559,"diff":11257},{"start":1494397907884567,"end":1494397907896035,"diff":11468},{"start":1494397907896058,"end":1494397907908651,"diff":12593},{"start":1494397907928328,"end":1494397907938529,"diff":10201},{"start":1494397907938574,"end":1494397907949381,"diff":10807},{"start":1494397907949460,"end":1494397907962269,"diff":12809},{"start":1494397907962311,"end":1494397907973575,"diff":11264},{"start":1494397907973597,"end":1494397907984636,"diff":11039},{"start":1494397908001302,"end":1494397908013981,"diff":12679},{"start":1494397908014037,"end":1494397908025698,"diff":11661},{"start":1494397908025722,"end":1494397908037344,"diff":11622},{"start":1494397908037364,"end":1494397908049280,"diff":11916},{"start":1494397908049302,"end":1494397908060471,"diff":11169},{"start":1494397908077350,"end":1494397908088583,"diff":11233},{"start":1494397908088643,"end":1494397908100988,"diff":12345},{"start":1494397908101030,"end":1494397908112993,"diff":11963},{"start":1494397908113025,"end":1494397908124376,"diff":11351},{"start":1494397908124412,"end":1494397908135936,"diff":11524},{"start":1494397908152151,"end":1494397908163246,"diff":11095},{"start":1494397908163307,"end":1494397908176086,"diff":12779},{"start":1494397908176127,"end":1494397908188499,"diff":12372},{"start":1494397908188520,"end":1494397908200023,"diff":11503},{"start":1494397908200046,"end":1494397908211662,"diff":11616},{"start":1494397908228862,"end":1494397908240358,"diff":11496},{"start":1494397908240417,"end":1494397908251975,"diff":11558},{"start":1494397908252067,"end":1494397908263274,"diff":11207},{"start":1494397908263363,"end":1494397908275248,"diff":11885},{"start":1494397908275301,"end":1494397908286836,"diff":11535},{"start":1494397908304442,"end":1494397908315888,"diff":11446},{"start":1494397908315942,"end":1494397908328695,"diff":12753},{"start":1494397908328760,"end":1494397908339673,"diff":10913},{"start":1494397908339706,"end":1494397908348900,"diff":9194},{"start":1494397908348954,"end":1494397908359189,"diff":10235},{"start":1494397908378225,"end":1494397908388355,"diff":10130},{"start":1494397908388384,"end":1494397908399946,"diff":11562},{"start":1494397908399957,"end":1494397908411573,"diff":11616},{"start":1494397908411595,"end":1494397908424329,"diff":12734},{"start":1494397908424352,"end":1494397908434871,"diff":10519},{"start":1494397908452753,"end":1494397908463097,"diff":10344},{"start":1494397908463148,"end":1494397908475883,"diff":12735},{"start":1494397908475906,"end":1494397908488454,"diff":12548},{"start":1494397908488477,"end":1494397908501124,"diff":12647},{"start":1494397908501147,"end":1494397908513230,"diff":12083},{"start":1494397908531395,"end":1494397908542192,"diff":10797},{"start":1494397908542288,"end":1494397908553797,"diff":11509},{"start":1494397908553823,"end":1494397908565378,"diff":11555},{"start":1494397908565398,"end":1494397908577183,"diff":11785},{"start":1494397908577208,"end":1494397908588522,"diff":11314},{"start":1494397908607616,"end":1494397908618092,"diff":10476},{"start":1494397908618136,"end":1494397908628541,"diff":10405},{"start":1494397908628565,"end":1494397908638711,"diff":10146},{"start":1494397908638732,"end":1494397908649213,"diff":10481},{"start":1494397908649234,"end":1494397908660876,"diff":11642},{"start":1494397908679029,"end":1494397908690589,"diff":11560},{"start":1494397908690634,"end":1494397908703391,"diff":12757},{"start":1494397908703413,"end":1494397908714557,"diff":11144},{"start":1494397908714578,"end":1494397908724808,"diff":10230},{"start":1494397908724827,"end":1494397908737538,"diff":12711},{"start":1494397908755981,"end":1494397908768757,"diff":12776},{"start":1494397908768795,"end":1494397908779988,"diff":11193},{"start":1494397908780009,"end":1494397908791013,"diff":11004},{"start":1494397908791034,"end":1494397908803612,"diff":12578},{"start":1494397908803634,"end":1494397908816397,"diff":12763},{"start":1494397908833213,"end":1494397908844220,"diff":11007},{"start":1494397908844260,"end":1494397908855729,"diff":11469},{"start":1494397908855749,"end":1494397908867337,"diff":11588},{"start":1494397908867356,"end":1494397908877830,"diff":10474},{"start":1494397908877850,"end":1494397908888509,"diff":10659},{"start":1494397908906273,"end":1494397908919029,"diff":12756},{"start":1494397908919103,"end":1494397908929697,"diff":10594},{"start":1494397908929716,"end":1494397908941188,"diff":11472},{"start":1494397908941225,"end":1494397908951599,"diff":10374},{"start":1494397908951622,"end":1494397908962351,"diff":10729}],"now":1494397908969,"mem":{"start":{"process":{"rss":53481472,"heapTotal":30670848,"heapUsed":24698264,"external":1891128},"os":353452032},"end":{"process":{"rss":51159040,"heapTotal":24924160,"heapUsed":18563640,"external":17476},"os":342634496}},"stats":{"moe":0.0002405410466237888,"rme":2.0727179201337336,"sem":0.00012272502378764735,"deviation":0.0010769077131784566,"mean":0.01160510285974026,"sample":[0.011467463,0.0116833162,0.0110667986,0.0114649296,0.0106894188,0.0113355634,0.011706378600000001,0.012012353,0.010710911600000001,0.011895782,0.011171711400000001,0.0114941526,0.0118087994,0.011764206000000001,0.0122733626,0.0120636172,0.011644141399999999,0.0109948232,0.0106830832,0.0112067242,0.0110229152,0.010528214800000001,0.0112750804,0.0116450236,0.010590902400000001,0.0117883798,0.0111215244,0.010934747,0.0108886886,0.011212129999999999,0.011645420600000001,0.0113731656,0.0107421604,0.0113989206,0.012110639,0.011928167600000001,0.0112285916,0.0111169406,0.0115185852,0.011128334600000001,0.0114127614,0.0119272068,0.011207295,0.0112760802,0.012035436600000001,0.0117016614,0.0117024192,0.012397311599999999,0.0118235306,0.0200884698,0.0113174864,0.011727395,0.012470336,0.0117018898,0.0109666452,0.0117500418,0.0117435844,0.011707255199999999,0.011253771999999999,0.0120616948,0.0118412792,0.012220146599999999,0.0116964134,0.011278997,0.011853991599999999,0.011737397600000001,0.011917730999999999,0.011631884,0.0109658168,0.0113459804,0.0121109982,0.0114423954,0.010815898000000001,0.0117182946,0.0121013318,0.0110752382,0.0112307852],"variance":0.000001159730222703253},"count":5,"hz":86.16899066609234,"time":11.60510285974026,"cycles":2,"battery":{"amperage":-2155,"currentCapacity":3701,"percent":49,"charging":"","temp":3105}}]}}
\ No newline at end of file
diff --git a/_modules/bench-chain/example/math/async-first-slower.js b/_modules/bench-chain/example/math/async-first-slower.js
new file mode 100644
index 0000000..0cef051
--- /dev/null
+++ b/_modules/bench-chain/example/math/async-first-slower.js
@@ -0,0 +1,18 @@
+const Bench = require('../../')
+
+const sleep = sleepDuration =>
+ new Promise(resolve => setTimeout(resolve, sleepDuration))
+
+/* prettier-ignore */
+
+Bench
+ .init().dir(__dirname).filename('async-first-faster2.json').setup()
+ .addAsync('snail2', async done => {
+ await sleep(200)
+ done()
+ })
+ .addAsync('zoomzoom2', async done => {
+ await sleep(10)
+ done()
+ })
+ .run()
diff --git a/_modules/bench-chain/example/math/sync-first-faster.js b/_modules/bench-chain/example/math/sync-first-faster.js
new file mode 100644
index 0000000..bfda968
--- /dev/null
+++ b/_modules/bench-chain/example/math/sync-first-faster.js
@@ -0,0 +1,8 @@
+const Bench = require('../../src')
+const sleepfor = require('sleepfor')
+
+Bench
+ .init(__dirname, 'sync-first-faster.json')
+ .add('zoomzoom', () => sleepfor(100))
+ .add('snail', () => sleepfor(500))
+ .run()
diff --git a/_modules/bench-chain/example/math/sync-first-faster.json b/_modules/bench-chain/example/math/sync-first-faster.json
new file mode 100644
index 0000000..c5ee440
--- /dev/null
+++ b/_modules/bench-chain/example/math/sync-first-faster.json
@@ -0,0 +1 @@
+{"/Users/james/code/fluents/chain/packages/bench-chain/example/math/sync-first-faster.json":{"zoomzoom":[{"msg":"zoomzoom x 10.03 ops/sec ±0.18% (29 runs sampled)","name":"zoomzoom","num":10.03,"sampled":"29","variation":"0.18","suite":["/Users/james/code/fluents/chain/packages/bench-chain/example/math/sync-first-faster.json"],"now":1494398090943,"mem":{"start":{"process":{"rss":53407744,"heapTotal":31719424,"heapUsed":24997208,"external":1893643},"os":211357696},"end":{"process":{"rss":63188992,"heapTotal":39079936,"heapUsed":22984568,"external":17476},"os":287350784}},"stats":{"moe":0.0001756264341796521,"rme":0.17623166464090306,"sem":0.00008575509481428325,"deviation":0.00046180531862636073,"mean":0.09965657110344829,"sample":[0.09917288,0.099718128,0.099461828,0.099784339,0.099788851,0.099922661,0.099870881,0.099530785,0.099529751,0.099289762,0.099316205,0.099404772,0.099486586,0.099422594,0.099363384,0.099639294,0.09970661,0.10176276,0.099904979,0.099580911,0.09998626,0.099473089,0.099432233,0.099477917,0.099328752,0.099590258,0.099565374,0.100043266,0.099485452],"variance":2.1326415231159453e-7},"count":1,"hz":10.034461239509758,"time":99.65657110344829,"cycles":1,"battery":{"amperage":-2291,"currentCapacity":3584,"percent":47,"charging":"","temp":3105}},{"msg":"zoomzoom x 10.03 ops/sec ±0.18% (29 runs sampled)","name":"zoomzoom","num":10.03,"sampled":"29","variation":"0.18","suite":["/Users/james/code/fluents/chain/packages/bench-chain/example/math/sync-first-faster.json"],"now":1494398090944,"mem":{"start":{"process":{"rss":53407744,"heapTotal":31719424,"heapUsed":24997208,"external":1893643},"os":211357696},"end":{"process":{"rss":63209472,"heapTotal":39079936,"heapUsed":23012752,"external":17476},"os":287350784}},"stats":{"moe":0.0001756264341796521,"rme":0.17623166464090306,"sem":0.00008575509481428325,"deviation":0.00046180531862636073,"mean":0.09965657110344829,"sample":[0.09917288,0.099718128,0.099461828,0.099784339,0.099788851,0.099922661,0.099870881,0.099530785,0.099529751,0.099289762,0.099316205,0.099404772,0.099486586,0.099422594,0.099363384,0.099639294,0.09970661,0.10176276,0.099904979,0.099580911,0.09998626,0.099473089,0.099432233,0.099477917,0.099328752,0.099590258,0.099565374,0.100043266,0.099485452],"variance":2.1326415231159453e-7},"count":1,"hz":10.034461239509758,"time":99.65657110344829,"cycles":1,"battery":{"amperage":-2291,"currentCapacity":3584,"percent":47,"charging":"","temp":3105}}],"snail":[{"msg":"snail x 2.00 ops/sec ±0.02% (9 runs sampled)","name":"snail","num":2,"sampled":"9","variation":"0.02","suite":["/Users/james/code/fluents/chain/packages/bench-chain/example/math/sync-first-faster.json"],"now":1494398099985,"mem":{"start":{"process":{"rss":53407744,"heapTotal":31719424,"heapUsed":24997208,"external":1893643},"os":211357696},"end":{"process":{"rss":65032192,"heapTotal":40652800,"heapUsed":29569136,"external":17476},"os":275374080}},"stats":{"moe":0.0000933408466204728,"rme":0.018692234687334896,"sem":0.00004047738361685724,"deviation":0.00012143215085057171,"mean":0.4993562737777778,"sample":[0.499362578,0.499280663,0.49940961,0.499284253,0.499116236,0.499528611,0.499482813,0.499385381,0.499356319],"variance":1.4745767260196003e-8},"count":1,"hz":2.002578224229976,"time":499.3562737777778,"cycles":1,"battery":{"amperage":-2291,"currentCapacity":3584,"percent":47,"charging":"","temp":3105}},{"msg":"snail x 2.00 ops/sec ±0.02% (9 runs sampled)","name":"snail","num":2,"sampled":"9","variation":"0.02","suite":["/Users/james/code/fluents/chain/packages/bench-chain/example/math/sync-first-faster.json"],"now":1494398099985,"mem":{"start":{"process":{"rss":53407744,"heapTotal":31719424,"heapUsed":24997208,"external":1893643},"os":211357696},"end":{"process":{"rss":65032192,"heapTotal":40652800,"heapUsed":29573328,"external":17476},"os":275374080}},"stats":{"moe":0.0000933408466204728,"rme":0.018692234687334896,"sem":0.00004047738361685724,"deviation":0.00012143215085057171,"mean":0.4993562737777778,"sample":[0.499362578,0.499280663,0.49940961,0.499284253,0.499116236,0.499528611,0.499482813,0.499385381,0.499356319],"variance":1.4745767260196003e-8},"count":1,"hz":2.002578224229976,"time":499.3562737777778,"cycles":1,"battery":{"amperage":-2291,"currentCapacity":3584,"percent":47,"charging":"","temp":3105}}]}}
\ No newline at end of file
diff --git a/_modules/bench-chain/example/math/sync-first-slower.js b/_modules/bench-chain/example/math/sync-first-slower.js
new file mode 100644
index 0000000..eaa2d12
--- /dev/null
+++ b/_modules/bench-chain/example/math/sync-first-slower.js
@@ -0,0 +1,8 @@
+const Bench = require('../../src')
+const sleepfor = require('sleepfor')
+
+Bench
+ .init(__dirname, 'sync-first-slower.json')
+ .add('snail2', () => sleepfor(500))
+ .add('zoomzoom2', () => sleepfor(100))
+ .run()
diff --git a/_modules/bench-chain/example/math/sync-first-slower.json b/_modules/bench-chain/example/math/sync-first-slower.json
new file mode 100644
index 0000000..de93a24
--- /dev/null
+++ b/_modules/bench-chain/example/math/sync-first-slower.json
@@ -0,0 +1 @@
+{"/Users/james/code/fluents/chain/packages/bench-chain/example/math/sync-first-slower.json":{"snail2":[{"msg":"snail2 x 2.00 ops/sec ±0.03% (9 runs sampled)","name":"snail2","num":2,"sampled":"9","variation":"0.03","suite":["/Users/james/code/fluents/chain/packages/bench-chain/example/math/sync-first-slower.json"],"now":1494398037932,"mem":{"start":{"process":{"rss":53608448,"heapTotal":31195136,"heapUsed":24721088,"external":1892228},"os":213823488},"end":{"process":{"rss":60743680,"heapTotal":36970496,"heapUsed":22395592,"external":17476},"os":207986688}},"stats":{"moe":0.00015917183559726564,"rme":0.03187108257825342,"sem":0.00006902508048450374,"deviation":0.00020707524145351122,"mean":0.4994240004444445,"sample":[0.499256347,0.499852198,0.499479212,0.499504112,0.499349806,0.499117224,0.499401758,0.499532497,0.49932285],"variance":4.288015562302997e-8},"count":1,"hz":2.002306655487293,"time":499.4240004444445,"cycles":1,"battery":{"amperage":-2172,"currentCapacity":3603,"percent":48,"charging":"","temp":3105}},{"msg":"snail2 x 2.00 ops/sec ±0.03% (9 runs sampled)","name":"snail2","num":2,"sampled":"9","variation":"0.03","suite":["/Users/james/code/fluents/chain/packages/bench-chain/example/math/sync-first-slower.json"],"now":1494398037933,"mem":{"start":{"process":{"rss":53608448,"heapTotal":31195136,"heapUsed":24721088,"external":1892228},"os":213823488},"end":{"process":{"rss":60755968,"heapTotal":36970496,"heapUsed":22421624,"external":17476},"os":207986688}},"stats":{"moe":0.00015917183559726564,"rme":0.03187108257825342,"sem":0.00006902508048450374,"deviation":0.00020707524145351122,"mean":0.4994240004444445,"sample":[0.499256347,0.499852198,0.499479212,0.499504112,0.499349806,0.499117224,0.499401758,0.499532497,0.49932285],"variance":4.288015562302997e-8},"count":1,"hz":2.002306655487293,"time":499.4240004444445,"cycles":1,"battery":{"amperage":-2172,"currentCapacity":3603,"percent":48,"charging":"","temp":3105}},{"msg":"snail2 x 2.00 ops/sec ±0.05% (9 runs sampled)","name":"snail2","num":2,"sampled":"9","variation":"0.05","suite":["/Users/james/code/fluents/chain/packages/bench-chain/example/math/sync-first-slower.json"],"now":1494398066060,"mem":{"start":{"process":{"rss":53088256,"heapTotal":31195136,"heapUsed":24721552,"external":1893258},"os":219308032},"end":{"process":{"rss":60715008,"heapTotal":36970496,"heapUsed":23660920,"external":17476},"os":209563648}},"stats":{"moe":0.00026640449116475907,"rme":0.05333762576115023,"sem":0.00011552666572626152,"deviation":0.00034657999717878455,"mean":0.4994682222222222,"sample":[0.499425,0.49921,0.499122,0.499895,0.499139,0.499063,0.499804,0.499697,0.499859],"variance":1.201176944444463e-7},"count":1,"hz":2.002129375820595,"time":499.4682222222222,"cycles":1,"battery":{"amperage":-2172,"currentCapacity":3603,"percent":48,"charging":"","temp":3105}},{"msg":"snail2 x 2.00 ops/sec ±0.05% (9 runs sampled)","name":"snail2","num":2,"sampled":"9","variation":"0.05","suite":["/Users/james/code/fluents/chain/packages/bench-chain/example/math/sync-first-slower.json"],"now":1494398066061,"mem":{"start":{"process":{"rss":53088256,"heapTotal":31195136,"heapUsed":24721552,"external":1893258},"os":219308032},"end":{"process":{"rss":60719104,"heapTotal":36970496,"heapUsed":23686968,"external":17476},"os":209563648}},"stats":{"moe":0.00026640449116475907,"rme":0.05333762576115023,"sem":0.00011552666572626152,"deviation":0.00034657999717878455,"mean":0.4994682222222222,"sample":[0.499425,0.49921,0.499122,0.499895,0.499139,0.499063,0.499804,0.499697,0.499859],"variance":1.201176944444463e-7},"count":1,"hz":2.002129375820595,"time":499.4682222222222,"cycles":1,"battery":{"amperage":-2172,"currentCapacity":3603,"percent":48,"charging":"","temp":3105}}],"zoomzoom2":[{"msg":"zoomzoom2 x 10.06 ops/sec ±0.09% (29 runs sampled)","name":"zoomzoom2","num":10.06,"sampled":"29","variation":"0.09","suite":["/Users/james/code/fluents/chain/packages/bench-chain/example/math/sync-first-slower.json"],"now":1494398043871,"mem":{"start":{"process":{"rss":53608448,"heapTotal":31195136,"heapUsed":24721088,"external":1892228},"os":213823488},"end":{"process":{"rss":65261568,"heapTotal":40652800,"heapUsed":27150520,"external":17476},"os":216920064}},"stats":{"moe":0.00009440691239476765,"rme":0.09494465525142698,"sem":0.00004609712519275764,"deviation":0.00024824061629811177,"mean":0.0994336249310345,"sample":[0.099798668,0.099333249,0.099971879,0.099076745,0.099126853,0.099394136,0.0994742,0.099729226,0.099304444,0.099386002,0.099480545,0.099408116,0.099351707,0.099314703,0.099458439,0.099513617,0.099174448,0.09986394,0.099768558,0.099384653,0.099972115,0.099238718,0.099407537,0.099290887,0.099085473,0.099154163,0.0994071,0.099324562,0.09938044],"variance":6.162340358006635e-8},"count":1,"hz":10.056960114785952,"time":99.4336249310345,"cycles":1,"battery":{"amperage":-2172,"currentCapacity":3603,"percent":48,"charging":"","temp":3105}},{"msg":"zoomzoom2 x 10.06 ops/sec ±0.09% (29 runs sampled)","name":"zoomzoom2","num":10.06,"sampled":"29","variation":"0.09","suite":["/Users/james/code/fluents/chain/packages/bench-chain/example/math/sync-first-slower.json"],"now":1494398043871,"mem":{"start":{"process":{"rss":53608448,"heapTotal":31195136,"heapUsed":24721088,"external":1892228},"os":213823488},"end":{"process":{"rss":65261568,"heapTotal":40652800,"heapUsed":27157328,"external":17476},"os":216920064}},"stats":{"moe":0.00009440691239476765,"rme":0.09494465525142698,"sem":0.00004609712519275764,"deviation":0.00024824061629811177,"mean":0.0994336249310345,"sample":[0.099798668,0.099333249,0.099971879,0.099076745,0.099126853,0.099394136,0.0994742,0.099729226,0.099304444,0.099386002,0.099480545,0.099408116,0.099351707,0.099314703,0.099458439,0.099513617,0.099174448,0.09986394,0.099768558,0.099384653,0.099972115,0.099238718,0.099407537,0.099290887,0.099085473,0.099154163,0.0994071,0.099324562,0.09938044],"variance":6.162340358006635e-8},"count":1,"hz":10.056960114785952,"time":99.4336249310345,"cycles":1,"battery":{"amperage":-2172,"currentCapacity":3603,"percent":48,"charging":"","temp":3105}},{"msg":"zoomzoom2 x 10.05 ops/sec ±0.07% (29 runs sampled)","name":"zoomzoom2","num":10.05,"sampled":"29","variation":"0.07","suite":["/Users/james/code/fluents/chain/packages/bench-chain/example/math/sync-first-slower.json"],"now":1494398071994,"mem":{"start":{"process":{"rss":53088256,"heapTotal":31195136,"heapUsed":24721552,"external":1893258},"os":219308032},"end":{"process":{"rss":65036288,"heapTotal":40652800,"heapUsed":28191944,"external":17476},"os":210321408}},"stats":{"moe":0.00007104808412891208,"rme":0.07142273330790512,"sem":0.00003469144732857035,"deviation":0.00018681916126237733,"mean":0.09947544827586208,"sample":[0.09942,0.099502,0.099557,0.09926,0.09936,0.09935,0.099524,0.099178,0.099507,0.099423,0.099486,0.099425,0.099456,0.099451,0.099505,0.099197,0.099927,0.099524,0.099975,0.099278,0.099851,0.099573,0.099331,0.099352,0.099327,0.099527,0.099553,0.099519,0.09945],"variance":3.4901399014778145e-8},"count":1,"hz":10.052731777863745,"time":99.47544827586208,"cycles":1,"battery":{"amperage":-2172,"currentCapacity":3603,"percent":48,"charging":"","temp":3105}},{"msg":"zoomzoom2 x 10.05 ops/sec ±0.07% (29 runs sampled)","name":"zoomzoom2","num":10.05,"sampled":"29","variation":"0.07","suite":["/Users/james/code/fluents/chain/packages/bench-chain/example/math/sync-first-slower.json"],"now":1494398071994,"mem":{"start":{"process":{"rss":53088256,"heapTotal":31195136,"heapUsed":24721552,"external":1893258},"os":219308032},"end":{"process":{"rss":65036288,"heapTotal":40652800,"heapUsed":28198720,"external":17476},"os":210321408}},"stats":{"moe":0.00007104808412891208,"rme":0.07142273330790512,"sem":0.00003469144732857035,"deviation":0.00018681916126237733,"mean":0.09947544827586208,"sample":[0.09942,0.099502,0.099557,0.09926,0.09936,0.09935,0.099524,0.099178,0.099507,0.099423,0.099486,0.099425,0.099456,0.099451,0.099505,0.099197,0.099927,0.099524,0.099975,0.099278,0.099851,0.099573,0.099331,0.099352,0.099327,0.099527,0.099553,0.099519,0.09945],"variance":3.4901399014778145e-8},"count":1,"hz":10.052731777863745,"time":99.47544827586208,"cycles":1,"battery":{"amperage":-2172,"currentCapacity":3603,"percent":48,"charging":"","temp":3105}}]}}
\ No newline at end of file
diff --git a/_modules/bench-chain/example/single.js b/_modules/bench-chain/example/single.js
new file mode 100644
index 0000000..23766a0
--- /dev/null
+++ b/_modules/bench-chain/example/single.js
@@ -0,0 +1,14 @@
+const Bench = require('../')
+
+const sleep = sleepDuration =>
+ new Promise(resolve => setTimeout(resolve, sleepDuration))
+
+/* prettier-ignore */
+
+Bench
+ .init(__dirname, 'single1')
+ .addAsync('single1', async done => {
+ await sleep(100)
+ done()
+ })
+ .run()
diff --git a/_modules/bench-chain/example/single1.json b/_modules/bench-chain/example/single1.json
new file mode 100644
index 0000000..ae2de07
--- /dev/null
+++ b/_modules/bench-chain/example/single1.json
@@ -0,0 +1 @@
+{"/Users/james/code/fluents/chain/packages/bench-chain/example/single1.json":{"single1":[{"msg":"single1 x 9.73 ops/sec ±0.43% (49 runs sampled)","name":"single1","num":9.73,"sampled":"49","variation":"0.43","suite":["/Users/james/code/fluents/chain/packages/bench-chain/example/single1.json"],"timesFor":[{"start":1494206011967450,"end":1494206012070867,"diff":103417},{"start":1494206012095629,"end":1494206012199645,"diff":104016},{"start":1494206012222782,"end":1494206012323276,"diff":100494},{"start":1494206012344089,"end":1494206012447039,"diff":102950},{"start":1494206012464198,"end":1494206012567247,"diff":103049},{"start":1494206012584489,"end":1494206012687756,"diff":103267},{"start":1494206012709517,"end":1494206012814062,"diff":104545},{"start":1494206012835645,"end":1494206012937788,"diff":102143},{"start":1494206012955886,"end":1494206013058664,"diff":102778},{"start":1494206013077758,"end":1494206013182286,"diff":104528},{"start":1494206013200540,"end":1494206013302375,"diff":101835},{"start":1494206013319306,"end":1494206013419781,"diff":100475},{"start":1494206013439498,"end":1494206013543903,"diff":104405},{"start":1494206013560606,"end":1494206013661283,"diff":100677},{"start":1494206013677980,"end":1494206013782572,"diff":104592},{"start":1494206013800742,"end":1494206013901117,"diff":100375},{"start":1494206013919344,"end":1494206014022886,"diff":103542},{"start":1494206014043933,"end":1494206014146962,"diff":103029},{"start":1494206014162855,"end":1494206014264289,"diff":101434},{"start":1494206014281862,"end":1494206014385592,"diff":103730},{"start":1494206014406420,"end":1494206014507982,"diff":101562},{"start":1494206014524055,"end":1494206014625833,"diff":101778},{"start":1494206014642841,"end":1494206014747007,"diff":104166},{"start":1494206014763524,"end":1494206014864431,"diff":100907},{"start":1494206014882265,"end":1494206014985585,"diff":103320},{"start":1494206015004298,"end":1494206015107981,"diff":103683},{"start":1494206015124042,"end":1494206015224602,"diff":100560},{"start":1494206015244223,"end":1494206015346939,"diff":102716},{"start":1494206015362935,"end":1494206015464797,"diff":101862},{"start":1494206015484735,"end":1494206015587601,"diff":102866},{"start":1494206015607428,"end":1494206015708080,"diff":100652},{"start":1494206015724925,"end":1494206015825803,"diff":100878},{"start":1494206015842601,"end":1494206015946860,"diff":104259},{"start":1494206015962806,"end":1494206016067283,"diff":104477},{"start":1494206016085284,"end":1494206016187548,"diff":102264},{"start":1494206016204379,"end":1494206016309107,"diff":104728},{"start":1494206016326136,"end":1494206016431247,"diff":105111},{"start":1494206016448613,"end":1494206016548570,"diff":99957},{"start":1494206016567663,"end":1494206016669935,"diff":102272},{"start":1494206016684199,"end":1494206016785663,"diff":101464},{"start":1494206016802914,"end":1494206016903306,"diff":100392},{"start":1494206016920750,"end":1494206017025743,"diff":104993},{"start":1494206017042200,"end":1494206017146768,"diff":104568},{"start":1494206017162547,"end":1494206017264092,"diff":101545},{"start":1494206017284681,"end":1494206017387539,"diff":102858},{"start":1494206017404623,"end":1494206017505002,"diff":100379},{"start":1494206017521791,"end":1494206017625724,"diff":103933},{"start":1494206017642597,"end":1494206017747408,"diff":104811},{"start":1494206017763320,"end":1494206017864005,"diff":100685}],"now":1494206017870,"mem":{"start":{"process":{"rss":51118080,"heapTotal":29458432,"heapUsed":22047456,"external":123168},"os":588464128},"end":{"process":{"rss":61685760,"heapTotal":41177088,"heapUsed":26962864,"external":25668},"os":599629824}},"stats":{"moe":0.0004371697963477016,"rme":0.42554409308401864,"sem":0.00022304581446311306,"deviation":0.0015613207012417914,"mean":0.10273196208163266,"sample":[0.103677747,0.104264315,0.100703133,0.103096341,0.10317092,0.103408632,0.104624792,0.10225705,0.102852184,0.104595853,0.101912681,0.100600109,0.104495387,0.100756113,0.104679206,0.100512645,0.103641545,0.103107847,0.101513813,0.103806441,0.101636023,0.10190455,0.104250925,0.100975376,0.103405061,0.10376532,0.100693533,0.102791744,0.101943484,0.102989622,0.100735322,0.100956742,0.104335297,0.104572249,0.102345036,0.104815557,0.105197974,0.100038977,0.1023407,0.101544017,0.100478794,0.105076949,0.104644538,0.101628522,0.102996788,0.100461659,0.104013871,0.104893119,0.100757639],"variance":0.0000024377223321261593},"count":1,"hz":9.734068927890057,"time":102.73196208163266,"cycles":1,"battery":{"amperage":4483,"currentCapacity":925,"percent":12,"charging":"","temp":3104}},{"msg":"single1 x 9.73 ops/sec ±0.43% (49 runs sampled)","name":"single1","num":9.73,"sampled":"49","variation":"0.43","suite":["/Users/james/code/fluents/chain/packages/bench-chain/example/single1.json"],"timesFor":[{"start":1494206011967450,"end":1494206012070867,"diff":103417},{"start":1494206012095629,"end":1494206012199645,"diff":104016},{"start":1494206012222782,"end":1494206012323276,"diff":100494},{"start":1494206012344089,"end":1494206012447039,"diff":102950},{"start":1494206012464198,"end":1494206012567247,"diff":103049},{"start":1494206012584489,"end":1494206012687756,"diff":103267},{"start":1494206012709517,"end":1494206012814062,"diff":104545},{"start":1494206012835645,"end":1494206012937788,"diff":102143},{"start":1494206012955886,"end":1494206013058664,"diff":102778},{"start":1494206013077758,"end":1494206013182286,"diff":104528},{"start":1494206013200540,"end":1494206013302375,"diff":101835},{"start":1494206013319306,"end":1494206013419781,"diff":100475},{"start":1494206013439498,"end":1494206013543903,"diff":104405},{"start":1494206013560606,"end":1494206013661283,"diff":100677},{"start":1494206013677980,"end":1494206013782572,"diff":104592},{"start":1494206013800742,"end":1494206013901117,"diff":100375},{"start":1494206013919344,"end":1494206014022886,"diff":103542},{"start":1494206014043933,"end":1494206014146962,"diff":103029},{"start":1494206014162855,"end":1494206014264289,"diff":101434},{"start":1494206014281862,"end":1494206014385592,"diff":103730},{"start":1494206014406420,"end":1494206014507982,"diff":101562},{"start":1494206014524055,"end":1494206014625833,"diff":101778},{"start":1494206014642841,"end":1494206014747007,"diff":104166},{"start":1494206014763524,"end":1494206014864431,"diff":100907},{"start":1494206014882265,"end":1494206014985585,"diff":103320},{"start":1494206015004298,"end":1494206015107981,"diff":103683},{"start":1494206015124042,"end":1494206015224602,"diff":100560},{"start":1494206015244223,"end":1494206015346939,"diff":102716},{"start":1494206015362935,"end":1494206015464797,"diff":101862},{"start":1494206015484735,"end":1494206015587601,"diff":102866},{"start":1494206015607428,"end":1494206015708080,"diff":100652},{"start":1494206015724925,"end":1494206015825803,"diff":100878},{"start":1494206015842601,"end":1494206015946860,"diff":104259},{"start":1494206015962806,"end":1494206016067283,"diff":104477},{"start":1494206016085284,"end":1494206016187548,"diff":102264},{"start":1494206016204379,"end":1494206016309107,"diff":104728},{"start":1494206016326136,"end":1494206016431247,"diff":105111},{"start":1494206016448613,"end":1494206016548570,"diff":99957},{"start":1494206016567663,"end":1494206016669935,"diff":102272},{"start":1494206016684199,"end":1494206016785663,"diff":101464},{"start":1494206016802914,"end":1494206016903306,"diff":100392},{"start":1494206016920750,"end":1494206017025743,"diff":104993},{"start":1494206017042200,"end":1494206017146768,"diff":104568},{"start":1494206017162547,"end":1494206017264092,"diff":101545},{"start":1494206017284681,"end":1494206017387539,"diff":102858},{"start":1494206017404623,"end":1494206017505002,"diff":100379},{"start":1494206017521791,"end":1494206017625724,"diff":103933},{"start":1494206017642597,"end":1494206017747408,"diff":104811},{"start":1494206017763320,"end":1494206017864005,"diff":100685}],"now":1494206017871,"mem":{"start":{"process":{"rss":51118080,"heapTotal":29458432,"heapUsed":22047456,"external":123168},"os":588464128},"end":{"process":{"rss":61710336,"heapTotal":41177088,"heapUsed":26990864,"external":25668},"os":599629824}},"stats":{"moe":0.0004371697963477016,"rme":0.42554409308401864,"sem":0.00022304581446311306,"deviation":0.0015613207012417914,"mean":0.10273196208163266,"sample":[0.103677747,0.104264315,0.100703133,0.103096341,0.10317092,0.103408632,0.104624792,0.10225705,0.102852184,0.104595853,0.101912681,0.100600109,0.104495387,0.100756113,0.104679206,0.100512645,0.103641545,0.103107847,0.101513813,0.103806441,0.101636023,0.10190455,0.104250925,0.100975376,0.103405061,0.10376532,0.100693533,0.102791744,0.101943484,0.102989622,0.100735322,0.100956742,0.104335297,0.104572249,0.102345036,0.104815557,0.105197974,0.100038977,0.1023407,0.101544017,0.100478794,0.105076949,0.104644538,0.101628522,0.102996788,0.100461659,0.104013871,0.104893119,0.100757639],"variance":0.0000024377223321261593},"count":1,"hz":9.734068927890057,"time":102.73196208163266,"cycles":1,"battery":{"amperage":4483,"currentCapacity":925,"percent":12,"charging":"","temp":3104}},{"msg":"single1 x 9.73 ops/sec ±0.43% (49 runs sampled)","name":"single1","num":9.73,"sampled":"49","variation":"0.43","suite":["/Users/james/code/fluents/chain/packages/bench-chain/example/single1.json"],"timesFor":[{"start":1494206023863390,"end":1494206023964911,"diff":101521},{"start":1494206023988565,"end":1494206024092032,"diff":103467},{"start":1494206024115674,"end":1494206024219022,"diff":103348},{"start":1494206024241989,"end":1494206024346648,"diff":104659},{"start":1494206024363939,"end":1494206024469395,"diff":105456},{"start":1494206024492130,"end":1494206024596859,"diff":104729},{"start":1494206024617856,"end":1494206024718972,"diff":101116},{"start":1494206024741438,"end":1494206024846253,"diff":104815},{"start":1494206024863365,"end":1494206024964995,"diff":101630},{"start":1494206024982248,"end":1494206025085521,"diff":103273},{"start":1494206025102259,"end":1494206025202203,"diff":99944},{"start":1494206025221370,"end":1494206025325424,"diff":104054},{"start":1494206025343927,"end":1494206025445225,"diff":101298},{"start":1494206025461013,"end":1494206025562369,"diff":101356},{"start":1494206025579566,"end":1494206025683537,"diff":103971},{"start":1494206025703510,"end":1494206025806357,"diff":102847},{"start":1494206025827317,"end":1494206025929479,"diff":102162},{"start":1494206025946945,"end":1494206026050303,"diff":103358},{"start":1494206026066683,"end":1494206026169360,"diff":102677},{"start":1494206026186766,"end":1494206026291323,"diff":104557},{"start":1494206026311528,"end":1494206026411851,"diff":100323},{"start":1494206026430700,"end":1494206026534671,"diff":103971},{"start":1494206026551732,"end":1494206026655768,"diff":104036},{"start":1494206026672978,"end":1494206026775360,"diff":102382},{"start":1494206026794368,"end":1494206026895212,"diff":100844},{"start":1494206026913391,"end":1494206027013122,"diff":99731},{"start":1494206027031834,"end":1494206027135427,"diff":103593},{"start":1494206027151893,"end":1494206027256008,"diff":104115},{"start":1494206027272138,"end":1494206027375377,"diff":103239},{"start":1494206027393920,"end":1494206027497665,"diff":103745},{"start":1494206027515731,"end":1494206027619736,"diff":104005},{"start":1494206027636846,"end":1494206027738116,"diff":101270},{"start":1494206027755000,"end":1494206027855712,"diff":100712},{"start":1494206027871970,"end":1494206027975322,"diff":103352},{"start":1494206027993883,"end":1494206028094744,"diff":100861},{"start":1494206028110764,"end":1494206028211346,"diff":100582},{"start":1494206028228727,"end":1494206028330875,"diff":102148},{"start":1494206028347612,"end":1494206028450611,"diff":102999},{"start":1494206028468151,"end":1494206028571062,"diff":102911},{"start":1494206028589691,"end":1494206028695083,"diff":105392},{"start":1494206028712510,"end":1494206028812729,"diff":100219},{"start":1494206028829446,"end":1494206028932656,"diff":103210},{"start":1494206028949803,"end":1494206029054200,"diff":104397},{"start":1494206029071657,"end":1494206029173660,"diff":102003},{"start":1494206029189794,"end":1494206029289969,"diff":100175},{"start":1494206029308710,"end":1494206029410153,"diff":101443},{"start":1494206029427359,"end":1494206029528033,"diff":100674},{"start":1494206029545903,"end":1494206029649994,"diff":104091},{"start":1494206029666607,"end":1494206029769242,"diff":102635}],"now":1494206029775,"mem":{"start":{"process":{"rss":51691520,"heapTotal":29458432,"heapUsed":22306952,"external":123168},"os":576430080},"end":{"process":{"rss":63619072,"heapTotal":41701376,"heapUsed":27995568,"external":25668},"os":536367104}},"stats":{"moe":0.00044088255543493163,"rme":0.4291368933469509,"sem":0.00022494007930353655,"deviation":0.001574580555124756,"mean":0.10273704318367347,"sample":[0.101770246,0.103720325,0.103471748,0.104795599,0.105535023,0.104817507,0.101192104,0.104893257,0.101705556,0.103360224,0.100034626,0.104180791,0.101420545,0.101441693,0.104061114,0.102967538,0.102234631,0.103439786,0.102758648,0.10463973,0.100407561,0.104109493,0.10416198,0.102468437,0.100942162,0.099806501,0.103722816,0.104194084,0.103317384,0.103823339,0.104090145,0.101395305,0.100796234,0.103431862,0.10093847,0.100657307,0.102213406,0.103078384,0.102997255,0.105477558,0.100301062,0.103332077,0.104490477,0.102099156,0.100259394,0.101521049,0.100743309,0.104187631,0.102710587],"variance":0.0000024793039245769844},"count":1,"hz":9.733587506623081,"time":102.73704318367346,"cycles":1,"battery":{"amperage":4483,"currentCapacity":925,"percent":12,"charging":"","temp":3104}},{"msg":"single1 x 9.73 ops/sec ±0.43% (49 runs sampled)","name":"single1","num":9.73,"sampled":"49","variation":"0.43","suite":["/Users/james/code/fluents/chain/packages/bench-chain/example/single1.json"],"timesFor":[{"start":1494206023863390,"end":1494206023964911,"diff":101521},{"start":1494206023988565,"end":1494206024092032,"diff":103467},{"start":1494206024115674,"end":1494206024219022,"diff":103348},{"start":1494206024241989,"end":1494206024346648,"diff":104659},{"start":1494206024363939,"end":1494206024469395,"diff":105456},{"start":1494206024492130,"end":1494206024596859,"diff":104729},{"start":1494206024617856,"end":1494206024718972,"diff":101116},{"start":1494206024741438,"end":1494206024846253,"diff":104815},{"start":1494206024863365,"end":1494206024964995,"diff":101630},{"start":1494206024982248,"end":1494206025085521,"diff":103273},{"start":1494206025102259,"end":1494206025202203,"diff":99944},{"start":1494206025221370,"end":1494206025325424,"diff":104054},{"start":1494206025343927,"end":1494206025445225,"diff":101298},{"start":1494206025461013,"end":1494206025562369,"diff":101356},{"start":1494206025579566,"end":1494206025683537,"diff":103971},{"start":1494206025703510,"end":1494206025806357,"diff":102847},{"start":1494206025827317,"end":1494206025929479,"diff":102162},{"start":1494206025946945,"end":1494206026050303,"diff":103358},{"start":1494206026066683,"end":1494206026169360,"diff":102677},{"start":1494206026186766,"end":1494206026291323,"diff":104557},{"start":1494206026311528,"end":1494206026411851,"diff":100323},{"start":1494206026430700,"end":1494206026534671,"diff":103971},{"start":1494206026551732,"end":1494206026655768,"diff":104036},{"start":1494206026672978,"end":1494206026775360,"diff":102382},{"start":1494206026794368,"end":1494206026895212,"diff":100844},{"start":1494206026913391,"end":1494206027013122,"diff":99731},{"start":1494206027031834,"end":1494206027135427,"diff":103593},{"start":1494206027151893,"end":1494206027256008,"diff":104115},{"start":1494206027272138,"end":1494206027375377,"diff":103239},{"start":1494206027393920,"end":1494206027497665,"diff":103745},{"start":1494206027515731,"end":1494206027619736,"diff":104005},{"start":1494206027636846,"end":1494206027738116,"diff":101270},{"start":1494206027755000,"end":1494206027855712,"diff":100712},{"start":1494206027871970,"end":1494206027975322,"diff":103352},{"start":1494206027993883,"end":1494206028094744,"diff":100861},{"start":1494206028110764,"end":1494206028211346,"diff":100582},{"start":1494206028228727,"end":1494206028330875,"diff":102148},{"start":1494206028347612,"end":1494206028450611,"diff":102999},{"start":1494206028468151,"end":1494206028571062,"diff":102911},{"start":1494206028589691,"end":1494206028695083,"diff":105392},{"start":1494206028712510,"end":1494206028812729,"diff":100219},{"start":1494206028829446,"end":1494206028932656,"diff":103210},{"start":1494206028949803,"end":1494206029054200,"diff":104397},{"start":1494206029071657,"end":1494206029173660,"diff":102003},{"start":1494206029189794,"end":1494206029289969,"diff":100175},{"start":1494206029308710,"end":1494206029410153,"diff":101443},{"start":1494206029427359,"end":1494206029528033,"diff":100674},{"start":1494206029545903,"end":1494206029649994,"diff":104091},{"start":1494206029666607,"end":1494206029769242,"diff":102635}],"now":1494206029775,"mem":{"start":{"process":{"rss":51691520,"heapTotal":29458432,"heapUsed":22306952,"external":123168},"os":576430080},"end":{"process":{"rss":63635456,"heapTotal":41701376,"heapUsed":28023584,"external":25668},"os":536367104}},"stats":{"moe":0.00044088255543493163,"rme":0.4291368933469509,"sem":0.00022494007930353655,"deviation":0.001574580555124756,"mean":0.10273704318367347,"sample":[0.101770246,0.103720325,0.103471748,0.104795599,0.105535023,0.104817507,0.101192104,0.104893257,0.101705556,0.103360224,0.100034626,0.104180791,0.101420545,0.101441693,0.104061114,0.102967538,0.102234631,0.103439786,0.102758648,0.10463973,0.100407561,0.104109493,0.10416198,0.102468437,0.100942162,0.099806501,0.103722816,0.104194084,0.103317384,0.103823339,0.104090145,0.101395305,0.100796234,0.103431862,0.10093847,0.100657307,0.102213406,0.103078384,0.102997255,0.105477558,0.100301062,0.103332077,0.104490477,0.102099156,0.100259394,0.101521049,0.100743309,0.104187631,0.102710587],"variance":0.0000024793039245769844},"count":1,"hz":9.733587506623081,"time":102.73704318367346,"cycles":1,"battery":{"amperage":4483,"currentCapacity":925,"percent":12,"charging":"","temp":3104}},{"msg":"single1 x 9.72 ops/sec ±0.47% (48 runs sampled)","name":"single1","num":9.72,"sampled":"48","variation":"0.47","suite":["/Users/james/code/fluents/chain/packages/bench-chain/example/single1.json"],"timesFor":[{"start":1494206036348074,"end":1494206036451521,"diff":103447},{"start":1494206036477177,"end":1494206036578712,"diff":101535},{"start":1494206036601564,"end":1494206036705735,"diff":104171},{"start":1494206036725097,"end":1494206036824992,"diff":99895},{"start":1494206036844855,"end":1494206036945448,"diff":100593},{"start":1494206036964201,"end":1494206037067828,"diff":103627},{"start":1494206037089436,"end":1494206037194781,"diff":105345},{"start":1494206037215323,"end":1494206037319889,"diff":104566},{"start":1494206037338534,"end":1494206037443384,"diff":104850},{"start":1494206037459653,"end":1494206037559614,"diff":99961},{"start":1494206037576242,"end":1494206037679564,"diff":103322},{"start":1494206037696661,"end":1494206037799211,"diff":102550},{"start":1494206037815466,"end":1494206037920316,"diff":104850},{"start":1494206037937741,"end":1494206038038564,"diff":100823},{"start":1494206038056495,"end":1494206038159799,"diff":103304},{"start":1494206038177246,"end":1494206038277281,"diff":100035},{"start":1494206038296419,"end":1494206038397099,"diff":100680},{"start":1494206038416472,"end":1494206038520874,"diff":104402},{"start":1494206038538117,"end":1494206038642088,"diff":103971},{"start":1494206038660702,"end":1494206038765211,"diff":104509},{"start":1494206038784197,"end":1494206038886202,"diff":102005},{"start":1494206038902753,"end":1494206039004757,"diff":102004},{"start":1494206039020463,"end":1494206039125391,"diff":104928},{"start":1494206039143160,"end":1494206039243356,"diff":100196},{"start":1494206039260362,"end":1494206039361705,"diff":101343},{"start":1494206039379133,"end":1494206039483402,"diff":104269},{"start":1494206039502754,"end":1494206039604051,"diff":101297},{"start":1494206039622543,"end":1494206039727378,"diff":104835},{"start":1494206039744672,"end":1494206039844823,"diff":100151},{"start":1494206039863027,"end":1494206039965768,"diff":102741},{"start":1494206039981057,"end":1494206040083332,"diff":102275},{"start":1494206040102522,"end":1494206040204937,"diff":102415},{"start":1494206040220759,"end":1494206040324833,"diff":104074},{"start":1494206040341475,"end":1494206040444255,"diff":102780},{"start":1494206040461653,"end":1494206040563601,"diff":101948},{"start":1494206040579668,"end":1494206040682833,"diff":103165},{"start":1494206040700902,"end":1494206040805368,"diff":104466},{"start":1494206040824049,"end":1494206040924896,"diff":100847},{"start":1494206040942928,"end":1494206041043303,"diff":100375},{"start":1494206041060423,"end":1494206041160884,"diff":100461},{"start":1494206041178536,"end":1494206041283247,"diff":104711},{"start":1494206041301167,"end":1494206041403431,"diff":102264},{"start":1494206041419679,"end":1494206041523291,"diff":103612},{"start":1494206041542676,"end":1494206041648087,"diff":105411},{"start":1494206041664732,"end":1494206041768818,"diff":104086},{"start":1494206041787366,"end":1494206041888726,"diff":101360},{"start":1494206041905407,"end":1494206042009993,"diff":104586},{"start":1494206042026526,"end":1494206042129753,"diff":103227}],"now":1494206042137,"mem":{"start":{"process":{"rss":51650560,"heapTotal":29458432,"heapUsed":22050720,"external":123168},"os":540717056},"end":{"process":{"rss":65581056,"heapTotal":41701376,"heapUsed":23599976,"external":25668},"os":565063680}},"stats":{"moe":0.00048343291325440326,"rme":0.47000776213509676,"sem":0.00024664944553796084,"deviation":0.0017088374853217636,"mean":0.10285636795833335,"sample":[0.103742006,0.101697722,0.104297269,0.100075499,0.100699494,0.103717699,0.105428015,0.104685441,0.105016142,0.100068347,0.103441427,0.102628673,0.104932585,0.10090065,0.103393805,0.100109702,0.100757255,0.104565933,0.104053922,0.104592082,0.102077933,0.102083067,0.105003487,0.100284782,0.10142059,0.104356635,0.101471985,0.104918994,0.10023405,0.102818603,0.102378445,0.102500103,0.104149123,0.102852184,0.102034912,0.10324335,0.104545334,0.100942218,0.100453666,0.100536479,0.104799247,0.102371854,0.103689952,0.105502841,0.104167029,0.101445786,0.104714598,0.103304747],"variance":0.0000029201255512408088},"count":1,"hz":9.722295467453172,"time":102.85636795833335,"cycles":1,"battery":{"amperage":4483,"currentCapacity":925,"percent":12,"charging":"","temp":3104}},{"msg":"single1 x 9.72 ops/sec ±0.47% (48 runs sampled)","name":"single1","num":9.72,"sampled":"48","variation":"0.47","suite":["/Users/james/code/fluents/chain/packages/bench-chain/example/single1.json"],"timesFor":[{"start":1494206036348074,"end":1494206036451521,"diff":103447},{"start":1494206036477177,"end":1494206036578712,"diff":101535},{"start":1494206036601564,"end":1494206036705735,"diff":104171},{"start":1494206036725097,"end":1494206036824992,"diff":99895},{"start":1494206036844855,"end":1494206036945448,"diff":100593},{"start":1494206036964201,"end":1494206037067828,"diff":103627},{"start":1494206037089436,"end":1494206037194781,"diff":105345},{"start":1494206037215323,"end":1494206037319889,"diff":104566},{"start":1494206037338534,"end":1494206037443384,"diff":104850},{"start":1494206037459653,"end":1494206037559614,"diff":99961},{"start":1494206037576242,"end":1494206037679564,"diff":103322},{"start":1494206037696661,"end":1494206037799211,"diff":102550},{"start":1494206037815466,"end":1494206037920316,"diff":104850},{"start":1494206037937741,"end":1494206038038564,"diff":100823},{"start":1494206038056495,"end":1494206038159799,"diff":103304},{"start":1494206038177246,"end":1494206038277281,"diff":100035},{"start":1494206038296419,"end":1494206038397099,"diff":100680},{"start":1494206038416472,"end":1494206038520874,"diff":104402},{"start":1494206038538117,"end":1494206038642088,"diff":103971},{"start":1494206038660702,"end":1494206038765211,"diff":104509},{"start":1494206038784197,"end":1494206038886202,"diff":102005},{"start":1494206038902753,"end":1494206039004757,"diff":102004},{"start":1494206039020463,"end":1494206039125391,"diff":104928},{"start":1494206039143160,"end":1494206039243356,"diff":100196},{"start":1494206039260362,"end":1494206039361705,"diff":101343},{"start":1494206039379133,"end":1494206039483402,"diff":104269},{"start":1494206039502754,"end":1494206039604051,"diff":101297},{"start":1494206039622543,"end":1494206039727378,"diff":104835},{"start":1494206039744672,"end":1494206039844823,"diff":100151},{"start":1494206039863027,"end":1494206039965768,"diff":102741},{"start":1494206039981057,"end":1494206040083332,"diff":102275},{"start":1494206040102522,"end":1494206040204937,"diff":102415},{"start":1494206040220759,"end":1494206040324833,"diff":104074},{"start":1494206040341475,"end":1494206040444255,"diff":102780},{"start":1494206040461653,"end":1494206040563601,"diff":101948},{"start":1494206040579668,"end":1494206040682833,"diff":103165},{"start":1494206040700902,"end":1494206040805368,"diff":104466},{"start":1494206040824049,"end":1494206040924896,"diff":100847},{"start":1494206040942928,"end":1494206041043303,"diff":100375},{"start":1494206041060423,"end":1494206041160884,"diff":100461},{"start":1494206041178536,"end":1494206041283247,"diff":104711},{"start":1494206041301167,"end":1494206041403431,"diff":102264},{"start":1494206041419679,"end":1494206041523291,"diff":103612},{"start":1494206041542676,"end":1494206041648087,"diff":105411},{"start":1494206041664732,"end":1494206041768818,"diff":104086},{"start":1494206041787366,"end":1494206041888726,"diff":101360},{"start":1494206041905407,"end":1494206042009993,"diff":104586},{"start":1494206042026526,"end":1494206042129753,"diff":103227}],"now":1494206042137,"mem":{"start":{"process":{"rss":51650560,"heapTotal":29458432,"heapUsed":22050720,"external":123168},"os":540717056},"end":{"process":{"rss":65589248,"heapTotal":41701376,"heapUsed":23628016,"external":25668},"os":565063680}},"stats":{"moe":0.00048343291325440326,"rme":0.47000776213509676,"sem":0.00024664944553796084,"deviation":0.0017088374853217636,"mean":0.10285636795833335,"sample":[0.103742006,0.101697722,0.104297269,0.100075499,0.100699494,0.103717699,0.105428015,0.104685441,0.105016142,0.100068347,0.103441427,0.102628673,0.104932585,0.10090065,0.103393805,0.100109702,0.100757255,0.104565933,0.104053922,0.104592082,0.102077933,0.102083067,0.105003487,0.100284782,0.10142059,0.104356635,0.101471985,0.104918994,0.10023405,0.102818603,0.102378445,0.102500103,0.104149123,0.102852184,0.102034912,0.10324335,0.104545334,0.100942218,0.100453666,0.100536479,0.104799247,0.102371854,0.103689952,0.105502841,0.104167029,0.101445786,0.104714598,0.103304747],"variance":0.0000029201255512408088},"count":1,"hz":9.722295467453172,"time":102.85636795833335,"cycles":1,"battery":{"amperage":4483,"currentCapacity":925,"percent":12,"charging":"","temp":3104}},{"msg":"single1 x 9.72 ops/sec ±0.45% (48 runs sampled)","name":"single1","num":9.72,"sampled":"48","variation":"0.45","suite":["/Users/james/code/fluents/chain/packages/bench-chain/example/single1.json"],"timesFor":[{"start":1494206121301851,"end":1494206121407477,"diff":105626},{"start":1494206121428497,"end":1494206121533643,"diff":105146},{"start":1494206121555397,"end":1494206121659072,"diff":103675},{"start":1494206121677781,"end":1494206121781679,"diff":103898},{"start":1494206121800482,"end":1494206121901332,"diff":100850},{"start":1494206121922577,"end":1494206122024750,"diff":102173},{"start":1494206122046349,"end":1494206122148762,"diff":102413},{"start":1494206122169101,"end":1494206122273198,"diff":104097},{"start":1494206122292914,"end":1494206122394079,"diff":101165},{"start":1494206122411330,"end":1494206122514201,"diff":102871},{"start":1494206122532613,"end":1494206122634578,"diff":101965},{"start":1494206122653869,"end":1494206122758689,"diff":104820},{"start":1494206122775312,"end":1494206122876225,"diff":100913},{"start":1494206122894036,"end":1494206122997630,"diff":103594},{"start":1494206123016593,"end":1494206123119709,"diff":103116},{"start":1494206123137384,"end":1494206123241292,"diff":103908},{"start":1494206123259819,"end":1494206123362817,"diff":102998},{"start":1494206123381747,"end":1494206123482869,"diff":101122},{"start":1494206123500719,"end":1494206123601832,"diff":101113},{"start":1494206123618859,"end":1494206123720704,"diff":101845},{"start":1494206123740965,"end":1494206123842456,"diff":101491},{"start":1494206123861877,"end":1494206123966161,"diff":104284},{"start":1494206123985106,"end":1494206124090337,"diff":105231},{"start":1494206124109679,"end":1494206124210500,"diff":100821},{"start":1494206124227550,"end":1494206124331621,"diff":104071},{"start":1494206124350305,"end":1494206124455020,"diff":104715},{"start":1494206124473316,"end":1494206124573153,"diff":99837},{"start":1494206124592583,"end":1494206124694359,"diff":101776},{"start":1494206124711857,"end":1494206124814471,"diff":102614},{"start":1494206124830952,"end":1494206124934812,"diff":103860},{"start":1494206124951534,"end":1494206125054780,"diff":103246},{"start":1494206125072301,"end":1494206125177431,"diff":105130},{"start":1494206125194830,"end":1494206125296212,"diff":101382},{"start":1494206125314042,"end":1494206125418831,"diff":104789},{"start":1494206125436113,"end":1494206125537144,"diff":101031},{"start":1494206125554127,"end":1494206125658073,"diff":103946},{"start":1494206125675923,"end":1494206125781205,"diff":105282},{"start":1494206125799921,"end":1494206125904585,"diff":104664},{"start":1494206125924522,"end":1494206126025151,"diff":100629},{"start":1494206126043699,"end":1494206126145193,"diff":101494},{"start":1494206126160795,"end":1494206126262911,"diff":102116},{"start":1494206126279983,"end":1494206126383243,"diff":103260},{"start":1494206126399002,"end":1494206126499148,"diff":100146},{"start":1494206126518007,"end":1494206126621369,"diff":103362},{"start":1494206126637165,"end":1494206126741131,"diff":103966},{"start":1494206126758364,"end":1494206126859916,"diff":101552},{"start":1494206126876673,"end":1494206126976798,"diff":100125},{"start":1494206126995230,"end":1494206127099322,"diff":104092}],"now":1494206127106,"mem":{"start":{"process":{"rss":51290112,"heapTotal":28934144,"heapUsed":22056984,"external":123168},"os":455811072},"end":{"process":{"rss":62799872,"heapTotal":41177088,"heapUsed":28199472,"external":25668},"os":465911808}},"stats":{"moe":0.0004597192689454255,"rme":0.4466437725053319,"sem":0.00023455064742113546,"deviation":0.0016250145531263227,"mean":0.1029275,"sample":[0.105873,0.105315,0.103796,0.104032,0.100929,0.102262,0.102491,0.104162,0.101253,0.102951,0.102063,0.1049,0.100985,0.103672,0.10319,0.103977,0.103102,0.101222,0.101207,0.101923,0.101557,0.104365,0.105312,0.100894,0.104161,0.104788,0.099989,0.101862,0.102686,0.103937,0.103309,0.105245,0.10154,0.104883,0.101102,0.104036,0.105367,0.104743,0.100702,0.10158,0.102197,0.103326,0.100204,0.103438,0.104025,0.101609,0.100193,0.104165],"variance":0.000002640672297872342},"count":1,"hz":9.71557649802045,"time":102.92750000000001,"cycles":1,"battery":{"amperage":4006,"currentCapacity":1066,"percent":14,"charging":"","temp":3104}},{"msg":"single1 x 9.72 ops/sec ±0.45% (48 runs sampled)","name":"single1","num":9.72,"sampled":"48","variation":"0.45","suite":["/Users/james/code/fluents/chain/packages/bench-chain/example/single1.json"],"timesFor":[{"start":1494206121301851,"end":1494206121407477,"diff":105626},{"start":1494206121428497,"end":1494206121533643,"diff":105146},{"start":1494206121555397,"end":1494206121659072,"diff":103675},{"start":1494206121677781,"end":1494206121781679,"diff":103898},{"start":1494206121800482,"end":1494206121901332,"diff":100850},{"start":1494206121922577,"end":1494206122024750,"diff":102173},{"start":1494206122046349,"end":1494206122148762,"diff":102413},{"start":1494206122169101,"end":1494206122273198,"diff":104097},{"start":1494206122292914,"end":1494206122394079,"diff":101165},{"start":1494206122411330,"end":1494206122514201,"diff":102871},{"start":1494206122532613,"end":1494206122634578,"diff":101965},{"start":1494206122653869,"end":1494206122758689,"diff":104820},{"start":1494206122775312,"end":1494206122876225,"diff":100913},{"start":1494206122894036,"end":1494206122997630,"diff":103594},{"start":1494206123016593,"end":1494206123119709,"diff":103116},{"start":1494206123137384,"end":1494206123241292,"diff":103908},{"start":1494206123259819,"end":1494206123362817,"diff":102998},{"start":1494206123381747,"end":1494206123482869,"diff":101122},{"start":1494206123500719,"end":1494206123601832,"diff":101113},{"start":1494206123618859,"end":1494206123720704,"diff":101845},{"start":1494206123740965,"end":1494206123842456,"diff":101491},{"start":1494206123861877,"end":1494206123966161,"diff":104284},{"start":1494206123985106,"end":1494206124090337,"diff":105231},{"start":1494206124109679,"end":1494206124210500,"diff":100821},{"start":1494206124227550,"end":1494206124331621,"diff":104071},{"start":1494206124350305,"end":1494206124455020,"diff":104715},{"start":1494206124473316,"end":1494206124573153,"diff":99837},{"start":1494206124592583,"end":1494206124694359,"diff":101776},{"start":1494206124711857,"end":1494206124814471,"diff":102614},{"start":1494206124830952,"end":1494206124934812,"diff":103860},{"start":1494206124951534,"end":1494206125054780,"diff":103246},{"start":1494206125072301,"end":1494206125177431,"diff":105130},{"start":1494206125194830,"end":1494206125296212,"diff":101382},{"start":1494206125314042,"end":1494206125418831,"diff":104789},{"start":1494206125436113,"end":1494206125537144,"diff":101031},{"start":1494206125554127,"end":1494206125658073,"diff":103946},{"start":1494206125675923,"end":1494206125781205,"diff":105282},{"start":1494206125799921,"end":1494206125904585,"diff":104664},{"start":1494206125924522,"end":1494206126025151,"diff":100629},{"start":1494206126043699,"end":1494206126145193,"diff":101494},{"start":1494206126160795,"end":1494206126262911,"diff":102116},{"start":1494206126279983,"end":1494206126383243,"diff":103260},{"start":1494206126399002,"end":1494206126499148,"diff":100146},{"start":1494206126518007,"end":1494206126621369,"diff":103362},{"start":1494206126637165,"end":1494206126741131,"diff":103966},{"start":1494206126758364,"end":1494206126859916,"diff":101552},{"start":1494206126876673,"end":1494206126976798,"diff":100125},{"start":1494206126995230,"end":1494206127099322,"diff":104092}],"now":1494206127107,"mem":{"start":{"process":{"rss":51290112,"heapTotal":28934144,"heapUsed":22056984,"external":123168},"os":455811072},"end":{"process":{"rss":62820352,"heapTotal":41177088,"heapUsed":28227536,"external":25668},"os":465911808}},"stats":{"moe":0.0004597192689454255,"rme":0.4466437725053319,"sem":0.00023455064742113546,"deviation":0.0016250145531263227,"mean":0.1029275,"sample":[0.105873,0.105315,0.103796,0.104032,0.100929,0.102262,0.102491,0.104162,0.101253,0.102951,0.102063,0.1049,0.100985,0.103672,0.10319,0.103977,0.103102,0.101222,0.101207,0.101923,0.101557,0.104365,0.105312,0.100894,0.104161,0.104788,0.099989,0.101862,0.102686,0.103937,0.103309,0.105245,0.10154,0.104883,0.101102,0.104036,0.105367,0.104743,0.100702,0.10158,0.102197,0.103326,0.100204,0.103438,0.104025,0.101609,0.100193,0.104165],"variance":0.000002640672297872342},"count":1,"hz":9.71557649802045,"time":102.92750000000001,"cycles":1,"battery":{"amperage":4006,"currentCapacity":1066,"percent":14,"charging":"","temp":3104}},{"msg":"single1 x 9.71 ops/sec ±0.46% (49 runs sampled)","name":"single1","num":9.71,"sampled":"49","variation":"0.46","suite":["/Users/james/code/fluents/chain/packages/bench-chain/example/single1.json"],"timesFor":[{"start":1494206163745554,"end":1494206163850885,"diff":105331},{"start":1494206163875293,"end":1494206163980160,"diff":104867},{"start":1494206164006185,"end":1494206164106656,"diff":100471},{"start":1494206164124783,"end":1494206164226396,"diff":101613},{"start":1494206164245897,"end":1494206164349622,"diff":103725},{"start":1494206164370411,"end":1494206164470380,"diff":99969},{"start":1494206164491162,"end":1494206164594672,"diff":103510},{"start":1494206164619267,"end":1494206164723704,"diff":104437},{"start":1494206164742160,"end":1494206164844498,"diff":102338},{"start":1494206164862844,"end":1494206164962502,"diff":99658},{"start":1494206164981648,"end":1494206165085399,"diff":103751},{"start":1494206165102477,"end":1494206165205244,"diff":102767},{"start":1494206165224003,"end":1494206165326517,"diff":102514},{"start":1494206165343358,"end":1494206165449126,"diff":105768},{"start":1494206165466684,"end":1494206165569939,"diff":103255},{"start":1494206165587439,"end":1494206165689672,"diff":102233},{"start":1494206165708447,"end":1494206165812538,"diff":104091},{"start":1494206165834014,"end":1494206165934980,"diff":100966},{"start":1494206165951581,"end":1494206166056158,"diff":104577},{"start":1494206166072480,"end":1494206166173935,"diff":101455},{"start":1494206166194336,"end":1494206166298697,"diff":104361},{"start":1494206166317363,"end":1494206166417889,"diff":100526},{"start":1494206166434772,"end":1494206166538773,"diff":104001},{"start":1494206166555308,"end":1494206166655335,"diff":100027},{"start":1494206166670282,"end":1494206166772592,"diff":102310},{"start":1494206166787904,"end":1494206166889480,"diff":101576},{"start":1494206166907795,"end":1494206167010979,"diff":103184},{"start":1494206167027828,"end":1494206167131984,"diff":104156},{"start":1494206167147038,"end":1494206167248593,"diff":101555},{"start":1494206167267001,"end":1494206167370662,"diff":103661},{"start":1494206167390364,"end":1494206167491157,"diff":100793},{"start":1494206167509097,"end":1494206167611874,"diff":102777},{"start":1494206167629109,"end":1494206167729852,"diff":100743},{"start":1494206167747462,"end":1494206167849002,"diff":101540},{"start":1494206167868189,"end":1494206167973744,"diff":105555},{"start":1494206167989078,"end":1494206168094308,"diff":105230},{"start":1494206168113777,"end":1494206168218130,"diff":104353},{"start":1494206168234785,"end":1494206168339471,"diff":104686},{"start":1494206168357067,"end":1494206168460907,"diff":103840},{"start":1494206168477504,"end":1494206168579809,"diff":102305},{"start":1494206168595979,"end":1494206168699268,"diff":103289},{"start":1494206168715026,"end":1494206168816694,"diff":101668},{"start":1494206168832097,"end":1494206168937736,"diff":105639},{"start":1494206168952607,"end":1494206169052782,"diff":100175},{"start":1494206169069296,"end":1494206169173363,"diff":104067},{"start":1494206169190190,"end":1494206169294735,"diff":104545},{"start":1494206169310665,"end":1494206169414294,"diff":103629},{"start":1494206169432600,"end":1494206169534949,"diff":102349},{"start":1494206169555005,"end":1494206169656485,"diff":101480}],"now":1494206169662,"mem":{"start":{"process":{"rss":51605504,"heapTotal":29458432,"heapUsed":22098728,"external":123168},"os":443027456},"end":{"process":{"rss":66109440,"heapTotal":41701376,"heapUsed":25184976,"external":25668},"os":442474496}},"stats":{"moe":0.0004745239526521346,"rme":0.460763001747599,"sem":0.0002421040574755789,"deviation":0.0016947284023290522,"mean":0.10298655726530614,"sample":[0.105595942,0.105291742,0.100640302,0.101779703,0.103793875,0.100040837,0.103595677,0.104503236,0.102417745,0.09977692,0.103841159,0.102919894,0.102596076,0.105861657,0.103334279,0.102310039,0.104171384,0.101056497,0.104651992,0.101542975,0.104430555,0.100662968,0.104081045,0.100096495,0.102372218,0.101644165,0.103323385,0.104217147,0.10161282,0.103730161,0.100886157,0.102896022,0.100828233,0.101618187,0.105639549,0.105314664,0.104474636,0.104753961,0.103941129,0.102368989,0.103347197,0.101783676,0.105705263,0.100238338,0.104148965,0.104657397,0.103701249,0.102436227,0.101708577],"variance":0.0000028721043576607814},"count":1,"hz":9.710005136144865,"time":102.98655726530615,"cycles":1,"battery":{"amperage":4006,"currentCapacity":1066,"percent":14,"charging":"","temp":3104}},{"msg":"single1 x 9.71 ops/sec ±0.46% (49 runs sampled)","name":"single1","num":9.71,"sampled":"49","variation":"0.46","suite":["/Users/james/code/fluents/chain/packages/bench-chain/example/single1.json"],"timesFor":[{"start":1494206163745554,"end":1494206163850885,"diff":105331},{"start":1494206163875293,"end":1494206163980160,"diff":104867},{"start":1494206164006185,"end":1494206164106656,"diff":100471},{"start":1494206164124783,"end":1494206164226396,"diff":101613},{"start":1494206164245897,"end":1494206164349622,"diff":103725},{"start":1494206164370411,"end":1494206164470380,"diff":99969},{"start":1494206164491162,"end":1494206164594672,"diff":103510},{"start":1494206164619267,"end":1494206164723704,"diff":104437},{"start":1494206164742160,"end":1494206164844498,"diff":102338},{"start":1494206164862844,"end":1494206164962502,"diff":99658},{"start":1494206164981648,"end":1494206165085399,"diff":103751},{"start":1494206165102477,"end":1494206165205244,"diff":102767},{"start":1494206165224003,"end":1494206165326517,"diff":102514},{"start":1494206165343358,"end":1494206165449126,"diff":105768},{"start":1494206165466684,"end":1494206165569939,"diff":103255},{"start":1494206165587439,"end":1494206165689672,"diff":102233},{"start":1494206165708447,"end":1494206165812538,"diff":104091},{"start":1494206165834014,"end":1494206165934980,"diff":100966},{"start":1494206165951581,"end":1494206166056158,"diff":104577},{"start":1494206166072480,"end":1494206166173935,"diff":101455},{"start":1494206166194336,"end":1494206166298697,"diff":104361},{"start":1494206166317363,"end":1494206166417889,"diff":100526},{"start":1494206166434772,"end":1494206166538773,"diff":104001},{"start":1494206166555308,"end":1494206166655335,"diff":100027},{"start":1494206166670282,"end":1494206166772592,"diff":102310},{"start":1494206166787904,"end":1494206166889480,"diff":101576},{"start":1494206166907795,"end":1494206167010979,"diff":103184},{"start":1494206167027828,"end":1494206167131984,"diff":104156},{"start":1494206167147038,"end":1494206167248593,"diff":101555},{"start":1494206167267001,"end":1494206167370662,"diff":103661},{"start":1494206167390364,"end":1494206167491157,"diff":100793},{"start":1494206167509097,"end":1494206167611874,"diff":102777},{"start":1494206167629109,"end":1494206167729852,"diff":100743},{"start":1494206167747462,"end":1494206167849002,"diff":101540},{"start":1494206167868189,"end":1494206167973744,"diff":105555},{"start":1494206167989078,"end":1494206168094308,"diff":105230},{"start":1494206168113777,"end":1494206168218130,"diff":104353},{"start":1494206168234785,"end":1494206168339471,"diff":104686},{"start":1494206168357067,"end":1494206168460907,"diff":103840},{"start":1494206168477504,"end":1494206168579809,"diff":102305},{"start":1494206168595979,"end":1494206168699268,"diff":103289},{"start":1494206168715026,"end":1494206168816694,"diff":101668},{"start":1494206168832097,"end":1494206168937736,"diff":105639},{"start":1494206168952607,"end":1494206169052782,"diff":100175},{"start":1494206169069296,"end":1494206169173363,"diff":104067},{"start":1494206169190190,"end":1494206169294735,"diff":104545},{"start":1494206169310665,"end":1494206169414294,"diff":103629},{"start":1494206169432600,"end":1494206169534949,"diff":102349},{"start":1494206169555005,"end":1494206169656485,"diff":101480}],"now":1494206169663,"mem":{"start":{"process":{"rss":51605504,"heapTotal":29458432,"heapUsed":22098728,"external":123168},"os":443027456},"end":{"process":{"rss":66117632,"heapTotal":41701376,"heapUsed":25213064,"external":25668},"os":442474496}},"stats":{"moe":0.0004745239526521346,"rme":0.460763001747599,"sem":0.0002421040574755789,"deviation":0.0016947284023290522,"mean":0.10298655726530614,"sample":[0.105595942,0.105291742,0.100640302,0.101779703,0.103793875,0.100040837,0.103595677,0.104503236,0.102417745,0.09977692,0.103841159,0.102919894,0.102596076,0.105861657,0.103334279,0.102310039,0.104171384,0.101056497,0.104651992,0.101542975,0.104430555,0.100662968,0.104081045,0.100096495,0.102372218,0.101644165,0.103323385,0.104217147,0.10161282,0.103730161,0.100886157,0.102896022,0.100828233,0.101618187,0.105639549,0.105314664,0.104474636,0.104753961,0.103941129,0.102368989,0.103347197,0.101783676,0.105705263,0.100238338,0.104148965,0.104657397,0.103701249,0.102436227,0.101708577],"variance":0.0000028721043576607814},"count":1,"hz":9.710005136144865,"time":102.98655726530615,"cycles":1,"battery":{"amperage":4006,"currentCapacity":1066,"percent":14,"charging":"","temp":3104}},{"msg":"single1 x 9.75 ops/sec ±0.45% (49 runs sampled)","name":"single1","num":9.75,"sampled":"49","variation":"0.45","suite":["/Users/james/code/fluents/chain/packages/bench-chain/example/single1.json"],"timesFor":[{"start":1494206370404592,"end":1494206370507137,"diff":102545},{"start":1494206370534064,"end":1494206370638805,"diff":104741},{"start":1494206370661624,"end":1494206370761663,"diff":100039},{"start":1494206370782053,"end":1494206370885310,"diff":103257},{"start":1494206370905024,"end":1494206371008045,"diff":103021},{"start":1494206371026388,"end":1494206371126619,"diff":100231},{"start":1494206371146020,"end":1494206371250589,"diff":104569},{"start":1494206371269912,"end":1494206371373299,"diff":103387},{"start":1494206371390741,"end":1494206371492820,"diff":102079},{"start":1494206371509208,"end":1494206371611884,"diff":102676},{"start":1494206371630814,"end":1494206371735352,"diff":104538},{"start":1494206371754610,"end":1494206371855954,"diff":101344},{"start":1494206371873707,"end":1494206371976654,"diff":102947},{"start":1494206371993514,"end":1494206372094588,"diff":101074},{"start":1494206372111011,"end":1494206372211920,"diff":100909},{"start":1494206372232675,"end":1494206372332832,"diff":100157},{"start":1494206372350424,"end":1494206372453867,"diff":103443},{"start":1494206372473516,"end":1494206372576620,"diff":103104},{"start":1494206372592862,"end":1494206372694555,"diff":101693},{"start":1494206372710490,"end":1494206372810177,"diff":99687},{"start":1494206372828428,"end":1494206372928889,"diff":100461},{"start":1494206372947684,"end":1494206373050497,"diff":102813},{"start":1494206373066299,"end":1494206373167122,"diff":100823},{"start":1494206373183687,"end":1494206373285477,"diff":101790},{"start":1494206373301689,"end":1494206373406006,"diff":104317},{"start":1494206373424226,"end":1494206373526693,"diff":102467},{"start":1494206373543433,"end":1494206373644452,"diff":101019},{"start":1494206373660789,"end":1494206373763331,"diff":102542},{"start":1494206373780033,"end":1494206373885401,"diff":105368},{"start":1494206373904239,"end":1494206374004554,"diff":100315},{"start":1494206374024270,"end":1494206374126684,"diff":102414},{"start":1494206374143648,"end":1494206374244175,"diff":100527},{"start":1494206374260552,"end":1494206374362661,"diff":102109},{"start":1494206374381873,"end":1494206374486975,"diff":105102},{"start":1494206374504918,"end":1494206374605910,"diff":100992},{"start":1494206374624667,"end":1494206374729172,"diff":104505},{"start":1494206374749189,"end":1494206374850124,"diff":100935},{"start":1494206374869182,"end":1494206374973240,"diff":104058},{"start":1494206374991408,"end":1494206375094859,"diff":103451},{"start":1494206375115084,"end":1494206375217352,"diff":102268},{"start":1494206375233553,"end":1494206375338537,"diff":104984},{"start":1494206375355699,"end":1494206375461371,"diff":105672},{"start":1494206375479359,"end":1494206375579588,"diff":100229},{"start":1494206375597135,"end":1494206375699733,"diff":102598},{"start":1494206375716856,"end":1494206375818144,"diff":101288},{"start":1494206375834692,"end":1494206375938596,"diff":103904},{"start":1494206375956101,"end":1494206376055851,"diff":99750},{"start":1494206376073180,"end":1494206376176648,"diff":103468},{"start":1494206376195398,"end":1494206376299831,"diff":104433}],"now":1494206376306,"mem":{"start":{"process":{"rss":51290112,"heapTotal":29458432,"heapUsed":22084448,"external":123168},"os":283664384},"end":{"process":{"rss":65478656,"heapTotal":41701376,"heapUsed":24960536,"external":25668},"os":259710976}},"stats":{"moe":0.0004662730491969794,"rme":0.45464550144610116,"sem":0.00023789441285560175,"deviation":0.0016652608899892123,"mean":0.10255749759183677,"sample":[0.102842423,0.10491822,0.100225616,0.10340501,0.103099241,0.100301266,0.104635282,0.103460083,0.102266291,0.102749619,0.104613746,0.101475791,0.103085837,0.10123915,0.100985911,0.100251627,0.103556899,0.103219141,0.101780301,0.099759345,0.100525717,0.10289568,0.101011301,0.101863096,0.10440035,0.102578187,0.101159669,0.102621519,0.105455052,0.100404922,0.102521076,0.100592837,0.102227554,0.105189382,0.101064741,0.104589963,0.101090562,0.104151593,0.103555197,0.102353254,0.105065631,0.105762247,0.100357754,0.102693864,0.101372209,0.103985259,0.099854328,0.103568451,0.104535188],"variance":0.0000027730938317276635},"count":1,"hz":9.750627925613472,"time":102.55749759183678,"cycles":1,"battery":{"amperage":3992,"currentCapacity":1351,"percent":17,"charging":"","temp":3104}},{"msg":"single1 x 9.75 ops/sec ±0.45% (49 runs sampled)","name":"single1","num":9.75,"sampled":"49","variation":"0.45","suite":["/Users/james/code/fluents/chain/packages/bench-chain/example/single1.json"],"timesFor":[{"start":1494206370404592,"end":1494206370507137,"diff":102545},{"start":1494206370534064,"end":1494206370638805,"diff":104741},{"start":1494206370661624,"end":1494206370761663,"diff":100039},{"start":1494206370782053,"end":1494206370885310,"diff":103257},{"start":1494206370905024,"end":1494206371008045,"diff":103021},{"start":1494206371026388,"end":1494206371126619,"diff":100231},{"start":1494206371146020,"end":1494206371250589,"diff":104569},{"start":1494206371269912,"end":1494206371373299,"diff":103387},{"start":1494206371390741,"end":1494206371492820,"diff":102079},{"start":1494206371509208,"end":1494206371611884,"diff":102676},{"start":1494206371630814,"end":1494206371735352,"diff":104538},{"start":1494206371754610,"end":1494206371855954,"diff":101344},{"start":1494206371873707,"end":1494206371976654,"diff":102947},{"start":1494206371993514,"end":1494206372094588,"diff":101074},{"start":1494206372111011,"end":1494206372211920,"diff":100909},{"start":1494206372232675,"end":1494206372332832,"diff":100157},{"start":1494206372350424,"end":1494206372453867,"diff":103443},{"start":1494206372473516,"end":1494206372576620,"diff":103104},{"start":1494206372592862,"end":1494206372694555,"diff":101693},{"start":1494206372710490,"end":1494206372810177,"diff":99687},{"start":1494206372828428,"end":1494206372928889,"diff":100461},{"start":1494206372947684,"end":1494206373050497,"diff":102813},{"start":1494206373066299,"end":1494206373167122,"diff":100823},{"start":1494206373183687,"end":1494206373285477,"diff":101790},{"start":1494206373301689,"end":1494206373406006,"diff":104317},{"start":1494206373424226,"end":1494206373526693,"diff":102467},{"start":1494206373543433,"end":1494206373644452,"diff":101019},{"start":1494206373660789,"end":1494206373763331,"diff":102542},{"start":1494206373780033,"end":1494206373885401,"diff":105368},{"start":1494206373904239,"end":1494206374004554,"diff":100315},{"start":1494206374024270,"end":1494206374126684,"diff":102414},{"start":1494206374143648,"end":1494206374244175,"diff":100527},{"start":1494206374260552,"end":1494206374362661,"diff":102109},{"start":1494206374381873,"end":1494206374486975,"diff":105102},{"start":1494206374504918,"end":1494206374605910,"diff":100992},{"start":1494206374624667,"end":1494206374729172,"diff":104505},{"start":1494206374749189,"end":1494206374850124,"diff":100935},{"start":1494206374869182,"end":1494206374973240,"diff":104058},{"start":1494206374991408,"end":1494206375094859,"diff":103451},{"start":1494206375115084,"end":1494206375217352,"diff":102268},{"start":1494206375233553,"end":1494206375338537,"diff":104984},{"start":1494206375355699,"end":1494206375461371,"diff":105672},{"start":1494206375479359,"end":1494206375579588,"diff":100229},{"start":1494206375597135,"end":1494206375699733,"diff":102598},{"start":1494206375716856,"end":1494206375818144,"diff":101288},{"start":1494206375834692,"end":1494206375938596,"diff":103904},{"start":1494206375956101,"end":1494206376055851,"diff":99750},{"start":1494206376073180,"end":1494206376176648,"diff":103468},{"start":1494206376195398,"end":1494206376299831,"diff":104433}],"now":1494206376307,"mem":{"start":{"process":{"rss":51290112,"heapTotal":29458432,"heapUsed":22084448,"external":123168},"os":283664384},"end":{"process":{"rss":65486848,"heapTotal":41701376,"heapUsed":24988648,"external":25668},"os":259719168}},"stats":{"moe":0.0004662730491969794,"rme":0.45464550144610116,"sem":0.00023789441285560175,"deviation":0.0016652608899892123,"mean":0.10255749759183677,"sample":[0.102842423,0.10491822,0.100225616,0.10340501,0.103099241,0.100301266,0.104635282,0.103460083,0.102266291,0.102749619,0.104613746,0.101475791,0.103085837,0.10123915,0.100985911,0.100251627,0.103556899,0.103219141,0.101780301,0.099759345,0.100525717,0.10289568,0.101011301,0.101863096,0.10440035,0.102578187,0.101159669,0.102621519,0.105455052,0.100404922,0.102521076,0.100592837,0.102227554,0.105189382,0.101064741,0.104589963,0.101090562,0.104151593,0.103555197,0.102353254,0.105065631,0.105762247,0.100357754,0.102693864,0.101372209,0.103985259,0.099854328,0.103568451,0.104535188],"variance":0.0000027730938317276635},"count":1,"hz":9.750627925613472,"time":102.55749759183678,"cycles":1,"battery":{"amperage":3992,"currentCapacity":1351,"percent":17,"charging":"","temp":3104}},{"msg":"single1 x 9.75 ops/sec ±0.50% (49 runs sampled)","name":"single1","num":9.75,"sampled":"49","variation":"0.50","suite":["/Users/james/code/fluents/chain/packages/bench-chain/example/single1.json"],"timesFor":[{"start":1494206479258450,"end":1494206479360753,"diff":102303},{"start":1494206479385837,"end":1494206479487210,"diff":101373},{"start":1494206479509229,"end":1494206479613813,"diff":104584},{"start":1494206479633231,"end":1494206479734077,"diff":100846},{"start":1494206479753188,"end":1494206479857177,"diff":103989},{"start":1494206479878621,"end":1494206479983919,"diff":105298},{"start":1494206480005932,"end":1494206480106592,"diff":100660},{"start":1494206480128226,"end":1494206480230895,"diff":102669},{"start":1494206480248448,"end":1494206480347836,"diff":99388},{"start":1494206480366795,"end":1494206480470173,"diff":103378},{"start":1494206480487343,"end":1494206480590340,"diff":102997},{"start":1494206480606828,"end":1494206480712069,"diff":105241},{"start":1494206480729990,"end":1494206480833919,"diff":103929},{"start":1494206480850805,"end":1494206480955731,"diff":104926},{"start":1494206480971280,"end":1494206481071937,"diff":100657},{"start":1494206481089807,"end":1494206481190976,"diff":101169},{"start":1494206481211421,"end":1494206481311378,"diff":99957},{"start":1494206481333155,"end":1494206481433954,"diff":100799},{"start":1494206481452268,"end":1494206481555753,"diff":103485},{"start":1494206481576167,"end":1494206481677591,"diff":101424},{"start":1494206481697450,"end":1494206481802938,"diff":105488},{"start":1494206481819481,"end":1494206481923012,"diff":103531},{"start":1494206481941139,"end":1494206482042071,"diff":100932},{"start":1494206482060919,"end":1494206482162833,"diff":101914},{"start":1494206482178778,"end":1494206482281874,"diff":103096},{"start":1494206482298664,"end":1494206482401007,"diff":102343},{"start":1494206482417254,"end":1494206482520189,"diff":102935},{"start":1494206482540115,"end":1494206482643403,"diff":103288},{"start":1494206482661007,"end":1494206482761154,"diff":100147},{"start":1494206482777263,"end":1494206482877349,"diff":100086},{"start":1494206482895053,"end":1494206482998921,"diff":103868},{"start":1494206483015655,"end":1494206483120825,"diff":105170},{"start":1494206483139654,"end":1494206483242619,"diff":102965},{"start":1494206483258892,"end":1494206483364408,"diff":105516},{"start":1494206483380964,"end":1494206483483143,"diff":102179},{"start":1494206483500618,"end":1494206483601996,"diff":101378},{"start":1494206483620923,"end":1494206483721675,"diff":100752},{"start":1494206483739796,"end":1494206483840670,"diff":100874},{"start":1494206483857767,"end":1494206483962470,"diff":104703},{"start":1494206483978148,"end":1494206484082659,"diff":104511},{"start":1494206484100016,"end":1494206484200528,"diff":100512},{"start":1494206484217556,"end":1494206484322378,"diff":104822},{"start":1494206484338894,"end":1494206484438746,"diff":99852},{"start":1494206484455261,"end":1494206484557083,"diff":101822},{"start":1494206484573782,"end":1494206484674361,"diff":100579},{"start":1494206484693354,"end":1494206484794821,"diff":101467},{"start":1494206484814213,"end":1494206484914474,"diff":100261},{"start":1494206484932315,"end":1494206485036460,"diff":104145},{"start":1494206485053124,"end":1494206485158264,"diff":105140}],"now":1494206485165,"mem":{"start":{"process":{"rss":49786880,"heapTotal":27009024,"heapUsed":16057176,"external":164173},"os":345309184},"end":{"process":{"rss":65454080,"heapTotal":41701376,"heapUsed":30776256,"external":17476},"os":341245952}},"stats":{"moe":0.0005112665418350781,"rme":0.4982559601809651,"sem":0.00026085027644646844,"deviation":0.0018259519351252792,"mean":0.1026112244897959,"sample":[0.102565,0.101546,0.104715,0.101002,0.104156,0.10539,0.100728,0.102736,0.099456,0.103464,0.103077,0.105315,0.104002,0.105015,0.100743,0.101234,0.100191,0.10087,0.103561,0.101512,0.105608,0.103604,0.101005,0.102005,0.103161,0.102419,0.103081,0.103359,0.100219,0.100157,0.103944,0.105245,0.103044,0.105604,0.102253,0.101463,0.100833,0.100957,0.104783,0.104585,0.100591,0.1049,0.099939,0.101902,0.100667,0.101553,0.100358,0.104213,0.10522],"variance":0.000003334100469387752},"count":1,"hz":9.745522529062542,"time":102.6112244897959,"cycles":1,"battery":{"amperage":3798,"currentCapacity":1487,"percent":19,"charging":"","temp":3108}},{"msg":"single1 x 9.75 ops/sec ±0.50% (49 runs sampled)","name":"single1","num":9.75,"sampled":"49","variation":"0.50","suite":["/Users/james/code/fluents/chain/packages/bench-chain/example/single1.json"],"timesFor":[{"start":1494206479258450,"end":1494206479360753,"diff":102303},{"start":1494206479385837,"end":1494206479487210,"diff":101373},{"start":1494206479509229,"end":1494206479613813,"diff":104584},{"start":1494206479633231,"end":1494206479734077,"diff":100846},{"start":1494206479753188,"end":1494206479857177,"diff":103989},{"start":1494206479878621,"end":1494206479983919,"diff":105298},{"start":1494206480005932,"end":1494206480106592,"diff":100660},{"start":1494206480128226,"end":1494206480230895,"diff":102669},{"start":1494206480248448,"end":1494206480347836,"diff":99388},{"start":1494206480366795,"end":1494206480470173,"diff":103378},{"start":1494206480487343,"end":1494206480590340,"diff":102997},{"start":1494206480606828,"end":1494206480712069,"diff":105241},{"start":1494206480729990,"end":1494206480833919,"diff":103929},{"start":1494206480850805,"end":1494206480955731,"diff":104926},{"start":1494206480971280,"end":1494206481071937,"diff":100657},{"start":1494206481089807,"end":1494206481190976,"diff":101169},{"start":1494206481211421,"end":1494206481311378,"diff":99957},{"start":1494206481333155,"end":1494206481433954,"diff":100799},{"start":1494206481452268,"end":1494206481555753,"diff":103485},{"start":1494206481576167,"end":1494206481677591,"diff":101424},{"start":1494206481697450,"end":1494206481802938,"diff":105488},{"start":1494206481819481,"end":1494206481923012,"diff":103531},{"start":1494206481941139,"end":1494206482042071,"diff":100932},{"start":1494206482060919,"end":1494206482162833,"diff":101914},{"start":1494206482178778,"end":1494206482281874,"diff":103096},{"start":1494206482298664,"end":1494206482401007,"diff":102343},{"start":1494206482417254,"end":1494206482520189,"diff":102935},{"start":1494206482540115,"end":1494206482643403,"diff":103288},{"start":1494206482661007,"end":1494206482761154,"diff":100147},{"start":1494206482777263,"end":1494206482877349,"diff":100086},{"start":1494206482895053,"end":1494206482998921,"diff":103868},{"start":1494206483015655,"end":1494206483120825,"diff":105170},{"start":1494206483139654,"end":1494206483242619,"diff":102965},{"start":1494206483258892,"end":1494206483364408,"diff":105516},{"start":1494206483380964,"end":1494206483483143,"diff":102179},{"start":1494206483500618,"end":1494206483601996,"diff":101378},{"start":1494206483620923,"end":1494206483721675,"diff":100752},{"start":1494206483739796,"end":1494206483840670,"diff":100874},{"start":1494206483857767,"end":1494206483962470,"diff":104703},{"start":1494206483978148,"end":1494206484082659,"diff":104511},{"start":1494206484100016,"end":1494206484200528,"diff":100512},{"start":1494206484217556,"end":1494206484322378,"diff":104822},{"start":1494206484338894,"end":1494206484438746,"diff":99852},{"start":1494206484455261,"end":1494206484557083,"diff":101822},{"start":1494206484573782,"end":1494206484674361,"diff":100579},{"start":1494206484693354,"end":1494206484794821,"diff":101467},{"start":1494206484814213,"end":1494206484914474,"diff":100261},{"start":1494206484932315,"end":1494206485036460,"diff":104145},{"start":1494206485053124,"end":1494206485158264,"diff":105140}],"now":1494206485165,"mem":{"start":{"process":{"rss":49786880,"heapTotal":27009024,"heapUsed":16057176,"external":164173},"os":345309184},"end":{"process":{"rss":65482752,"heapTotal":41701376,"heapUsed":30804392,"external":17476},"os":341245952}},"stats":{"moe":0.0005112665418350781,"rme":0.4982559601809651,"sem":0.00026085027644646844,"deviation":0.0018259519351252792,"mean":0.1026112244897959,"sample":[0.102565,0.101546,0.104715,0.101002,0.104156,0.10539,0.100728,0.102736,0.099456,0.103464,0.103077,0.105315,0.104002,0.105015,0.100743,0.101234,0.100191,0.10087,0.103561,0.101512,0.105608,0.103604,0.101005,0.102005,0.103161,0.102419,0.103081,0.103359,0.100219,0.100157,0.103944,0.105245,0.103044,0.105604,0.102253,0.101463,0.100833,0.100957,0.104783,0.104585,0.100591,0.1049,0.099939,0.101902,0.100667,0.101553,0.100358,0.104213,0.10522],"variance":0.000003334100469387752},"count":1,"hz":9.745522529062542,"time":102.6112244897959,"cycles":1,"battery":{"amperage":3798,"currentCapacity":1487,"percent":19,"charging":"","temp":3108}},{"msg":"single1 x 9.73 ops/sec ±0.48% (49 runs sampled)","name":"single1","num":9.73,"sampled":"49","variation":"0.48","suite":["/Users/james/code/fluents/chain/packages/bench-chain/example/single1.json"],"timesFor":[{"start":1494206769073064,"end":1494206769178427,"diff":105363},{"start":1494206769204975,"end":1494206769307121,"diff":102146},{"start":1494206769326453,"end":1494206769429178,"diff":102725},{"start":1494206769445460,"end":1494206769550394,"diff":104934},{"start":1494206769566295,"end":1494206769666517,"diff":100222},{"start":1494206769683793,"end":1494206769788376,"diff":104583},{"start":1494206769809014,"end":1494206769913117,"diff":104103},{"start":1494206769932738,"end":1494206770033338,"diff":100600},{"start":1494206770051026,"end":1494206770150653,"diff":99627},{"start":1494206770166759,"end":1494206770270172,"diff":103413},{"start":1494206770285695,"end":1494206770389883,"diff":104188},{"start":1494206770408327,"end":1494206770509335,"diff":101008},{"start":1494206770528652,"end":1494206770631578,"diff":102926},{"start":1494206770647797,"end":1494206770747859,"diff":100062},{"start":1494206770765548,"end":1494206770867965,"diff":102417},{"start":1494206770886691,"end":1494206770987855,"diff":101164},{"start":1494206771005091,"end":1494206771109830,"diff":104739},{"start":1494206771128716,"end":1494206771232337,"diff":103621},{"start":1494206771248012,"end":1494206771349838,"diff":101826},{"start":1494206771365666,"end":1494206771466317,"diff":100651},{"start":1494206771487556,"end":1494206771587493,"diff":99937},{"start":1494206771604596,"end":1494206771706327,"diff":101731},{"start":1494206771723950,"end":1494206771829104,"diff":105154},{"start":1494206771848362,"end":1494206771953584,"diff":105222},{"start":1494206771969172,"end":1494206772068773,"diff":99601},{"start":1494206772085726,"end":1494206772187713,"diff":101987},{"start":1494206772206919,"end":1494206772307671,"diff":100752},{"start":1494206772324224,"end":1494206772428707,"diff":104483},{"start":1494206772447422,"end":1494206772551415,"diff":103993},{"start":1494206772565886,"end":1494206772667642,"diff":101756},{"start":1494206772683792,"end":1494206772786930,"diff":103138},{"start":1494206772805753,"end":1494206772907988,"diff":102235},{"start":1494206772924008,"end":1494206773028491,"diff":104483},{"start":1494206773044222,"end":1494206773143722,"diff":99500},{"start":1494206773160609,"end":1494206773263149,"diff":102540},{"start":1494206773283759,"end":1494206773387419,"diff":103660},{"start":1494206773402781,"end":1494206773507114,"diff":104333},{"start":1494206773522665,"end":1494206773625288,"diff":102623},{"start":1494206773641770,"end":1494206773744901,"diff":103131},{"start":1494206773762539,"end":1494206773865802,"diff":103263},{"start":1494206773886477,"end":1494206773987869,"diff":101392},{"start":1494206774004039,"end":1494206774108124,"diff":104085},{"start":1494206774124670,"end":1494206774229088,"diff":104418},{"start":1494206774249597,"end":1494206774349661,"diff":100064},{"start":1494206774367052,"end":1494206774469541,"diff":102489},{"start":1494206774485046,"end":1494206774589062,"diff":104016},{"start":1494206774604825,"end":1494206774709945,"diff":105120},{"start":1494206774726422,"end":1494206774827135,"diff":100713},{"start":1494206774845401,"end":1494206774948749,"diff":103348}],"now":1494206774955,"mem":{"start":{"process":{"rss":47665152,"heapTotal":27873280,"heapUsed":15259488,"external":1589786},"os":561700864},"end":{"process":{"rss":60219392,"heapTotal":41517056,"heapUsed":29748920,"external":17476},"os":558870528}},"stats":{"moe":0.000490172560907551,"rme":0.4771310123609116,"sem":0.0002500880412793627,"deviation":0.001750616288955539,"mean":0.1027333265306122,"sample":[0.105656,0.102345,0.102844,0.105098,0.100314,0.104655,0.104171,0.100669,0.099827,0.103476,0.104253,0.101115,0.103011,0.100129,0.102509,0.101221,0.104802,0.10369,0.101899,0.100711,0.100007,0.1018,0.105248,0.105285,0.099658,0.102053,0.100938,0.104549,0.104067,0.101825,0.103208,0.102337,0.104574,0.099617,0.10261,0.103763,0.104401,0.102684,0.103203,0.103346,0.1015,0.104149,0.104499,0.100124,0.102574,0.104086,0.105197,0.100781,0.103455],"variance":0.0000030646573911564633},"count":1,"hz":9.733939645203863,"time":102.7333265306122,"cycles":1,"battery":{"amperage":3199,"currentCapacity":1783,"percent":23,"charging":"","temp":3108}},{"msg":"single1 x 9.73 ops/sec ±0.48% (49 runs sampled)","name":"single1","num":9.73,"sampled":"49","variation":"0.48","suite":["/Users/james/code/fluents/chain/packages/bench-chain/example/single1.json"],"timesFor":[{"start":1494206769073064,"end":1494206769178427,"diff":105363},{"start":1494206769204975,"end":1494206769307121,"diff":102146},{"start":1494206769326453,"end":1494206769429178,"diff":102725},{"start":1494206769445460,"end":1494206769550394,"diff":104934},{"start":1494206769566295,"end":1494206769666517,"diff":100222},{"start":1494206769683793,"end":1494206769788376,"diff":104583},{"start":1494206769809014,"end":1494206769913117,"diff":104103},{"start":1494206769932738,"end":1494206770033338,"diff":100600},{"start":1494206770051026,"end":1494206770150653,"diff":99627},{"start":1494206770166759,"end":1494206770270172,"diff":103413},{"start":1494206770285695,"end":1494206770389883,"diff":104188},{"start":1494206770408327,"end":1494206770509335,"diff":101008},{"start":1494206770528652,"end":1494206770631578,"diff":102926},{"start":1494206770647797,"end":1494206770747859,"diff":100062},{"start":1494206770765548,"end":1494206770867965,"diff":102417},{"start":1494206770886691,"end":1494206770987855,"diff":101164},{"start":1494206771005091,"end":1494206771109830,"diff":104739},{"start":1494206771128716,"end":1494206771232337,"diff":103621},{"start":1494206771248012,"end":1494206771349838,"diff":101826},{"start":1494206771365666,"end":1494206771466317,"diff":100651},{"start":1494206771487556,"end":1494206771587493,"diff":99937},{"start":1494206771604596,"end":1494206771706327,"diff":101731},{"start":1494206771723950,"end":1494206771829104,"diff":105154},{"start":1494206771848362,"end":1494206771953584,"diff":105222},{"start":1494206771969172,"end":1494206772068773,"diff":99601},{"start":1494206772085726,"end":1494206772187713,"diff":101987},{"start":1494206772206919,"end":1494206772307671,"diff":100752},{"start":1494206772324224,"end":1494206772428707,"diff":104483},{"start":1494206772447422,"end":1494206772551415,"diff":103993},{"start":1494206772565886,"end":1494206772667642,"diff":101756},{"start":1494206772683792,"end":1494206772786930,"diff":103138},{"start":1494206772805753,"end":1494206772907988,"diff":102235},{"start":1494206772924008,"end":1494206773028491,"diff":104483},{"start":1494206773044222,"end":1494206773143722,"diff":99500},{"start":1494206773160609,"end":1494206773263149,"diff":102540},{"start":1494206773283759,"end":1494206773387419,"diff":103660},{"start":1494206773402781,"end":1494206773507114,"diff":104333},{"start":1494206773522665,"end":1494206773625288,"diff":102623},{"start":1494206773641770,"end":1494206773744901,"diff":103131},{"start":1494206773762539,"end":1494206773865802,"diff":103263},{"start":1494206773886477,"end":1494206773987869,"diff":101392},{"start":1494206774004039,"end":1494206774108124,"diff":104085},{"start":1494206774124670,"end":1494206774229088,"diff":104418},{"start":1494206774249597,"end":1494206774349661,"diff":100064},{"start":1494206774367052,"end":1494206774469541,"diff":102489},{"start":1494206774485046,"end":1494206774589062,"diff":104016},{"start":1494206774604825,"end":1494206774709945,"diff":105120},{"start":1494206774726422,"end":1494206774827135,"diff":100713},{"start":1494206774845401,"end":1494206774948749,"diff":103348}],"now":1494206774955,"mem":{"start":{"process":{"rss":47665152,"heapTotal":27873280,"heapUsed":15259488,"external":1589786},"os":561700864},"end":{"process":{"rss":60239872,"heapTotal":41517056,"heapUsed":29777016,"external":17476},"os":558874624}},"stats":{"moe":0.000490172560907551,"rme":0.4771310123609116,"sem":0.0002500880412793627,"deviation":0.001750616288955539,"mean":0.1027333265306122,"sample":[0.105656,0.102345,0.102844,0.105098,0.100314,0.104655,0.104171,0.100669,0.099827,0.103476,0.104253,0.101115,0.103011,0.100129,0.102509,0.101221,0.104802,0.10369,0.101899,0.100711,0.100007,0.1018,0.105248,0.105285,0.099658,0.102053,0.100938,0.104549,0.104067,0.101825,0.103208,0.102337,0.104574,0.099617,0.10261,0.103763,0.104401,0.102684,0.103203,0.103346,0.1015,0.104149,0.104499,0.100124,0.102574,0.104086,0.105197,0.100781,0.103455],"variance":0.0000030646573911564633},"count":1,"hz":9.733939645203863,"time":102.7333265306122,"cycles":1,"battery":{"amperage":3199,"currentCapacity":1783,"percent":23,"charging":"","temp":3108}}]}}
\ No newline at end of file
diff --git a/_modules/bench-chain/package.json b/_modules/bench-chain/package.json
new file mode 100644
index 0000000..30c6b38
--- /dev/null
+++ b/_modules/bench-chain/package.json
@@ -0,0 +1,72 @@
+{
+ "version": "0.5.2",
+ "name": "bench-chain",
+ "description": "benchmark recording - averages & graphs.",
+ "main": "src/index",
+ "scripts": {
+ "examples": "node example/asyncs && node example/basic && node example/configstore && node example/single",
+ "test": "ava --verbose",
+ "docs": "jsdoc"
+ },
+ "dependencies": {
+ "obj-chain-core": "0.0.7",
+ "obj-chain-plugin-config": "0.0.7",
+ "benchmark": "2.1.4",
+ "cli-table2": "^0.2.0",
+ "flipchain": "*",
+ "flipfile": "*",
+ "fliplog": "^1.0.4",
+ "funwithflags": "*",
+ "lodash.debounce": "^4.0.8",
+ "lodash.flatten": "^4.4.0",
+ "lodash.forown": "^4.4.0",
+ "script-chain": "*"
+ },
+ "devDependencies": {
+ "ava": "*",
+ "doxdox": "*",
+ "fosho": "0.0.12",
+ "jsdoc": "3.4.3",
+ "jsdoc-api": "3.0.0",
+ "jsdoc-babel": "^0.3.0",
+ "tui-jsdoc-template": "^1.1.0",
+ "fluent-skeleton": "*"
+ },
+ "keywords": [
+ "benchmark",
+ "ui",
+ "average",
+ "graph",
+ "time",
+ "record"
+ ],
+ "author": "James ",
+ "license": "MIT",
+ "bugs": {
+ "url": "https://github.com/aretecode/bench-chain"
+ },
+ "homepage": "https://github.com/aretecode/bench-chain",
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/aretecode/bench-chain.git"
+ },
+ "jsdocs": {
+ "source": {
+ "include": [
+ "readme.md",
+ "src"
+ ],
+ "includePattern": ".+\\.js(doc)?$"
+ },
+ "opts": {
+ "recurse": true,
+ "destination": "./jsdocs",
+ "template": "node_modules/tui-jsdoc-template",
+ "package": "package.json"
+ },
+ "plugins": [
+ "node_modules/jsdoc-babel",
+ "plugins/markdown"
+ ]
+ }
+}
diff --git a/_modules/bench-chain/src/BenchChain.js b/_modules/bench-chain/src/BenchChain.js
new file mode 100644
index 0000000..16a6240
--- /dev/null
+++ b/_modules/bench-chain/src/BenchChain.js
@@ -0,0 +1,646 @@
+/* eslint max-lines: "off" */
+/* eslint import/no-dynamic-require: "off" */
+
+const {Suite} = require('benchmark')
+const log = require('fliplog')
+const Fun = require('funwithflags')
+const ChainedMap = require('./_chains')
+const battery = require('./battery')
+const {getCurrentMemory, debounce} = require('./deps')
+const Interface = require('./UI')
+const Reporter = require('./reports/Report')
+const Results = require('./Results')
+
+const fliptime = log.fliptime()
+const {microtime} = fliptime
+
+// cli arguments
+const argv = Fun(process.argv.slice(2), {
+ default: {
+ runTimes: 1,
+ graph: false,
+ dry: false,
+ debug: false,
+ noTags: false,
+ noGraph: false,
+ configStore: false,
+ reasoning: false,
+ help: false,
+ noChart: false,
+ },
+ bool: [
+ 'graph', 'debug',
+ 'no-graph',
+ 'no-tags',
+ 'silent',
+ 'configStore',
+ 'reasoning',
+ 'help',
+ 'noChart',
+ ],
+ alias: {
+ noGraph: 'silent',
+ configStore: ['file', 'config-store'],
+ reasoning: ['calculations'],
+ },
+ camel: true,
+ unknown(arg, fun) {
+ if (fun.i === 0) fun.argv.runTimes = Number(arg)
+ },
+})
+let {runTimes, graph, dry, debug, noGraph, noTags, configStore, reasoning, help, noChart} = argv
+
+if (help) {
+ const chalk = log.chalk()
+ log
+ .underline('bench-chain: --help')
+ .fmtobj({
+ '--runTimes': {
+ type: chalk.blue('Number'),
+ default: 1,
+ description: 'run the benchmarks multiple times',
+ },
+ '--graph': {
+ type: chalk.blue('Boolean'),
+ default: false,
+ description: 'only show the graph',
+ },
+ '--noGraph': {
+ type: chalk.blue('Boolean'),
+ default: false,
+ description: 'do not show the graph',
+ },
+ '--dry': {
+ type: chalk.blue('Boolean'),
+ default: false,
+ description: 'do not run the graph',
+ },
+ '--debug': {
+ type: chalk.blue('Boolean'),
+ default: false,
+ description: 'verbose debugging information',
+ },
+ '--configStore': {
+ type: chalk.blue('Boolean'),
+ default: false,
+ description: 'use configstore instead of the json file in source',
+ },
+ '--reasoning': {
+ type: chalk.blue('Boolean'),
+ default: false,
+ description: 'show math calculation reasoning for slower/faster',
+ },
+ })
+ .echo()
+ .exit()
+
+ process.exit()
+}
+
+/**
+ * @prop {string} store.dir directory
+ * @prop {boolean} store.debug very verbose
+ * @prop {Object} store.memory memory when started
+ * @prop {number} store.testNames names of tests, useful for length
+ * @prop {string} store.suiteName benchmarkjs suite name, defaults to filename
+ * @prop {string} store.rel relative path to results json file
+ * @prop {string} store.abs absolute path to results json file
+ * @prop {Object} ui class for helping with spinners etc
+ * @prop {Object} results class with json contents of file
+ * @prop {Object} current current event target object
+ * @prop {Array} timesFor microtime | performance.now times
+ *
+ * @TODO memoize subscriber cb check and normal for loop
+ */
+class BenchChain extends ChainedMap {
+ constructor() {
+ super()
+ this.timesFor = {}
+ this.tag = ''
+
+ /* prettier-ignore */
+
+ this
+ .extend([
+ 'dir',
+ 'debug',
+ 'testNames',
+ 'memory',
+ 'subscribers',
+ 'configStore',
+ 'reasoning',
+ // 'showTags',
+ ])
+ .method('index').autoIncrement().build()
+ .debug(debug)
+ .reasoning(reasoning)
+ // .showTags(!noTags)
+ .testNames([])
+ .memory(getCurrentMemory())
+ .subscribers({
+ cycle: [],
+ complete: [],
+ allComplete: [],
+ })
+ .set('index', 0)
+
+ this.echo = debounce(this.echo.bind(this), 2000)
+
+ /* prettier-enable */
+ }
+
+ /**
+ * @param {string} [dir=null] directory for the file with the record
+ * @param {string} [filename=null] filename for benchmark
+ * @param {string} [debugOverride=false] debugOverride
+ * @return {BenchChain} @chainable
+ */
+ static init(dir = null, filename = null, debugOverride = false) {
+ const bench = new BenchChain()
+
+ if (debugOverride !== false) bench.debug(debugOverride)
+ if (dir !== null) bench.dir(dir)
+ if (filename !== null) bench.filename(filename)
+
+ // for just use as a factory method
+ if (!dir && !filename) return bench
+
+ return bench.setup()
+ }
+
+ /**
+ * @since 0.3.0
+ * @param {string} name test name
+ * @return {BenchChain} @chainable
+ */
+ name(name) {
+ return this.set('suiteName', name)
+ }
+
+ /**
+ * @since 0.2.0
+ * @param {string} tags tag current benchmarks with
+ * @return {BenchChain} @chainable
+ */
+ tags(tags) {
+ return this.set('tags', tags)
+ }
+
+ // --- events ---
+
+ /**
+ * @event setup
+ * @since 0.4.0
+ * @param {Function} cb
+ * @return {BenchChain} @chainable
+ */
+ onSetup(cb) {
+ this.get('suite').on('setup', cb)
+ return this
+ }
+
+ /**
+ * @event cycle
+ * @since 0.4.0
+ * @param {Function} cb
+ * @return {BenchChain} @chainable
+ */
+ onCycle(cb) {
+ this.get('subscribers').cycle.push(cb)
+ return this
+ }
+
+ /**
+ * @event complete
+ * @since 0.4.0
+ * @param {Function} cb
+ * @return {BenchChain} @chainable
+ */
+ onComplete(cb) {
+ this.get('subscribers').complete.push(cb)
+ return this
+ }
+
+ /**
+ * @event allComplete
+ * @since 0.4.0
+ * @param {Function} cb
+ * @return {BenchChain} @chainable
+ */
+ onAllComplete(cb) {
+ this.get('subscribers').allComplete.push(cb)
+ return this
+ }
+
+ /**
+ * @event teardown
+ * @since 0.4.0
+ * @param {Function} cb
+ * @return {BenchChain} @chainable
+ */
+ onTeardown(cb) {
+ this.get('suite').on('teardown', cb)
+ return this
+ }
+
+ // --- helpers ---
+
+ /**
+ * @protected
+ * @since 0.4.0
+ * @see BenchChain.testName
+ * @param {boolean} [latest=false] only use latest data
+ * @return {Object} results, with test name when available
+ */
+ getResults(latest = false) {
+ return this.results.getForName(this.get('suiteName'), latest)
+ }
+
+ /**
+ * @see BenchChain.suite
+ * @desc filters benchmark results for fastest
+ * @since 0.1.0
+ * @return {Array} test case name
+ */
+ fastest() {
+ return this.get('suite').filter('fastest').map('name')
+ }
+
+ // --- file ---
+
+ /**
+ * @desc save and load file for the results
+ * @since 0.2.0
+ * @param {String} [filename='./results.json']
+ * @return {BenchChain} @chainable
+ */
+ filename(filename = './results.json') {
+ this.results = Results.init(this, configStore)
+ .setup(this.get('dir'), filename)
+ .load()
+
+ return this.setup()
+ }
+
+ // --- subscribers ---
+
+ /**
+ * @protected
+ * @since 0.2.0
+ * @desc handles benchmark cycle event
+ * @see BenchChain.results, BenchChain.current
+ * @param {Benchmark.Event} event
+ * @return {BenchChain} @chainable
+ */
+ _onCycle(event) {
+ const now = Date.now()
+ const mem = {
+ start: this.get('memory'),
+ end: getCurrentMemory(),
+ }
+
+ const tags = this.get('tags')
+ const suite = this.get('suiteName')
+ const hz = event.target.hz < 100 ? 2 : 0
+ const num = Number(event.target.hz.toFixed(hz))
+
+ // @example "optimized x 42,951 ops/sec ±3.45% (65 runs sampled)"
+ const msg = event.target.toString()
+ const sampled = msg.split('% (').pop().split(' runs').shift()
+ const variation = msg.split('±').pop().split('%').shift()
+
+ const {target} = event
+ const {stats, count, cycles, errors, name} = target
+ const timesFor = this.timesFor[name]
+
+ const result = {
+ msg,
+ name,
+ num,
+ sampled,
+ variation,
+ tags,
+ suite: [suite],
+ timesFor,
+ now,
+ mem,
+ stats,
+ count,
+ hz: target.hz,
+ time: stats.mean * 1000,
+ cycles,
+ }
+
+ // optimize
+ if (battery) result.battery = battery
+ if (errors) result.errors = errors
+
+ this.current = result
+
+ this.results.add(this.get('suiteName'), name, result)
+
+ return this
+ }
+
+ /**
+ * @protected
+ * @desc after all benchmarks
+ * @since 0.4.0
+ * @return {BenchChain} @chainable
+ */
+ _onAllCompleted() {
+ const {subscribers, suiteName} = this.entries()
+ subscribers.allComplete.forEach(cb => cb.call(this, this))
+
+ log.cyan('finished! ' + JSON.stringify(suiteName)).echo(this.get('debug'))
+
+ this.ui.onAllComplete(suiteName)
+
+ this.results.save()
+ this.echo()
+
+ return this
+ }
+
+ /**
+ * @protected
+ * @since 0.4.0
+ * @NOTE complete is called at the end of *EACH* bench
+ * @param {Benchmark.Event} event
+ * @return {BenchChain} @chainable
+ */
+ _onComplete(event) {
+ const {testNames, index, subscribers} = this.entries()
+ subscribers.complete.forEach(cb => cb.call(this, this))
+
+ const indexSaysDone = index === testNames.length
+ const eventSaysDone = event.currentTarget.length === testNames.length
+
+ if (indexSaysDone || eventSaysDone) this._onAllCompleted(event)
+ else this.index()
+
+ // log.dim('completed ' + testNames[index]).json(event).echo(this.get('debug'))
+ log
+ .dim('completed ' + testNames[index])
+ .data({
+ current: index,
+ total: testNames.length,
+ targetLen: event.currentTarget.length,
+ })
+ .echo(this.get('debug'))
+
+ return this
+ }
+
+ // --- suite ---
+
+ /**
+ * @see BenchChain.setup
+ * @param {string} [override=null] defaults to this., or this.paths.abs
+ * @return {Benchmark.Suite}
+ */
+ suite(override = null) {
+ const suiteName =
+ override || this.get('suiteName') || this.results.get('abs')
+
+ this.name(suiteName)
+
+ this.set('suite', new Suite(suiteName))
+
+ return this.get('suite')
+ }
+
+ /**
+ * @desc subscribes onCycle and onComplete
+ * @since 0.1.0
+ * @return {BenchChain} @chainable
+ */
+ setup() {
+ if (!this.has('suite')) this.suite()
+
+ // setup ui
+ this.ui = new Interface(this)
+
+ // setup file
+ // @TODO
+
+ // setup name
+ if (!this.get('suiteName')) {
+ const rel = this.results
+ .get('rel')
+ .replace('json', '')
+ .replace(/[./]/g, '')
+
+ this.name(rel)
+ }
+
+ // bind the callbacks
+ const cycle = this._onCycle.bind(this)
+ const onComplete = this._onComplete.bind(this)
+
+ // subscribe
+ this.get('suite').on('cycle', event => cycle(event))
+ this.get('suite').on('complete', event => onComplete(event))
+
+ return this
+ }
+
+ // --- operations / bench helpers when not using suite / ---
+
+ /**
+ * @param {boolean} [asyncs=true]
+ * @return {BenchChain} @chainable
+ */
+ asyncMode(asyncs = true) {
+ return this.set('asyncMode', asyncs)
+ }
+
+ /**
+ * @protected
+ * @since 0.4.0
+ * @param {string} name
+ * @return {BenchChain} @chainable
+ */
+ addRecorder(name) {
+ const results = this.getResults()
+ const latest = this.getResults(true)
+
+ // use results object, or a new object
+ if (results !== undefined && results[name] === undefined) results[name] = []
+ else if (Array.isArray(results[name]) === false) results[name] = []
+
+ // same for latest
+ if (latest !== undefined && latest[name] === undefined) latest[name] = []
+ else if (Array.isArray(latest[name]) === false) latest[name] = []
+
+
+ this.get('testNames').push(name)
+
+ return this
+ }
+
+ /**
+ * @protected
+ * @since 0.2.0
+ * @desc should return empty calls to see baseline
+ * empty bench to get more raw overhead
+ *
+ * @see BenchChain.addAsync
+ * @param {string} name test name
+ * @param {Function} fn function to call deferred
+ * @return {BenchChain} @chainable
+ */
+ hijackAsync(name, fn) {
+ return async cb => {
+ if (!cb.reject) {
+ cb.reject = e => {
+ throw e
+ }
+ }
+
+ const times = {
+ start: null,
+ end: null,
+ }
+
+ const hjResolve = arg => {
+ times.end = microtime.now()
+ times.diff = times.end - times.start
+ return cb.resolve(arg)
+ }
+ const hjReject = arg => {
+ times.end = microtime.now()
+ times.diff = times.end - times.start
+ delete times.end
+ delete times.start
+
+ return cb.reject(arg)
+ }
+
+ hjResolve.reject = hjReject
+ hjResolve.resolve = hjResolve
+
+ this.timesFor[name] = this.timesFor[name] || []
+ this.timesFor[name].push(times)
+
+ // start timer after setup
+ times.start = microtime.now()
+
+ const called = await fn(hjResolve, hjReject)
+ if (called && called.then) {
+ called.then(arg => cb.resolve(arg))
+ }
+ return called
+ }
+ }
+
+ /**
+ * @since 0.2.0
+ * @desc add benchmark case (with defer)
+ * @param {string} name
+ * @param {Function} fn
+ * @return {BenchChain} @chainable
+ */
+ addAsync(name, fn) {
+ this.set('asyncMode', true)
+ this.get('suite').add(name, {
+ defer: true,
+ fn: this.hijackAsync(name, fn),
+ })
+
+ return this.addRecorder(name)
+ }
+
+ /**
+ * @desc add benchmark case
+ * @since 0.1.0
+ * @param {string} name
+ * @param {Function} fn
+ * @return {BenchChain} @chainable
+ */
+ add(name, fn) {
+ this.set('asyncMode', false)
+
+ this.get('suite').add(name, fn)
+
+ return this.addRecorder(name)
+ }
+
+ // --- ops ---
+
+ /**
+ * @since 0.1.0
+ * @desc calls setup, runs suite
+ * @return {BenchChain} @chainable
+ */
+ run() {
+ const {suiteName, asyncMode} = this.entries()
+
+ if (dry) {
+ log.warn('dry run').echo(this.get('debug'))
+ return this
+ }
+
+ if (graph === true) {
+ return this.echo()
+ }
+
+ log.cyan('starting! ' + JSON.stringify(suiteName)).echo(this.get('debug'))
+
+ this.ui.onRun(suiteName)
+ this.get('suite').run({async: asyncMode})
+
+ return this
+ }
+
+ /**
+ * @TODO merge with .run, disable logs until end of all
+ * @desc runs the suite test x times
+ * @since 0.2.0
+ * @param {Number} [times=runTimes] defaults to 1, allows first arg to be number of runs
+ * @return {BenchChain} @chainable
+ */
+ runTimes(times = runTimes) {
+ if (times === null) times = runTimes
+
+ const total = log.colored(times, 'bold')
+
+ for (let i = 0; i < times; i++) {
+ const current = log.colored(i, 'bold')
+ const running = log.colored('running ', 'dim')
+ const msg = `${running} ${current}/${total}`
+
+ log.yellow('reset suite: ').data(msg).echo()
+
+ this.get('suite').reset()
+ this.get('suite').run({async: this.get('asyncMode')})
+ }
+
+ return this
+ }
+
+ /**
+ * @see this.filename
+ * @NOTE debounced
+ * @since 0.2.0
+ * @desc instantiates Reporter, does echoing of numbers
+ * @return {BenchChain} @chainable
+ */
+ echo() {
+ if (noGraph) return this
+
+ const reporter = new Reporter(this)
+ console.log('\n')
+ reporter.echoFastest()
+ reporter.echoAvgs()
+ reporter.echoPercent()
+ if (!noTags) reporter.echoTags()
+ if (!noChart) reporter.echoAvgGraph()
+ if (!noChart) reporter.echoTrend()
+ reporter.echoOps()
+
+ return this
+ }
+}
+
+module.exports = BenchChain
diff --git a/_modules/bench-chain/src/Results.js b/_modules/bench-chain/src/Results.js
new file mode 100644
index 0000000..4990ed1
--- /dev/null
+++ b/_modules/bench-chain/src/Results.js
@@ -0,0 +1,195 @@
+/* eslint import/no-dynamic-require: "off" */
+const {resolve} = require('path')
+const exists = require('flipfile/exists')
+const write = require('flipfile/write')
+const log = require('fliplog')
+const ObjChain = require('obj-chain-core')
+const ChainedMap = require('./_chains')
+
+/**
+ * @TODO: should use obj-chain for the file as well so just a file swap, same api
+ */
+module.exports = class Results extends ChainedMap {
+ /**
+ * @param {BenchChain} parent
+ * @param {boolean} [configStore=false] use configstore
+ * @return {Results}
+ */
+ static init(parent, configStore = false) {
+ return new Results(parent, configStore)
+ }
+
+ /**
+ * @param {BenchChain} parent
+ * @param {boolean} [configStore=false] use configstore
+ */
+ constructor(parent, configStore = false) {
+ super(parent)
+
+ if (configStore) {
+ this.configStore(configStore)
+ }
+
+ if (parent && parent.has && parent.has('debug')) {
+ this.debug(parent.get('debug'))
+ }
+ else {
+ this.debug(false)
+ }
+ }
+
+ /**
+ * @desc use configstore via obj-chain (for easy escaping of `dot` syntax)
+ * @since 0.4.4
+ * @param {boolean} use
+ * @return {BenchChain} @chainable
+ */
+ configStore(use = true) {
+ const configStore = new ObjChain({}, ['config']).setup().dot(false)
+ return this.set('configStore', configStore)
+ }
+
+ /**
+ * @since 0.5.0
+ * @desc add data to record
+ * @param {string} suiteName bench suite name
+ * @param {string} name name of test
+ * @param {Object} result data to record
+ * @return {Results} @chainable
+ */
+ add(suiteName, name, result) {
+ const data1 = this.getForName(suiteName)
+ const data2 = this.getForNameLatest(suiteName)
+
+ if (!data1[name]) data1[name] = []
+ if (!data2[name]) data2[name] = []
+ data1[name].push(result)
+ data2[name].push(result)
+
+ return this
+ }
+
+ /**
+ * @since 0.5.0
+ * @desc latest run results only
+ * @param {string} name suite name
+ * @return {Object} results
+ */
+ getForNameLatest(name) {
+ if (name !== undefined) {
+ if (this.latest[name] === undefined) {
+ this.latest[name] = {}
+ }
+ return this.latest[name]
+ }
+ return this.latest
+ }
+
+ /**
+ * @since 0.4.1
+ * @desc gets results from file keyed
+ * @param {string} name suite name
+ * @param {boolean} [latest=false] latest run results only
+ * @return {Object} results
+ */
+ getForName(name, latest = false) {
+ if (latest === true) {
+ return this.getForNameLatest(name)
+ }
+
+ if (name !== undefined) {
+ if (this.data[name] === undefined) {
+ this.data[name] = {}
+ }
+ return this.data[name]
+ }
+ return this.data
+ }
+
+ /**
+ * @desc resolve file, paths to file
+ * sets abs: absolute path
+ * sets rel: relative path
+ * @since 0.4.1
+ * @param {string} dir
+ * @param {string} filename
+ * @return {BenchChain} @chainable
+ */
+ setup(dir, filename) {
+ if (filename && !filename.includes('.json') && !filename.includes('.js')) {
+ filename = filename + '.json'
+ }
+ const rel = filename || './results.json'
+ const abs = resolve(dir, rel)
+ return this.set('abs', abs).set('rel', rel)
+ }
+
+ /**
+ * @protected
+ * @desc load from file or configstore (still a file but diff)
+ * @since 0.2.0
+ * @see BenchChain.results
+ * @param {boolean} [force=false] force reload
+ * @return {BenchChain} @chainable
+ */
+ load(force = false) {
+ if (this.data && force === false) return this
+
+ let {abs, configStore} = this.entries()
+ this.latest = {}
+
+ if (abs.includes('configstore') && !configStore) {
+ configStore = this.configStore(true).get('configStore')
+
+ log
+ .green('results loaded from configstore: ')
+ .json({'(cmd + click)': log.colored(configStore.path, 'underline')})
+ .echo()
+ }
+
+ // use configstore
+ if (configStore) {
+ log.underline('using configstore').echo(this.get('debug'))
+ if (!configStore.has(abs)) {
+ configStore.set(abs, {})
+ }
+ this.data = configStore.get(abs) || {}
+
+ return this
+ }
+
+ if (exists(abs) === false) write(abs, '{}')
+
+ this.data = require(abs)
+ log.green('loading').echo(this.get('debug'))
+
+ return this
+ }
+
+ /**
+ * @protected
+ * @since 0.2.0
+ * @desc saves to file or configstore
+ * @see BenchChain.load, BenchChain.filename
+ * @return {BenchChain} @chainable
+ */
+ save() {
+ log.green('saving').echo(this.get('debug'))
+ const {configStore, abs} = this.entries()
+
+ if (configStore) {
+ configStore.set(abs, JSON.stringify(this.data))
+
+ log
+ .green('results saved to: ')
+ .json({'(cmd + click)': log.colored(configStore.path, 'underline')})
+ .echo()
+
+ return this
+ }
+
+ write(abs, JSON.stringify(this.data))
+
+ return this
+ }
+}
diff --git a/_modules/bench-chain/src/UI.js b/_modules/bench-chain/src/UI.js
new file mode 100644
index 0000000..aa8eab3
--- /dev/null
+++ b/_modules/bench-chain/src/UI.js
@@ -0,0 +1,108 @@
+/* eslint lines-around-comment: "off" */
+
+const log = require('fliplog')
+const {Remember} = require('script-chain')
+const ChainedMap = require('./_chains')
+
+/**
+ * @see configstore
+ * @see script-chain
+ * @prop {Remember} remember script to remember durations in configstore
+ */
+module.exports = class BenchChainUserInterface extends ChainedMap {
+ constructor(parent) {
+ super(parent)
+ this.remember = new Remember()
+ }
+
+ /**
+ * @event onAllComplete
+ * @param {string} name
+ * @return {BenchChainUserInterface} @chainable
+ */
+ onRun(name) {
+ this.remember.start(name, true)
+ this.spinner()
+ return this
+ }
+
+ /**
+ * @event onAllComplete
+ * @param {string} name
+ * @return {BenchChainUserInterface} @chainable
+ */
+ onAllComplete(name) {
+ this.remember.finish(name, true)
+ this.clearSpinners()
+ return this
+ }
+
+ /**
+ * @desc add a pseudo animated
+ * @since 0.4.1
+ * @return {BenchChain} @chainable
+ */
+ spinner() {
+ /**
+ * @see this.spinning
+ * @desc adds spinner for benchmarking
+ * @type {Function}
+ */
+ this.spin = () => {
+ log.addSpinner('benchmarking', 'benchmarking')
+ log.startSpinners([
+ ' 🏋️',
+ ' 🏋️',
+ ' 🏎',
+ ' 🏎 ',
+ ' 🏎 ∞',
+ ' 🏎 ∞ ',
+ ' 🏎 ∞∞ ',
+ ' 🏎 ∞∞ ',
+ ' 🏎 ∞ ',
+ '🏎 ∞∞ ',
+ ])
+ }
+ this.spin()
+
+ /**
+ * @see this.spinning
+ * @desc interval every 10 seconds swaps animated benchmarking for progress
+ * @type {Function}
+ */
+ this.removeSpinner = () => {
+ try {
+ log.removeSpinner()
+ }
+ catch (e) {
+ // ignore
+ }
+
+ // reset and clear terminal
+ log.clear()
+ }
+
+ /**
+ * @see this.spinning
+ * @desc interval every 10 seconds swaps animated benchmarking for progress
+ * @type {Function}
+ */
+ this.spinning = setInterval(() => {
+ this.removeSpinner()
+ this.spinAgain = setTimeout(() => this.spin(), 4000)
+ }, 10000)
+
+ /**
+ * @see this.spinning
+ * @desc function to clear interval and reset back
+ * @type {Function}
+ */
+ this.clearSpinners = () => {
+ clearInterval(this.spinning)
+ clearTimeout(this.spinAgain)
+ this.removeSpinner()
+ }
+
+ return this
+ }
+}
diff --git a/_modules/bench-chain/src/_chains.js b/_modules/bench-chain/src/_chains.js
new file mode 100644
index 0000000..adc47a5
--- /dev/null
+++ b/_modules/bench-chain/src/_chains.js
@@ -0,0 +1,3 @@
+const Chain = require('../../../exports')
+
+module.exports = Chain
diff --git a/_modules/bench-chain/src/battery.js b/_modules/bench-chain/src/battery.js
new file mode 100644
index 0000000..88a3bca
--- /dev/null
+++ b/_modules/bench-chain/src/battery.js
@@ -0,0 +1,44 @@
+const {execFileSync} = require('child_process')
+
+const cmd = 'ioreg'
+const args = ['-n', 'AppleSmartBattery', '-r', '-a']
+
+function strip(i) {
+ return i.replace(/[\n\r\t]/gim, '').replace(/<\/?[^>]+(>|$)/g, '')
+}
+
+function plist(str) {
+ const data = {}
+ let current = {}
+ str.split('\n').forEach(item => {
+ if (item.includes('key') === true) {
+ current.key = strip(item)
+ }
+ else {
+ current.val = strip(item)
+ data[current.key] = current.val
+ current = {}
+ }
+ })
+ return data
+}
+
+function battery() {
+ if (process.platform !== 'darwin') return 'NA: ' + process.platform
+ return plist(execFileSync(cmd, args).toString())
+}
+
+const b = battery()
+
+let Battery = {}
+if (process.platform === 'darwin') {
+ Battery = {
+ amperage: Number(b.Amperage),
+ currentCapacity: Number(b.CurrentCapacity),
+ percent: Math.floor(b.Current / b.Capacity * 100),
+ charging: b.IsCharging,
+ temp: Number(b.Temperature),
+ }
+}
+
+module.exports = Battery
diff --git a/_modules/bench-chain/src/cli.js b/_modules/bench-chain/src/cli.js
new file mode 100644
index 0000000..e69de29
diff --git a/_modules/bench-chain/src/deps.js b/_modules/bench-chain/src/deps.js
new file mode 100644
index 0000000..edd26e9
--- /dev/null
+++ b/_modules/bench-chain/src/deps.js
@@ -0,0 +1,280 @@
+const os = require('os')
+
+function uniq(value, index, arr) {
+ return arr.indexOf(value) === index
+}
+
+/**
+ * @param {Function[]} funcs functions to flow left to right
+ * @return {Function} passes args through the functions, bound to this
+ */
+function flow(...funcs) {
+ const length = funcs ? funcs.length : 0
+ return function flowing(...args) {
+ let index = 0
+ // eslint-disable-next-line
+ let result = length ? funcs[index].apply(this, args) : args[0]
+ while (++index < length) {
+ // eslint-disable-next-line
+ result = funcs[index].call(this, result)
+ }
+ return result
+ }
+}
+
+/**
+ * Converts a number to a more readable comma-separated string representation.
+ *
+ * @static
+ * @param {number} number The number to convert.
+ * @return {string} The more readable string representation.
+ */
+function formatNumber(number) {
+ number = String(number).split('.')
+ return (
+ number[0].replace(/(?=(?:\d{3})+$)(?!\b)/g, ',') +
+ (number[1] ? '.' + number[1] : '')
+ )
+}
+
+/**
+ * @tutorial http://stackoverflow.com/questions/5799055/calculate-percentage-saved-between-two-numbers
+ * @param {number} value
+ * @param {number} other
+ * @return {number}
+ */
+function calcTimes(value, other) {
+ const diff = other / value
+
+ // require('fliplog').quick({value, other, diff, fixed, end2, end3, end4, end5, end6, fixed2})
+
+ return diff
+}
+
+/**
+ * @tutorial http://www.randomsnippets.com/2009/07/12/dynamic-or-on-the-fly-percentage-calculations-with-javascript/
+ * @param {number} oldval
+ * @param {number} newval
+ * @return {number}
+ */
+function calcPercent(oldval, newval) {
+ var percentsavings = ((oldval - newval) / oldval) * 100
+ return Math.round(percentsavings * 100) / 100
+}
+
+/**
+ * @NOTE mutates obj
+ * @param {Function} cb
+ * @return {Function} to call with callback obj
+ */
+function flowVals(cb) {
+ /**
+ * @param {Object} obj
+ * @return {Object}
+ */
+ return function flowCb(obj) {
+ const keys = Object.keys(obj)
+ for (let i = 0; i < keys.length; i++) {
+ const val = obj[keys[i]].map(str => str.length)
+ obj[keys[i]] = cb(val)
+ }
+ return obj
+ }
+}
+
+/**
+ * @param {Array} data
+ * @return {number} average
+ */
+function average(data) {
+ const sum = data.reduce((prev, curr) => 0 + prev + curr, 0)
+ return Math.floor(sum / data.length)
+}
+
+function standardDeviation(values) {
+ const avg = average(values)
+ const squareDiffs = values.map(value => {
+ const diff = value - avg
+ const sqrDiff = diff * diff
+ return sqrDiff
+ })
+ const avgSquareDiff = average(squareDiffs)
+ const stdDev = Math.sqrt(avgSquareDiff)
+ return stdDev
+}
+
+/**
+ * @private
+ * @desc divide by this number for nicer numbers
+ * @param {number} max
+ * @return {number}
+ */
+function getDiv(max) {
+ switch (true) {
+ case max > 1000:
+ return 100
+ case max > 10000:
+ return 1000
+ case max > 100000:
+ return 10000
+ case max > 1000000:
+ return 100000
+ case max > 10000000:
+ return 1000000
+ default:
+ return 1
+ }
+}
+
+// const flowmin = flow(Math.floor, Math.min)
+// const flowmax = flow(Math.floor, Math.max)
+const flowmin = nums => Math.floor(Math.min(...nums))
+const flowmax = nums => Math.floor(Math.max(...nums))
+// const flowmax = nums => {
+// if (!nums) return 0
+// return Math.floor(nums.reduce((a, b) => Math.max(a, b)))
+// }
+// const flowmin = nums => {
+// if (!nums) return 0
+// return Math.floor(nums.reduce((a, b) => Math.min(a, b)))
+// }
+//
+function getCurrentMemory(init = null) {
+ return {
+ process: process.memoryUsage(),
+ os: os.freemem(),
+ }
+}
+
+const _flatten = require('lodash.flatten')
+const flatten = arr => [].concat.apply(arr)
+const forown = require('lodash.forown')
+
+const mapown = (obj, cb) => {
+ const mapped = []
+ forown(obj, (value, key, o) => {
+ mapped.push(cb(value, key, o))
+ })
+ return mapped
+}
+
+const mapObjArr = (obj, cb) => {
+ const mapped = []
+ forown(obj, (value, key, o) => {
+ mapped.push(mapown(value, cb))
+ // mapped.push(cb(value, key, o))
+ })
+ return _flatten(mapped)
+}
+
+function groupBy(arr, property) {
+ return arr.reduce((memo, x) => {
+ if (!memo[x[property]]) {
+ memo[x[property]] = []
+ }
+ memo[x[property]].push(x)
+ return memo
+ }, {})
+}
+
+// https://github.com/netcode/node-prettydate/blob/master/index.js
+function createHandler(divisor, noun, restOfString) {
+ return function(diff) {
+ var n = Math.floor(diff / divisor)
+ var pluralizedNoun = noun + (n > 1 ? 's' : '')
+ return '' + n + ' ' + pluralizedNoun + ' ' + restOfString
+ }
+}
+
+var formatters = [
+ {threshold: -31535999, handler: createHandler(-31536000, 'year', 'from now')},
+ {threshold: -2591999, handler: createHandler(-2592000, 'month', 'from now')},
+ {threshold: -604799, handler: createHandler(-604800, 'week', 'from now')},
+ {threshold: -172799, handler: createHandler(-86400, 'day', 'from now')},
+ {
+ threshold: -86399,
+ handler() {
+ return 'tomorrow'
+ },
+ },
+ {threshold: -3599, handler: createHandler(-3600, 'hour', 'from now')},
+ {threshold: -59, handler: createHandler(-60, 'minute', 'from now')},
+ {threshold: -0.9999, handler: createHandler(-1, 'second', 'from now')},
+ {
+ threshold: 1,
+ handler() {
+ return 'just now'
+ },
+ },
+ {threshold: 60, handler: createHandler(1, 'second', 'ago')},
+ {threshold: 3600, handler: createHandler(60, 'minute', 'ago')},
+ {threshold: 86400, handler: createHandler(3600, 'hour', 'ago')},
+ {
+ threshold: 172800,
+ handler() {
+ return 'yesterday'
+ },
+ },
+ {threshold: 604800, handler: createHandler(86400, 'day', 'ago')},
+ {threshold: 2592000, handler: createHandler(604800, 'week', 'ago')},
+ {threshold: 31536000, handler: createHandler(2592000, 'month', 'ago')},
+ {threshold: Infinity, handler: createHandler(31536000, 'year', 'ago')},
+]
+
+function prettydate(date) {
+ var diff = (new Date().getTime() - date.getTime()) / 1000
+ for (var i = 0; i < formatters.length; i++) {
+ if (diff < formatters[i].threshold) {
+ return formatters[i].handler(diff)
+ }
+ }
+ throw new Error('exhausted all formatter options, none found') // should never be reached
+}
+
+const debounce = require('lodash.debounce')
+
+// https://github.com/chalk/ansi-regex/blob/master/index.js
+const ansiRegex = /[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-PRZcf-nqry=><]/g
+const replaceAnsi = str => str.replace(ansiRegex, '')
+
+// https://github.com/uxitten/polyfill/blob/master/string.polyfill.js
+// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/repeat
+if (!String.prototype.padEnd) {
+ String.prototype.padEnd = function padEnd(targetLength, padString) {
+ targetLength = targetLength >> 0 // floor if number or convert non-number to 0;
+ padString = String(padString || ' ')
+ if (this.length > targetLength) {
+ return String(this)
+ }
+ else {
+ targetLength = targetLength - this.length
+ if (targetLength > padString.length) {
+ padString += padString.repeat(targetLength / padString.length) // append to original to ensure we are longer than needed
+ }
+ return String(this) + padString.slice(0, targetLength)
+ }
+ }
+}
+
+module.exports = {
+ replaceAnsi,
+ uniq,
+ flow,
+ calcTimes,
+ calcPercent,
+ flowVals,
+ average,
+ getDiv,
+ standardDeviation,
+ flowmin,
+ flowmax,
+ getCurrentMemory,
+ flatten,
+ forown,
+ mapown,
+ mapObjArr,
+ _flatten,
+ groupBy,
+ prettydate,
+ debounce,
+}
diff --git a/_modules/bench-chain/src/index.js b/_modules/bench-chain/src/index.js
new file mode 100644
index 0000000..020dd2d
--- /dev/null
+++ b/_modules/bench-chain/src/index.js
@@ -0,0 +1,13 @@
+const log = require('fliplog')
+const pkg = require('../package.json')
+const BenchChain = require('./BenchChain')
+
+log.registerCatch()
+
+// @TODO every time a bench is added, should register all here, for multi benches
+// const suites = {}
+
+BenchChain.Bench = BenchChain
+BenchChain.log = log
+BenchChain.version = pkg.version
+module.exports = BenchChain
diff --git a/_modules/bench-chain/src/reports/GraphReporter.js b/_modules/bench-chain/src/reports/GraphReporter.js
new file mode 100644
index 0000000..7723d59
--- /dev/null
+++ b/_modules/bench-chain/src/reports/GraphReporter.js
@@ -0,0 +1,189 @@
+const log = require('fliplog')
+let {average, getDiv, flowmin, flowmax, flatten} = require('../deps')
+
+const {tillNow} = log.fliptime()
+
+module.exports = class GraphReporter {
+ constructor(parent) {
+ this.parent = parent
+ this.debug = parent.debug
+ this.loopResults = parent.loopResults.bind(parent)
+ this.filterIfNeeded = parent.filterIfNeeded.bind(parent)
+ this.avgs = parent.avgs.bind(parent)
+ // this.trend = parent.trend.bind(parent)
+ }
+
+ /**
+ * @TODO: abstract this
+ * @see deps/getDiv
+ *
+ * @desc go through results,
+ * get max and min,
+ * pretty print numbers
+ *
+ * @return {Object} trend graph data
+ */
+ trend() {
+ const trend = {}
+
+ this.loopResults((value, name) => {
+ let timesFor
+ let nums
+
+ // skip for now
+ if (!value || !value[0]) {
+ log.yellow(name + ' had no value - yet').echo(this.debug)
+ return
+ }
+
+ if (value[0].timesFor) {
+ // remap
+ timesFor = value
+ .filter(v => v.timesFor)
+ .map(entry => entry.timesFor.map(t => t.diff))
+
+ // flatten
+ let nums1 = flatten(timesFor)
+
+ // average
+ nums = nums1.map(numnum => average(numnum))
+ }
+ else {
+ // log.quick('good')
+ nums = value.map(entry => entry.num)
+ }
+
+ // min max
+ let min = flowmin(nums)
+ let max = flowmax(nums)
+ const div = getDiv(max)
+ if (this.max < max) this.max = max
+ if (this.min < min) this.min = min
+
+ // filter anomolies
+ nums = this.filterIfNeeded({nums, min, max, div})
+
+ log.json({max, min, div}).text('trendy').echo(this.debug)
+
+ max = max / div
+ min = min / div
+
+ // into graph points
+ const points = nums
+ .map((r, i) => {
+ if (Math.floor(r / (div || 1)) === 0) return 0
+ return [i, Math.floor(r / (div || 1))]
+ })
+ .filter(r => r !== 0)
+
+ // into graph points from date
+ const datePoints = nums
+ .map((r, i) => {
+ let key = i
+
+ const {ms, s, m, h, d, y} = tillNow(value[key].now)
+ key = i
+
+ if (m === 0) return 0
+ return [key, m]
+ })
+ .filter(r => r !== 0)
+
+ trend[name] = {points, datePoints, max, min}
+ })
+
+ // log.cyan('all trend data').verbose(100).data(trend).echo(this.debug)
+
+ return trend
+ }
+
+ /**
+ * @see Record.trend
+ * @return {Record} @chainable
+ */
+ echoTrend() {
+ const graphs = this.trend()
+
+ Object.keys(graphs).forEach(name => {
+ console.log('\n')
+ const {points, datePoints, max, min} = graphs[name]
+
+ log
+ .magenta('verbose graph:')
+ .verbose(100)
+ .data(graphs[name])
+ .echo(this.debug)
+
+ log.data({points, datePoints, max, min}).echo(this.debug)
+
+ log
+ .barStyles({
+ color: 'green',
+ width: 150,
+ height: 10,
+ maxY: max,
+ yFractions: 0,
+ caption: name,
+ })
+ .bar(points)
+ .echo(this.shouldEcho)
+
+ log
+ .barStyles({
+ color: 'yellow',
+ width: 150,
+ height: 10,
+ yFractions: 0,
+ caption: name + ' over time' + log.colored(' (minutes):', 'dim'),
+ })
+ .bar(datePoints)
+ .echo(false)
+ // .echo(this.shouldEcho)
+ })
+
+ return this
+ }
+
+ /**
+ * @since 0.0.2
+ * @see Record.avgs
+ * @TODO transform data to trim
+ * @return {Record} @chainable
+ */
+ echoAvgGraph() {
+ const avgs = this.avgs()
+ const nums = Object.keys(avgs).map(name => Number(avgs[name]))
+ const max = flowmax(nums)
+ const min = flowmin(nums)
+ const div = getDiv(max) // * 10
+
+ if (this.max < max) this.max = max
+ if (this.min < min) this.min = min
+
+ // log.data({avgs, nums, max, min, div}).echo(thisdebug)
+
+ const points = Object.keys(avgs).map((name, i) => {
+ return [i, Math.floor(avgs[name] / div)]
+ })
+
+ // , {max, min, nums, points}
+ log.blue('averages of: ').data(Object.keys(avgs)).echo(this.debug)
+
+ log
+ .barStyles({
+ color: 'blue',
+ maxY: Math.floor(max / div),
+ minY: Math.floor(min / div),
+ // width: 150,
+ // height: 100,
+ // yFractions: 0,
+ // xFractions: 0,
+ caption: 'averages of all:',
+ })
+ .bar(points)
+ .echo(false)
+ // .echo(this.shouldEcho)
+
+ return this
+ }
+}
diff --git a/_modules/bench-chain/src/reports/PercentReporter.js b/_modules/bench-chain/src/reports/PercentReporter.js
new file mode 100644
index 0000000..c98b1ff
--- /dev/null
+++ b/_modules/bench-chain/src/reports/PercentReporter.js
@@ -0,0 +1,271 @@
+// %%% %%%%%%%%%%%%%%% %%%
+// %%% percent calcs %%%
+// %%% %%%%%%%%%%%%%%% %%%
+
+const log = require('fliplog')
+const Table = require('cli-table2')
+let {
+ padEnd,
+ calcTimes,
+ flowVals,
+ calcPercent,
+ flowmax,
+ forown,
+ replaceAnsi,
+} = require('../deps')
+
+/**
+ * @see Reporter.avgs
+ * @see Reporter.asyncMode
+ */
+module.exports = class PercentReporter {
+ constructor(parent) {
+ this.reasoning = parent.reasoning
+ this.asyncMode = parent.asyncMode
+ this.suiteName = parent.parent.get('suiteName')
+ this.avgs = parent.avgs.bind(parent)
+ }
+
+ /**
+ * @protected
+ * @see [x] https://github.com/aretecode/bench-chain/issues/2
+ *
+ * @desc compares two numbers,
+ * calculates times & percent,
+ * adjusts wording based on results
+ * calculate the positive and negatives * / x / times more/less
+ *
+ * @NOTE when in not-async mode,
+ * it was using cycle ops instead of microtime diffs
+ * but to simplify now both use the same
+ * also because the hz in ops can be below 0
+ * throwing off the calculations
+ *
+ * @since 0.4.1
+ * @param {number} value
+ * @param {number} other
+ * @return {Object} {end, fixed, percent, word}
+ */
+ calculatePercent(value, other) {
+ const higherIsBetter = !this.asyncMode
+
+ const data = {
+ higherIsBetter,
+ firstIsMore: value > other,
+ negative: false,
+ xy: calcTimes(value, other),
+ yx: calcTimes(other, value),
+ xyf: Math.floor(calcTimes(value, other)),
+ yxf: Math.floor(calcTimes(other, value)),
+ yxpercent: Math.floor(calcPercent(other, value)),
+ xypercent: Math.floor(calcPercent(value, other)),
+ }
+
+ // default usually
+ const shouldUseTimes = () => {
+ return data.xyf !== 0 && data.yxf === 0
+ }
+ // if higher is better, if the calculates are revered, fix
+ const shouldUseTimesFlipped = () => {
+ return data.xyf === 0 && data.yxf !== 0 // && higherIsBetter
+ }
+ // usually used if below 0 && higher is not better
+ const shouldUsePercent = () => {
+ return data.xyf === 1 || data.yxf === 1
+ }
+ // check the calculations to return formatted string
+ const format = () => {
+ if (shouldUseTimes()) {
+ return data.xyf + 'X'
+ }
+ if (shouldUseTimesFlipped()) {
+ return data.yxf + 'X'
+ }
+ if (shouldUsePercent()) {
+ return data.yxpercent + '%'
+ }
+
+ return data.yxf + 'X'
+ }
+ const slowerOrFaster = () => {
+ // all nots
+ if (!higherIsBetter && !data.firstIsMore && !data.negative) {
+ return 'faster'
+ }
+ if (higherIsBetter && data.firstIsMore && !data.negative) {
+ return 'faster'
+ }
+
+ return 'slower'
+ }
+
+ data.calculated = {
+ msg: format() + ' ' + slowerOrFaster(),
+ slowerOrFaster: slowerOrFaster(),
+ shouldUseTimes: shouldUseTimes(),
+ shouldUseTimesFlipped: shouldUseTimesFlipped(),
+ shouldUsePercent: shouldUsePercent(),
+ formatted: format(),
+ }
+
+ log.bold('======\n').fmtobj(data).echo(this.reasoning)
+
+ const word = slowerOrFaster()
+ const end = format()
+
+ return {end, word}
+ }
+
+ /**
+ * @TODO needs cleaning
+ *
+ * @since 0.3.0
+ * @desc
+ * uses microtime recordings & benchmarkjs data
+ * to go through an average of averages
+ * then compare each result to each other to show how many times
+ * faster/slower they are
+ *
+ * @return {Record} @chainable
+ */
+ echoPercent() {
+ const avgs = this.avgs()
+ const names = Object.keys(avgs)
+ const values = Object.values(avgs)
+ const pcts = []
+ const parts = {
+ name: [],
+ val: [],
+ diff: [],
+ word: [],
+ compare: [],
+ otherVal: [],
+ }
+
+ // add each part in so we know the lengths of each to padd
+ const addPart = part => {
+ parts.name.push(part.name)
+ parts.val.push(part.val)
+ parts.word.push(part.word)
+ parts.diff.push(part.diff)
+ parts.compare.push(part.compare)
+ parts.otherVal.push(part.otherVal)
+ pcts.push(part)
+ }
+
+ // go through each name
+ // then go through each other name to compare
+ names.forEach((name, n) =>
+ names.forEach((compare, i) => {
+ if (compare === name) return
+
+ const value = values[n]
+ const other = avgs[compare]
+ const {end, word} = this.calculatePercent(value, other)
+
+ // format
+ let vc = log.colored(value + '', 'green.underline')
+ let oc = log.colored(other + '', 'green.underline')
+ let ec = log.colored(end, 'bold')
+ let wc = log.colored(word, 'italic') + ' than'
+ let ns = [log.colored(name, 'cyan'), log.colored(compare, 'blue')]
+
+ // wrap strings
+ vc = `(${vc})`
+ oc = `(${oc})`
+
+ // put the parts into an array to format padding
+ addPart({
+ name: ns[0],
+ val: vc,
+ diff: ec,
+ word: wc,
+ compare: ns[1],
+ otherVal: oc,
+ })
+ })
+ )
+
+ return this.echoPaddedAverages(pcts, names, parts).echoAvgTable(pcts, names)
+ }
+
+ /**
+ * @protected
+ * @since 0.4.1
+ * @param {Array} pcts paddedColoredParts
+ * @param {Array} names testnames
+ * @param {Array} parts array of parts before padding and coloring
+ * @return {Reporter} @chainable
+ */
+ echoPaddedAverages(pcts, names, parts) {
+ console.log('\n')
+ let suiteName = this.suiteName
+
+ if (suiteName.includes('/')) {
+ suiteName = suiteName.split('/').pop()
+ }
+ if (suiteName.includes('.json')) {
+ suiteName = suiteName.split('.json').shift()
+ }
+
+ log.bold(suiteName).echo()
+ if (names[0]) {
+ console.log('🏆 ' + log.colored(names[0].split(' ').shift(), 'underline'))
+ }
+
+ // padd end for pretty string
+ const longests = flowVals(flowmax)(Object.assign({}, parts))
+ pcts.forEach(pct => {
+ let str = ''
+ forown(pct, (v, k) => {
+ if (k === 'msg') return
+
+ // pad first
+ v = v.padEnd(longests[k] + 2)
+
+ // because these emoji have different lengths in chars
+ // but not terminal size so we replace here
+ if (v.includes('faster')) {
+ v = v.replace(/(faster)/g, '🏎️') // 🏎️ ⚡
+ }
+ else if (v.includes('slower')) {
+ v = v.replace(/(slower)/g, '🐌')
+ }
+ v = v.replace(/(than)/g, log.colored(' than', 'dim'))
+
+ str += v
+ })
+ console.log(str)
+ })
+ console.log('\n')
+
+ return this
+ }
+
+ /**
+ * @protected
+ * @since 0.4.1
+ * @param {Array} pcts paddedColoredParts
+ * @param {Array} names testnames
+ * @return {Reporter} @chainable
+ */
+ echoAvgTable(pcts, names) {
+ const avgLong = this.avgs()
+ const table = new Table({head: pcts.map(p => p.name)})
+
+ const rows = pcts.map((p, i) => {
+ const strippedName = replaceAnsi(p.name)
+ if (!avgLong[strippedName]) {
+ log.red('could not average it out' + p.name).echo()
+ // log.quick({avgLong, names, strippedName, i, p})
+ return ''
+ }
+
+ return avgLong[strippedName]
+ })
+
+ table.push(rows)
+ console.log(table.toString())
+ return this
+ }
+}
diff --git a/_modules/bench-chain/src/reports/Report.js b/_modules/bench-chain/src/reports/Report.js
new file mode 100644
index 0000000..3b6691c
--- /dev/null
+++ b/_modules/bench-chain/src/reports/Report.js
@@ -0,0 +1,282 @@
+const log = require('fliplog')
+const ChainedMap = require('flipchain/ChainedMapExtendable')
+let {average, flowmin, flowmax, flatten, mapown, mapObjArr} = require('../deps')
+const TagReporter = require('./TagReporter')
+const PercentReporter = require('./PercentReporter')
+const GraphReporter = require('./GraphReporter')
+
+/**
+ * @TODO
+ * - [ ] deepmerge multi results
+ * - [ ] graph comparisons
+ * @type {Class}
+ */
+module.exports = class Report extends ChainedMap {
+ constructor(parent) {
+ super(parent)
+
+ const {debug, asyncMode, reasoning} = parent.entries()
+
+ this.fastest = parent.fastest.bind(parent)
+ this.getResults = (latest = false) => this.parent.getResults(latest)
+ this.getNames = () => this.parent.get('testNames')
+ this.getResultsWithNames = () => {
+ return {names: this.getNames(), results: this.getResults()}
+ }
+
+ // @TODO improve
+ this.reasoning = reasoning
+ this.shouldEcho = true
+ this.shouldFilter = false
+ this.asyncMode = asyncMode
+ this.debug = debug
+ this.max = 0
+ this.min = 0
+ this.mean = 0
+
+ this.tagReporter = new TagReporter(this)
+ this.percentReporter = new PercentReporter(this)
+ this.graphReporter = new GraphReporter(this)
+
+ this.echoAvgGraph = this.graphReporter.echoAvgGraph.bind(this.graphReporter)
+ this.echoTrend = this.graphReporter.echoTrend.bind(this.graphReporter)
+ this.echoPercent = () => {
+ this.percentReporter.echoPercent()
+ }
+ this.echoTags = () => {
+ this.tagReporter.echoTagged()
+ }
+ }
+
+ // --- transformers (fbp here makes sense) ---
+
+ /**
+ * @since 0.2.0
+ * @see BenchChain.asyncMode
+ * @param {string} prop map to this property to average with that data
+ * @return {Averages} averages
+ */
+ avgs(prop = 'num') {
+ const avgs = {}
+ const {results, names} = this.getResultsWithNames()
+
+ log.blue('this.results').data({results, names}).echo(this.debug)
+
+ // results(keys[0]).timesFor
+ if (this.asyncMode) {
+ names.forEach(name => {
+ const value = results[name]
+
+ // skip for now
+ if (!value || !value[0] || !value[0].timesFor) {
+ log.yellow(name + ' had no value - yet').echo(this.debug)
+ return
+ }
+
+ // gather
+ const timesForMulti = value
+ .map(entry => {
+ log
+ .data(entry, entry.timesFor)
+ .red('ENTRY ' + entry.name)
+ .echo(this.debug)
+
+ if (entry.timesFor === undefined) {
+ // log.quick(entry)
+ return false
+ }
+ return entry.timesFor.map(t => t.diff)
+ })
+ .filter(val => val)
+
+ // flatten
+ const timesFor = flatten(timesForMulti).pop()
+
+ const max = flowmax(timesFor)
+ const min = flowmax(timesFor)
+ if (this.max < max) this.max = max
+ if (this.min < min) this.min = min
+
+ const avgavg = Math.abs(average(timesFor))
+
+ // more averages
+ const resultsForProp = value.map(result => avgavg)
+ const avg = average(resultsForProp)
+
+ log
+ .blue('averages')
+ .data({name, resultsForProp, avg, avgavg, timesFor})
+ .echo(this.debug)
+
+ avgs[name] = avg
+ })
+ }
+ else {
+ return this.propAvg()
+ }
+
+ return avgs
+ }
+
+ /**
+ * @desc same as avg, but using a specific prop
+ * @since 0.4.1
+ * @param {String} [prop='num']
+ * @return {Array}
+ */
+ propAvg(prop = 'num') {
+ const avgs = {}
+ const {results, names} = this.getResultsWithNames()
+
+ names.forEach(name => {
+ const resultsForProp = results[name].map(result => Number(result[prop]))
+ const avg = average(resultsForProp)
+ log.blue('averages').data({name, resultsForProp, avg}).echo(this.debug)
+ avgs[name] = avg
+ })
+
+ return avgs
+ }
+
+ // --- echoing helpers 2 ---
+
+ /**
+ * @since 0.4.1
+ * @param {Function} cb
+ * @return {Array} mapped results
+ */
+ loopResults(cb) {
+ return mapown(this.getResults(), cb)
+ }
+
+ /**
+ * @desc filters numbers outside of the usual range if needed
+ * @param {number} nums
+ * @param {number} min
+ * @param {number} max
+ * @return {Array}
+ */
+ filterIfNeeded({nums, min, max}) {
+ if (!this.shouldFilter) return nums
+
+ nums = nums.filter(nn => {
+ const minp = min * 1.1
+ const maxp = max / 1.1
+
+ log
+ .data({
+ nn,
+ minp,
+ maxp,
+ max,
+ min,
+ passes: nn >= minp && nn <= maxp,
+ })
+ .echo(false)
+
+ return nn >= minp // && (nn <= maxp)
+ })
+
+ return nums
+ }
+
+ /**
+ * @param {number} avg
+ * @return {string} color
+ */
+ colorForAvg(avg) {
+ const avgMin = avg > this.min * 1.1
+ const minmin = avg > this.min * 1.1
+ const minish = avg > this.min * 1.5
+ const abvAvg = avg > this.max / 1.3
+ const avgish = avg > this.max / 1.1
+ const wow = avg > this.max / 1.05
+ if (wow) return 'bold'
+ if (avgish) return 'green'
+ if (abvAvg || minish) return 'dim'
+ if (avgMin) return 'yellow'
+ if (minmin) return 'red'
+ return 'red'
+ }
+
+ // --- simple echos ---
+
+ /**
+ * @see Record.avgs
+ * @TODO transform data to trim
+ * @return {Record} @chainable
+ */
+ echoAvgs() {
+ // in async mode, uses microtime diffs as ops are not as reliable
+ let msg = 'lower is better, time taken in microseconds'
+
+ // when in sync mode, it is ops/second instead
+ if (!this.asyncMode) {
+ msg = 'higher is better, operations per second'
+ }
+
+ log
+ .color('dim.italic')
+ .text(msg)
+ .echo()
+
+ log
+ .fmtobj(this.avgs())
+ .bold('averages:')
+ .echo(this.shouldEcho)
+
+ return this
+ }
+
+ /**
+ * @see Record.fastest
+ * @return {Record} @chainable
+ */
+ echoFastest() {
+ log
+ .verbose(this.fastest().shift())
+ .underline('Fastest is ')
+ .echo(this.shouldEcho)
+
+ return this
+ }
+
+ /**
+ * @since 0.4.1
+ * @desc very long message echoing
+ * for all cycles of all test echoing,
+ * should filter
+ * @return {Record} @chainable
+ */
+ echoOps() {
+ this.getResults()
+ const {results, names} = this.getResultsWithNames()
+ const msgs = []
+
+ msgs.push('-----')
+ names.forEach(name => {
+ const value = results[name].slice(0).reverse()
+ let limit = 10
+ for (let i = 0; i < limit && i < value.length; i++) {
+ if (!value[i].msg) {
+ limit++
+ continue
+ }
+ msgs.push(value[i].msg)
+ }
+
+ msgs.push('-----')
+ })
+
+ log.bold('\n\noperations per second\n').echo()
+ msgs.forEach(msg => console.log(msg))
+
+ // works too, but harder to filter
+ // const msgs = mapObjArr(this.getResults(), data => data.msg).reverse()
+
+ return this
+ }
+ // --- -------------- ---
+ // --- graph building ---
+ // --- -------------- ---
+}
diff --git a/_modules/bench-chain/src/reports/TagReporter.js b/_modules/bench-chain/src/reports/TagReporter.js
new file mode 100644
index 0000000..73f883d
--- /dev/null
+++ b/_modules/bench-chain/src/reports/TagReporter.js
@@ -0,0 +1,158 @@
+// ### ############
+// ### tags ###
+// ### ############
+
+const log = require('fliplog')
+const Table = require('cli-table2')
+let {forown, mapown, groupBy, prettydate} = require('../deps')
+
+/**
+ * @see Reporter.getResultsWithNames
+ * @see Reporter.avgs
+ * @see Reporter.colorForAvg
+ * @see Reporter.debug
+ * @see Reporter.loopResults
+ */
+module.exports = class TableReporter {
+ constructor(parent) {
+ this.parent = parent
+ this.debug = parent.debug
+ this.getResultsWithNames = parent.getResultsWithNames.bind(parent)
+ this.loopResults = parent.loopResults.bind(parent)
+ this.avgs = parent.avgs.bind(parent)
+ this.colorForAvg = parent.colorForAvg.bind(parent)
+ }
+
+ /**
+ * @see this._regroupTags
+ * @see this._makeTagTableRows
+ * @desc makes a table, regroups tags, puts tags into a table
+ * @since 0.4.1
+ * @return {Reports} @chainable
+ */
+ echoTagged() {
+ const table = new Table({
+ hAlign: 'center',
+ head: ['name', 'tags', 'averages', 'time'],
+ })
+
+ const regrouped = this._regroupTags()
+ const tds = this._makeTagTableRows(regrouped)
+
+ table.push(...tds)
+ console.log(table.toString())
+
+ return this
+ }
+
+ /**
+ * @desc regroup results by tag with pretty dates
+ * @since 0.4.1
+ * @param {Object} [grouped={}]
+ * @param {Object} [tagged={}]
+ * @param {Object} [regrouped={}]
+ * @return {Object} regrouped
+ */
+ _regroupTags(grouped = {}, tagged = {}, regrouped = {}) {
+ this.loopResults((v, name) => {
+ grouped[name] = groupBy(v, 'tags')
+ tagged[name] = Object.keys(grouped[name]).map(tag => tag.split(','))
+ regrouped[name] = {}
+ })
+
+ // scoped vars for following loops
+ const tagKeys = Object.keys(tagged)
+ let tagIndex = 0
+
+ // go through each test (by name)
+ mapown(tagged, (tags, testNameAsTag) => {
+ const key = tagKeys[tagIndex]
+
+ // go through each test case (by tag index)
+ mapown(tags, (tag, index, obj) => {
+ // setup
+ let uniqTags = tag.slice(0)
+ const tagStr = tag.join(',')
+
+ // get tests for first test for first time tag was used
+ const tests = grouped[testNameAsTag][tagStr] // [ti]
+
+ if (!tests) {
+ log
+ .data({
+ group: grouped[testNameAsTag],
+ atTag: grouped[testNameAsTag][tagStr],
+ tagStr,
+ testNameAsTag,
+ tagIndex,
+ })
+ .red('no tests somehow when tagging')
+ .echo()
+ return
+ }
+
+ let firstTest = tests[tagIndex]
+
+ // @NOTE: @TODO:
+ // was putting data on at complete,
+ // not at cycle,
+ // so data needs transforming
+ if (!firstTest || !firstTest.now) return
+
+ // prettify
+ const uniqTagStr = uniqTags
+ .map(t => log.colored(' ' + t + ' ', 'bgBlack.yellow'))
+ .join(', ')
+
+ const uniqKey = uniqTagStr + ' @' + prettydate(new Date(firstTest.now))
+
+ log.data({uniqKey, uniqTagStr, uniqTags}).echo(this.debug)
+
+ // change the keys
+ regrouped[testNameAsTag][uniqKey] = tests
+ })
+
+ tagIndex++
+ })
+
+ return regrouped
+ }
+
+ /**
+ * @protected
+ * @since 0.4.1
+ * @param {Object} regrouped results indexed by tagged
+ * @param {Array} [tds=[]]
+ * @return {Array} table rows
+ */
+ _makeTagTableRows(regrouped, tds = []) {
+ forown(regrouped, (v, name) => {
+ const groups = Object.keys(regrouped[name])
+ const ref = this.getResultsWithNames
+
+ forown(regrouped[name], (groupName, group, obj, i) => {
+ this.parent.getResultsWithNames = () => ({
+ names: groups,
+ results: obj,
+ })
+
+ const avgs = this.avgs()
+
+ const td = mapown(avgs, (avg, tag) => {
+ const pretty = tag.split('@')
+ const pureTag = pretty.shift()
+ const time = pretty.pop()
+ avg = log.colored(avg, this.colorForAvg(avg))
+ return {[name]: [pureTag, avg, time]}
+ })
+
+ tds = tds.concat(td)
+ })
+
+ // restore
+ this.parent.getResultsWithNames = ref
+ })
+
+ return tds
+ }
+}
diff --git a/_modules/bench-chain/test/adding.js b/_modules/bench-chain/test/adding.js
new file mode 100644
index 0000000..8f7bf45
--- /dev/null
+++ b/_modules/bench-chain/test/adding.js
@@ -0,0 +1,30 @@
+/* eslint no-return-await: "off" */
+const test = require('ava')
+const {fosho} = require('fosho')
+const Bench = require('../src')
+
+const sleep = sleepDuration =>
+ new Promise(resolve => setTimeout(resolve, sleepDuration))
+
+test('can add bench cases', t => {
+ const bench = new Bench()
+ bench
+ .dir(__dirname)
+ .filename('configstore-adding-test-basic')
+ .add('case1', () => 1 + 1)
+ .add('case2', () => 1 * 1)
+ .add('case3', () => 1 / 1)
+
+ fosho(bench.suite, t).obj()
+ t.pass()
+})
+
+test('can add async bench cases', t => {
+ const bench = Bench.init(__dirname, 'configstore-adding-test-async')
+ .addAsync('case1', async () => await sleep(100))
+ .addAsync('case2', async () => await sleep(200))
+ .addAsync('case31', async () => await sleep(100))
+
+ fosho(bench.suite, t).obj()
+ t.pass()
+})
diff --git a/_modules/bench-chain/test/chain.js b/_modules/bench-chain/test/chain.js
new file mode 100644
index 0000000..2c89aa8
--- /dev/null
+++ b/_modules/bench-chain/test/chain.js
@@ -0,0 +1,19 @@
+const test = require('ava')
+const {fosho} = require('fosho')
+const Bench = require('../src')
+
+test('can instantiate', t => {
+ const record = new Bench(__dirname)
+ t.true(record instanceof Bench)
+})
+
+test('can chain filename and dir', t => {
+ const bench = new Bench()
+ bench.dir(__dirname).filename('configstore-adding-test-chain')
+ fosho(bench.get('dir'), t).isString()
+})
+
+test('can use init insteadof chain', t => {
+ const bench = Bench.init(__dirname, 'configstore-adding-test-chain')
+ fosho(bench.get('dir'), t).isString()
+})
diff --git a/_modules/bench-chain/test/cli.js b/_modules/bench-chain/test/cli.js
new file mode 100644
index 0000000..d885ca8
--- /dev/null
+++ b/_modules/bench-chain/test/cli.js
@@ -0,0 +1,7 @@
+const test = require('ava')
+const Bench = require('../src')
+
+test.todo('can run multiple times')
+test.todo('can dry run')
+test.todo('can debug')
+test.todo('can debug')
diff --git a/_modules/bench-chain/test/index.js b/_modules/bench-chain/test/index.js
new file mode 100644
index 0000000..4ad2eff
--- /dev/null
+++ b/_modules/bench-chain/test/index.js
@@ -0,0 +1,20 @@
+const test = require('ava')
+const {fosho} = require('fosho')
+const Bench = require('../src')
+
+test.todo('benchmark reports over time')
+test.todo('benchmark test ranges')
+test.todo('benchmark stdout with flags')
+test.todo('benchmark onCycles contain ...data...')
+test.todo('can subscribe to lifecycle events')
+
+test.failing('can add multiple suites', t => {
+ Bench.init()
+ .dir(__dirname)
+ .addSuite('one')
+ .filename('configstore-adding-test')
+ .add('bench1')
+ .add('bench2')
+
+ t.fail()
+})
diff --git a/_modules/bench-chain/test/persistance.js b/_modules/bench-chain/test/persistance.js
new file mode 100644
index 0000000..bc4f2ef
--- /dev/null
+++ b/_modules/bench-chain/test/persistance.js
@@ -0,0 +1,6 @@
+const test = require('ava')
+const {fosho} = require('fosho')
+const Bench = require('../src')
+
+test.todo('configstore')
+test.todo('file')
diff --git a/_modules/bench-chain/test/running.js b/_modules/bench-chain/test/running.js
new file mode 100644
index 0000000..1fc0c04
--- /dev/null
+++ b/_modules/bench-chain/test/running.js
@@ -0,0 +1,37 @@
+/* eslint no-return-await: "off" */
+const test = require('ava')
+const {fosho, log} = require('fosho')
+const Bench = require('../src')
+
+const sleep = sleepDuration =>
+ new Promise(resolve => setTimeout(resolve, sleepDuration))
+
+test('can run bench cases', t => {
+ const bench = new Bench()
+ bench
+ .dir(__dirname)
+ .filename('configstore.running-test-basic')
+ .add('case1', () => 1 + 1)
+ .add('case2', () => 1 * 1)
+ .add('case3', () => 1 / 1)
+ .run()
+
+ const data = bench.getResults()
+ fosho(data, t).obj()
+ fosho(data, t).obj()
+ fosho(data.case1, t).obj()
+})
+
+test('can run async bench cases', t => {
+ const bench = Bench.init(__dirname, 'configstore.running-test-async')
+ .addAsync('case1', async () => await sleep(100))
+ .addAsync('case2', async () => await sleep(200))
+ .addAsync('case31', async () => await sleep(100))
+ .run()
+
+ const data = bench.getResults()
+ fosho(data, t).obj()
+ fosho(data.case1, t).obj()
+ fosho(data.case2, t).obj()
+ fosho(data.case31, t).obj()
+})
diff --git a/_modules/frisbee/eh.js b/_modules/frisbee/eh.js
new file mode 100644
index 0000000..03950b4
--- /dev/null
+++ b/_modules/frisbee/eh.js
@@ -0,0 +1,28 @@
+require('isomorphic-fetch')
+const log = require('fliplog')
+const Frisbee = require('./src/frisbee')
+require('./test-setup')
+
+global._server.start()
+
+async function eh() {
+ const api = new Frisbee(global._options)
+ const querystring = {
+ a: 'blue',
+ b: 'cyan',
+ c: 'pink',
+ }
+ const getRes = await api.get('/querystring', {
+ body: querystring,
+ })
+
+ console.log(typeof getRes.body)
+ console.log(getRes.body)
+
+ const delRes = await api.get('/querystring', {
+ body: querystring,
+ })
+ console.log(typeof delRes.body)
+ console.log(delRes.body)
+}
+eh()
diff --git a/_modules/frisbee/package.json b/_modules/frisbee/package.json
new file mode 100644
index 0000000..17ed34a
--- /dev/null
+++ b/_modules/frisbee/package.json
@@ -0,0 +1,25 @@
+{
+ "name": "md-chain",
+ "scripts": {
+ "babs": "babel awesome-github.js > awesome-github-es6.js",
+ "build": "node js",
+ "test": "jest --verbose"
+ },
+ "jest": {
+ "setupTestFrameworkScriptFile": "./test-setup.js"
+ },
+ "devDependencies": {
+ "isomorphic-fetch": "*",
+ "express": "*",
+ "cors": "*",
+ "body-parser": "*",
+ "jest": "*"
+ },
+ "dependencies": {
+ "fliplog": "^1.0.4",
+ "qs": "*",
+ "frisbee": "^1.5.0",
+ "node-fetch": "^1.7.1",
+ "xmlhttprequest": "^1.8.0"
+ }
+}
diff --git a/_modules/frisbee/src/__tests__/node.test.js b/_modules/frisbee/src/__tests__/node.test.js
new file mode 100644
index 0000000..cb410eb
--- /dev/null
+++ b/_modules/frisbee/src/__tests__/node.test.js
@@ -0,0 +1,323 @@
+require('isomorphic-fetch')
+const log = require('fliplog')
+const Frisbee = require('../../src/frisbee')
+const { isError, isObj, isString, isNumber } = require('../chains')
+
+const standardMethods = ['get', 'post', 'put', 'del', 'patch']
+const methods = [].slice.call(standardMethods).concat(['head', 'options'])
+const server = global._server
+
+// log.registerCatch()
+
+// describe('node runtime', () => {
+let api
+
+// server.start()
+afterEach(() => server.start())
+beforeEach(() => server.stop())
+
+test('should have `fetch` defined', done => {
+ expect(fetch).toBeTruthy()
+ done()
+})
+
+//
+test('should throw an error if we fail to pass baseURI', done => {
+ // expect(new Frisbee).toThrow(new Error('baseURI option is required'));
+ expect(() => new Frisbee()).toThrow(/baseURI option is required/)
+ done()
+})
+
+test('should create Frisbee instance with all methods', done => {
+ console.log(global._options)
+ api = new Frisbee(global._options)
+ expect(isObj(api)).toBe(true)
+ methods.forEach(method => expect(typeof api[method]).toBe('function'))
+ done()
+})
+
+test('should throw errors for incorrect auth() usage', done => {
+ api = new Frisbee(global._options)
+ expect(() => api.auth({})).toThrow(/auth option `user` must be a string/)
+ expect(() => api.auth(new Array(3))).toThrow(
+ /auth option can only have two keys/
+ )
+ expect(() => api.auth([{}, ''])).toThrow(
+ /auth option `user` must be a string/
+ )
+ expect(() => api.auth(['', {}])).toThrow(
+ /auth option `pass` must be a string/
+ )
+ done()
+})
+
+test('should accept valid auth("user:pass") usage', done => {
+ api = new Frisbee(global._options)
+ const creds = 'foo:bar'
+ api.auth('foo:bar')
+ const basicAuthHeader = `Basic ${new Buffer(creds).toString('base64')}`
+ expect(api.headers.Authorization).toEqual(basicAuthHeader)
+ done()
+})
+
+test('should allow chaining of `auth` and an HTTP method', async done => {
+ api = new Frisbee(global._options)
+ try {
+ await api.auth('foo', 'bar').get('/')
+ }
+ catch (err) {
+ throw err
+ }
+ done()
+})
+
+test('should allow removal of auth() header', done => {
+ api = new Frisbee(global._options)
+
+ api.auth('foo')
+ // invalid auth
+ // expect(() => .toThrow(/user/)
+ api.auth()
+ expect(api.headers.Authorization).toBeFalsy()
+ done()
+})
+
+test(
+ 'should throw an error if we fail to pass a string `path`',
+ async done => {
+ api = new Frisbee(global._options)
+
+ try {
+ await api.get({})
+ }
+ catch (err) {
+ expect(err.message).toEqual('`path` must be a string')
+ }
+
+ done()
+ }
+)
+
+test('should throw an error if we fail to pass an object `options`', async done => {
+ api = new Frisbee(global._options)
+
+ try {
+ await api.get('', [])
+ }
+ catch (err) {
+ expect(err.message).toEqual('`options` must be an object')
+ }
+ try {
+ await api.get('', 1)
+ }
+ catch (err) {
+ expect(err.message).toEqual('`options` must be an object')
+ }
+ done()
+})
+
+test('should throw an error if we pass a non object `options`', async done => {
+ api = new Frisbee(global._options)
+ try {
+ await api.get('', false)
+ }
+ catch (err) {
+ expect(err.message).toEqual('`options` must be an object')
+ }
+ done()
+})
+
+test('should automatically set options to an empty object if not set', async done => {
+ api = new Frisbee(global._options)
+
+ try {
+ await api.get('')
+ }
+ catch (err) {
+ throw err
+ }
+
+ done()
+})
+
+standardMethods.forEach(method => {
+ const methodName = method === 'del' ? 'DELETE' : method.toUpperCase()
+
+ test(`should return 200 on ${methodName}`, async done => {
+ api = new Frisbee(global._options)
+
+ const opts = {}
+
+ if (method === 'post') opts.body = { foo: 'bar' }
+
+ try {
+ const res = await api[method]('/', opts)
+ expect(isObj(res)).toBe(true)
+ expect(isObj(res.body)).toBe(true)
+ }
+ catch (err) {
+ throw err
+ }
+
+ done()
+ })
+})
+
+standardMethods.forEach(method => {
+ const methodName = method === 'del' ? 'DELETE' : method.toUpperCase()
+
+ test(`should return 200 on ${methodName}`, async done => {
+ api = new Frisbee(global._options)
+
+ const opts = {}
+ if (method === 'post') opts.body = { foo: 'bar' }
+
+ try {
+ const res = await api[method]('/', opts)
+ expect(isObj(res)).toBe(true)
+ expect(isObj(res.body)).toBe(true)
+ }
+ catch (err) {
+ throw err
+ }
+
+ done()
+ })
+})
+
+test('should stringify querystring parameters for GET and DELETE requests', async done => {
+ api = new Frisbee(global._options)
+ const querystring = {
+ a: 'blue',
+ b: 'cyan',
+ c: 'pink',
+ }
+ const getRes = await api.get('/querystring', {
+ body: querystring,
+ })
+
+ expect(isObj(getRes.body)).toBe(true)
+ expect(getRes.body).toEqual(querystring)
+
+ const delRes = await api.get('/querystring', {
+ body: querystring,
+ })
+ expect(isObj(delRes.body)).toBe(true)
+ expect(delRes.body).toEqual(querystring)
+
+ done()
+})
+
+test('should stringify querystring parameters with arrayFormat for GET and DELETE requests', async done => {
+ api = new Frisbee(
+ Object.assign({}, global._options, { formatArray: 'brackets' })
+ )
+ const querystring = {
+ a: 'blue',
+ b: 'cyan',
+ c: 'pink',
+ d: ['1', '2', '3'],
+ }
+ const getRes = await api.get('/querystring', {
+ body: querystring,
+ })
+ expect(isObj(getRes.body)).toBe(true)
+ expect(getRes.body).toEqual(querystring)
+
+ const delRes = await api.get('/querystring', {
+ body: querystring,
+ })
+ expect(isObj(delRes.body)).toBe(true)
+ expect(delRes.body).toEqual(querystring)
+
+ done()
+})
+
+test('should URL encode querystring parameters for GET and DELETE requests', async done => {
+ api = new Frisbee(global._options)
+ const querystring = {
+ a: ' ',
+ b: '&foo&',
+ c: '$$%%%%',
+ }
+ const getRes = await api.get('/querystring', {
+ body: querystring,
+ })
+ expect(isObj(getRes.body)).toBe(true)
+ expect(getRes.body).toEqual(querystring)
+
+ const delRes = await api.del('/querystring', {
+ body: querystring,
+ })
+ expect(isObj(delRes.body)).toBe(true)
+ expect(delRes.body).toEqual(querystring)
+
+ done()
+})
+
+test('should return 404', async done => {
+ api = new Frisbee(global._options)
+ const res = await api.get('/404')
+ console.log('should return 404', { res, statusText: res.statusText })
+ console.log(res.statusText, 'statusText', res.statusText == 'Not Found')
+ // expect(isError(res.err)).toBe(true)
+ // expect(res.err.message).toEqual('Not Found')
+ expect(res.statusText).toEqual('Not Found')
+ done()
+})
+
+test('should return 404 with valid json', async done => {
+ api = new Frisbee(global._options)
+ const res = await api.get('/404-with-valid-json')
+ console.log('should return 404 with valid json', { res })
+
+ // expect(isError(res.err)).toBe(true)
+ // expect(res.err.message).toEqual('Bad Request')
+ expect(res.statusText).toEqual('Bad Request')
+ done()
+})
+
+test('should return 404 with invalid json', async done => {
+ api = new Frisbee(global._options)
+ try {
+ const res = await api.get('/404-with-invalid-json')
+ log.data(res).echo()
+ console.log(isError(res.err), res.err, 'isError___')
+ // expect(isError(res.err)).toBe(true)
+ expect(typeof (res.err)).toBe('object')
+ }
+ catch (e) {
+ log.data(e).red('e').echo()
+ }
+ // console.log('fetched, checking error message', res.err)
+ // invalid json response body at
+ // expect(res.err.message).toEqual(
+ // // @NOTE was Invalid JSON received from
+ // //
+ // `invalid json response body at ${global._options.baseURI}`
+ // )
+ done()
+})
+
+test('should return 404 with stripe error', async done => {
+ api = new Frisbee(global._options)
+ const res = await api.get('/404-with-stripe-error')
+ console.log('should return 404 with stripe error', res)
+ // expect(isError(res.err)).toBe(true)
+ expect(isString(res.err.message)).toBe(true)
+ // expect(isString(res.err.stack)).toBe(true)
+ // expect(isNumber(res.err.code)).toBe(true)
+ // expect(isString(res.err.param)).toBe('string')
+ done()
+})
+
+test('should return 400 with message', async done => {
+ api = new Frisbee(global._options)
+ const res = await api.get('/400-with-message')
+
+ // expect(isError(res.err)).toBe(true)
+ expect(res.body.message).toEqual('Oops!')
+ // expect(res.err.message).toEqual('Oops!')
+ done()
+})
+// })
diff --git a/_modules/frisbee/src/chains.js b/_modules/frisbee/src/chains.js
new file mode 100644
index 0000000..c116740
--- /dev/null
+++ b/_modules/frisbee/src/chains.js
@@ -0,0 +1,7 @@
+const Chainable = require('../../../src')
+const isJSON = require('../../../src/deps/is/JSON')
+
+Chainable.isJSON = Chainable.is.isJSON = isJSON
+Chainable.enhanceError = require('../../../src/deps/validators/error')
+
+module.exports = Chainable
diff --git a/_modules/frisbee/src/frisbee.js b/_modules/frisbee/src/frisbee.js
new file mode 100644
index 0000000..1caac02
--- /dev/null
+++ b/_modules/frisbee/src/frisbee.js
@@ -0,0 +1,710 @@
+// frisbee
+// Copyright (c) 2015- Nick Baugh
+// MIT Licensed
+// * Author: [@niftylettuce](https://twitter.com/#!/niftylettuce)
+// * Source:
+// # frisbee
+
+// eslint-disable-next-line
+'use strict'
+
+// https://davidwalsh.name/fetch
+
+const {Buffer} = require('buffer')
+const qs = require('qs')
+const {
+ Chain,
+ isFunction,
+ isString,
+ isObjPure,
+ isReal,
+ isUndefined,
+ isObj,
+ isArray,
+ isNull,
+ isNill,
+ isJSON,
+ merge,
+ encase,
+ enhanceError,
+} = require('./chains')
+
+const fetch = typeof window === 'object' ? window.fetch : global.fetch
+const mergeOpts = {clone: true}
+
+/* @TODO should wildcard fliplog in with logchain internal debugging for debug levels in dev build system thing */
+function isJSONSafe(json, debug = false) {
+ let valid = json
+ try {
+ valid = JSON.parse(json)
+ return valid
+ }
+ catch (e) {
+ if (debug === true) {
+ console.log('JSON is not JSON', e)
+ }
+ return false
+ }
+}
+
+// base URI for everything
+global._options = {
+ baseURI: 'http://localhost:8080',
+ headers: {
+ 'Accept': 'application/json',
+ 'Content-Type': 'application/json',
+ },
+}
+
+// scope the old function to the new one like .has .get since they are common
+// have a requireable fn
+//
+// @IMPORTANT TO UPGRADE THE EXPORTING SO EVERYTHING IS FLAT
+// NEEDS SOLID CHAIN-ABLE-FS
+function renameMethod(originalMethodName, newMethodName) {
+ this[newMethodName] = this[originalMethodName]
+}
+
+const validations = [
+ // 0 fatal.fetch
+ 'A global `fetch` method is required as either `window.fetch` ' +
+ 'for browsers or `global.fetch` for node runtime environments. ' +
+ 'Please add `require(\'isomorphic-fetch\')` before importing `frisbee`. ' +
+ 'You may optionally `require(\'es6-promise\').polyfill()` before you ' +
+ 'require `isomorphic-fetch` if you want to support older browsers.' +
+ '\n\nFor more info: https://github.com/niftylettuce/frisbee#usage',
+ // 1 validate.fatal.baseuri*
+ 'baseURI option is required',
+ // 2 validate.path.string
+ '`path` must be a string',
+ // 3 validate.opts.obj
+ '`options` must be an object',
+ // 4 validate.auth.keys
+ 'auth option can only have two keys `[user, pass]`',
+ // 5 validate.auth.user.string
+ 'auth option `user` must be a string',
+ // 6 validate.auth.pass.string
+ 'auth option `pass` must be a string',
+ // 7 validate.auth.jwt.string
+ 'jwt token must be a string',
+ `Invalid JSON received from`,
+]
+
+// @TODO could also just put strings here but then they are allocated each time
+// using `_` instead of dot for easier selection
+// could also assign to variables but array isn't so bad for order and the eyes and ease
+// smaller this way, but changes stack...
+const errMsg = msg => {
+ if (msg === 'req_fetch') return validations[0]
+ else if (msg === 'req_base') return validations[1]
+ else if (msg === 'str_path') return validations[2]
+ else if (msg === 'obj_opts') return validations[3]
+ else if (msg === 'auth_keys') return validations[4]
+ else if (msg === 'str_user') return validations[5]
+ else if (msg === 'str_pass') return validations[6]
+ else if (msg === 'str_jwt') return validations[7]
+ else if (msg === 'json') return validations[8]
+}
+const throwWithMsg = msg => {
+ throw new Error(errMsg(msg))
+}
+
+if (!fetch) throwWithMsg('req_fetch')
+
+const methods = ['get', 'head', 'post', 'put', 'del', 'options', 'patch']
+
+const respProperties = {
+ readOnly: [
+ 'headers',
+ 'ok',
+ 'redirected',
+ 'status',
+ 'statusText',
+ 'type',
+ 'url',
+ 'bodyUsed',
+ ],
+ writable: ['useFinalURL'],
+ callable: [
+ 'clone',
+ 'error',
+ 'redirect',
+ 'arrayBuffer',
+ 'blob',
+ 'formData',
+ 'json',
+ 'text',
+ ],
+}
+
+const getContentType = headers => {
+ if (isNill(headers)) {
+ return null
+ }
+ else if (isFunction(headers.get)) {
+ return headers.get('Content-Type') || headers.get('content-type')
+ }
+ else if (isObj(headers)) {
+ return headers['Content-Type'] || headers['content-type']
+ }
+}
+
+// @TODO could copy in the typed version to generate comments to generate docs too
+// and allows backwards parsing thinking for creating typedefs
+//
+// clone() - Creates a clone of a Response object.
+// error() - Returns a new Response object associated with a network error.
+// redirect() - Creates a new response with a different URL.
+// arrayBuffer() - Returns a promise that resolves with an ArrayBuffer.
+// blob() - Returns a promise that resolves with a Blob.
+// formData() - Returns a promise that resolves with a FormData object.
+// json() - Returns a promise that resolves with a JSON object.
+// text()
+
+// determine whether we're returning text or json for body
+// or attempt to parse json body to use as error message
+async function parseFrisbeeResponseBody(res, contentTypeJSON) {
+ // for (var originalProp in res.originalResponse) {
+ // // if (!isUndefined(res[originalProp])) {
+ // const has = originalProp in res
+ // if (has) continue
+ // Object.defineProperty(res, originalProp, Object.getOwnPropertyDescriptor(res.originalResponse, originalProp) || {})
+ // // }
+ // }
+ try {
+ if (contentTypeJSON) {
+ // console.log('is contentTypeJSON')
+ if (isFunction(res.json)) {
+ // console.log('is json on response')
+ try {
+ // @TODO encase()
+ res.body = await res.json()
+ }
+ catch (e) {
+ // console.log('errored parsing json on response', e)
+ // return e
+ res.err = e
+ res.originalResponse.statusText = e ? e.message : e
+
+ // res.originalResponse.err = e
+ // res.statusText = e.message
+ // console.log({res})
+ }
+ // console.log('parsed json on response, done')
+ }
+ else {
+ // console.log('is isFoshoJSON - calling text')
+
+ res.body = await res.text()
+ // console.log('is isFoshoJSON -pre')
+ const isFoshoJSON = isJSONSafe(res.body)
+ // console.log('is isFoshoJSON - pre parse')
+
+ // @TODO another fn here could do
+ // @NOTE good thing to test solidly
+ if (isJSON(res.body)) {
+ res.body = encase(JSON.parse(res.body)).onInvalid((error) => res.err = error)
+ // console.log('error?')
+ }
+ else {
+ // console.log('handling it, on own')
+ res.err = this.handleError('json')
+ }
+ }
+ return res
+ }
+ else {
+ // console.log('LAST ELSE')
+ res.body = await res.text()
+ }
+ }
+ catch (e) {
+ res.err = e
+ // console.log('ERROR PARSING', e)
+ }
+
+ // console.log('parsed response')
+ return res
+}
+
+/**
+ * @TODO needs more features that make axios viable
+ * easy middleware for local storage & jwt retry que
+ */
+
+/* prettier-ignore */
+function formatFrisbeeResponseError(res, contentTypeJSON, baseURI) {
+ // res.err = new Error(res.statusText)
+ const FrisbeeResponse = res
+ // new Response(res)
+
+ // type - basic, cors
+ // url
+ // useFinalURL - Boolean for if url is the final URL
+ // status - status code (ex: 200, 404, etc.)
+ // ok - Boolean for successful response (status in the range 200-299)
+ // statusText - status code (ex: OK)
+ // headers
+
+
+ // check if the response was JSON, and if so, better the error
+ if (contentTypeJSON) {
+ // @TODO Glazed?
+ // attempt to use Glazed error messages
+ if (isObj(FrisbeeResponse.body) && isString(FrisbeeResponse.body.message)) {
+ // @TODO these are the same...?
+ // FrisbeeResponse.err = new Error(FrisbeeResponse.body.message)
+ FrisbeeResponse.err = FrisbeeResponse.body
+ }
+ // attempt to utilize Stripe-inspired error messages
+ if (!(isArray(FrisbeeResponse.body) && isObj(FrisbeeResponse.body.error))) {
+ // was here
+ res.err = FrisbeeResponse.body.error
+ }
+ // if (isObj(res.err)) {
+ // if (res.err.message) res.err = new Error(res.err.message)
+ // if (res.err.stack) res.err.stack = (res.err.stack)
+ // if (res.err.code) res.err.code = (res.err.code)
+ // if (res.err.param) res.err.param = (res.err.param)
+ // }
+ }
+ return FrisbeeResponse
+}
+
+// enhanceError
+
+function createFrisbeeResponse(origResp) {
+ const resp = {
+ originalResponse: origResp,
+ }
+
+ // curry
+ // const define = (prop, value) => Object.defineProperty(resp, prop, value)
+
+ // console.log('creating frisbee response', {resp})
+
+ respProperties.readOnly.forEach(prop =>
+ Object.defineProperty(resp, prop, {
+ value: origResp[prop],
+ })
+ //&& console.log({ prop })
+ )
+
+ respProperties.writable.forEach(prop =>
+ Object.defineProperty(resp, prop, {
+ get() {
+ return origResp[prop]
+ },
+ set(value) {
+ origResp[prop] = value
+ },
+ })
+ //&& console.log({ prop })
+ )
+
+ let callable = null
+ respProperties.callable.forEach(prop => {
+ Object.defineProperty(resp, prop, {
+ // enumerable: true,
+ value: (
+ (callable = origResp[prop]),
+ isFunction(callable) && callable.bind(origResp)
+ ),
+ })
+ // && console.log({ prop })
+ })
+
+ // easy vanilla access headers
+ const headersObj = {}
+ origResp.headers.forEach(pair => {
+ headersObj[pair[0]] = pair[1]
+ })
+ Object.defineProperty(resp, 'headersObj', {
+ value: headersObj,
+ })
+
+ // const descriptors = obj => {
+ // const descs = []
+ // for (let prop in obj) {
+ // descs.push({ [prop]: Object.getOwnPropertyDescriptor(obj, prop) })
+ // }
+ // return descs
+ // }
+
+ // .body
+ // descriptors(resp.originalResponse).forEach(desc => {
+ // const prop = Object.keys(desc)[0]
+ // if (resp[prop]) return
+ // Object.defineProperty(resp, prop, desc[prop])
+ // console.log({ prop })
+ // })
+
+ // console.log('created frisbee response')
+ // console.log(descriptors(resp.originalResponse))
+
+ return resp
+}
+
+function copySetToMethodPlugin(name, parent) {
+ const copySetOntoMethod = arg => {
+ if (isUndefined(arg)) {
+ parent.get(name)
+ }
+ else {
+ parent.set(name, arg)
+ Object.assign(parent[name], arg)
+ }
+ return parent
+ }
+
+ // so we know if we defaulted them
+ copySetOntoMethod.copySetOntoMethod = true
+
+ return this.onSet(copySetOntoMethod)
+ .onGet(copySetOntoMethod)
+ .onCall(copySetOntoMethod)
+}
+
+const makeBody = () => {
+
+}
+const makeRequest = (url, opts) => {
+ const requestConfig = {
+ method: 'POST',
+ mode: 'cors',
+ redirect: 'follow',
+ headers: new Headers({
+ 'Content-Type': 'text/plain',
+ }),
+ }
+ Object.assign(requestConfig, opts)
+
+ return new Request(url, requestConfig)
+}
+
+
+/**
+ * @TODO formData (use util)
+ */
+// const blob = () => {
+// fetch('https://davidwalsh.name/submit', {
+// method: 'post',
+// body: new FormData(document.getElementById('comment-form'))
+// });
+//
+// .then(function(response) {
+// return response.blob();
+// })
+// .then(function(imageBlob) {
+// document.querySelector('img').src = URL.createObjectURL(imageBlob);
+// });
+// }
+
+// easy destructure err
+const fetchIt = async(url, opts) => {
+ let error = null
+ try {
+ const request = makeRequest(url, opts)
+ // console.log({request})
+ // url, opts
+ const result = await fetch(request)
+ // console.log(result)
+ return [error, result]
+ }
+ catch (e) {
+ return [e, null]
+ }
+}
+
+/* prettier-ignore */
+class Frisbee extends Chain {
+ constructor(opts = {}) {
+ //('frisbee'
+ super()
+
+ // because conflicting names
+ this._get = this.get.bind(this)
+
+ // @default
+ // wish you could make better stack traces once thrown? extend error??
+ this.onError(function defaultErrorThrower(error) {
+ console.log('throwing...', {error})
+ throw error
+ })
+
+ // try {
+ // this.method('_setup').encase().onInvalid((error) => {
+ // require('fliplog').quick(error)
+ // }).build()
+ // }
+ // catch (e) {
+ // console.log('ugh', e)
+ // }
+
+
+ this
+ .method('headers')
+ .plugin(copySetToMethodPlugin)
+ .build()
+ .extend(['arrayFormat'])
+ // .autoGetSet()
+ // .getSet()
+ // .build()
+
+ .auth(opts.auth)
+ .opts(opts)
+ .headers(opts.headers)
+ .arrayFormat(opts.arrayFormat || 'indices')
+ // .when(opts.auth, () => this.auth(opts.auth))
+
+ methods.forEach(method => {
+ this[method] = this._setup(method)
+ })
+
+ // already bound
+ // this.httpGet = this._get
+ // this._get = (arg1, arg2) => {
+ // if (isUndefined(arg2))
+ // }
+ }
+ opts(opts) {
+ // validate
+ if (!opts.baseURI) this.handleError('req_base')
+ this.set('opts', opts)
+ return this
+ }
+
+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error#Custom_Error_Types
+ // can have arrays of handlers, middleware, this is baby steps
+ onError(handler) {
+ // console.log('onerror')
+ return this.set('onError', handler)
+ }
+ handleError(msg, data) {
+ const messageForIndex = isString(msg) ? errMsg(msg) : msg
+ // console.log('handleerror')
+ const errorPlus = new Error(messageForIndex)
+ errorPlus.data = data
+
+ // isError [object Object] FetchError {
+ // name: 'FetchError',
+ // message: 'invalid json response body at http://localhost:8080/404-with-invalid-json reason: Unexpected token o in JSON at position 1',
+ // type: 'invalid-json'
+
+ // console.log(error.message, error.stack)
+ // throw error
+
+
+ // try {
+ // const errorPlus = new Error(messageForIndex)
+ // newest at top, remove this line
+ // errorPlus.stack = errorPlus.stack.split('\n')
+ // errorPlus.stack.shift()
+ // errorPlus.stack = errorPlus.stack.join('\n')
+ // throw errorPlus
+ const onerr = this._get('onError')
+ // console.log({onerr})
+ // console.log(this.store)
+ onerr(errorPlus)
+ // }
+ // // when onerr throws an error
+ // catch (errorError) {
+ // console.log(errorError.message)
+ // console.log(errorError.stack)
+ // throw errorError
+ // }
+ // this._get('onError').call(this, error, this)
+ return errorPlus
+ }
+
+ /**
+ * @methodFactory
+ * @method
+ * @memberOf frisbee
+ * @protected
+ * @param {string} method enum
+ * @return {Frisbee} @chainable
+ */
+ _setup(methodKeyword) {
+ return (path = '/', options = {}) => {
+ // validate ---
+
+ // path must be string
+ if (!isString(path)) return this.handleError('str_path')
+
+ // otherwise check if its an object
+ if (!isObjPure(options)) return this.handleError('obj_opts', options)
+
+ // console.log('about to get', this)
+ // require('fliplog').quick(this)
+
+ // setup data ---
+ const {baseURI} = this._get('opts')
+
+ // swappable/placeholder var to use existing them update with merged
+ let headers = this._get('headers')
+
+ // console.log({baseURI, headers}, this)
+
+ // --- here down is not tied to any instance ---
+
+ // don't want to override param,
+ // and it's easier to read as a descriptive variable
+ // @NOTE would be a good transform
+ const method =
+ methodKeyword === 'del' ? 'DELETE' : methodKeyword.toUpperCase()
+
+ // merge headers when we have them
+ if (isObj(options) && options.headers) {
+ headers = merge(headers, options.headers, mergeOpts)
+ }
+ const opts = merge(options, {headers, method}, mergeOpts)
+
+ // remove any nil or blank headers
+ // (e.g. to automatically set Content-Type with `FormData` boundary)
+ Object.keys(opts.headers).forEach(key => {
+ if (!isReal(opts.headers[key])) delete opts.headers[key]
+ })
+
+
+ /**
+ * in order to support Android POST requests
+ * we must allow an empty body to be sent
+ * @see https://github.com/facebook/react-native/issues/4890
+ */
+ if (isUndefined(opts.body)) {
+ if (opts.method === 'POST') {
+ opts.body = ''
+ }
+ }
+ else if (isObj(opts.body)) {
+ if (opts.method === 'GET' || opts.method === 'DELETE') {
+ let qsOpts = null
+ if (this.has('arrayFormat')) {
+ qsOpts = {arrayFormat: this._get('arrayFormat')}
+ }
+
+ console.log('QS', qs.stringify(opts.body))
+
+ path += `?${qs.stringify(opts.body, qsOpts)}`
+ delete opts.body
+ }
+ // @TODO: better stringify here
+ else {
+ /*
+ * @NOTE using caseless means checking
+ * permutations of casings
+ * encouraging bad practice
+ * and doing a massive amount of loops
+ * when it just simply isn't in the headers
+ */
+ const reqContentType = opts.headers ? getContentType(opts.headers) : false
+
+ if (reqContentType && reqContentType.split(';')[0] === 'application/json') {
+ try {
+ opts.body = JSON.stringify(opts.body)
+ }
+ catch (err) {
+ this.handleError(err)
+ }
+ }
+ }
+ }
+
+ // @TODO does this part here ever throw to wrap try catch?
+ const dofetch = async() => {
+ // console.log('do fetch', {path, opts})
+
+ const [error, ogRes] = await fetchIt(baseURI + path, opts)
+
+ // console.log('do fetch - PASS')
+
+ // simple error
+ if (!isNill(error)) {
+ // @TODO @DEV
+ // console.log('has error', {error})
+ return this.handleError(error)
+ // return Promise.reject(error)
+ }
+
+ let res = createFrisbeeResponse(ogRes)
+ const contentType = res.headers.get('Content-Type')
+ const contentTypeJSON =
+ isString(contentType) &&
+ contentType.includes('application/json')
+
+ // console.log('enhanced contentType')
+ const encasedParse = encase(parseFrisbeeResponseBody)
+ res = await encasedParse(res, contentTypeJSON)
+
+ // console.log('parsed response body')
+
+ if (!res.ok) res = formatFrisbeeResponseError(res, contentTypeJSON, baseURI)
+
+ // console.log('formatted')
+
+ return Promise.resolve(res)
+ }
+
+ return dofetch()
+ }
+ }
+
+ /**
+ * @TODO have option to allow .setEh .getEh & access as normal properties so never `eh()`
+ */
+ delAuth() {
+ // @TODO this is kind of weird
+ delete this.headers.Authorization
+ return this.delete('headers.Authorization')
+ }
+ setAuth(Authorization) {
+ this.headers.Authorization = Authorization
+ return this.set('headers.Authorization', Authorization)
+ }
+
+ auth(creditStringOrArray) {
+ let creds = creditStringOrArray
+ console.log({creditStringOrArray})
+ // if it has :, split into array
+ if (isString(creds)) {
+ const index = creds.indexOf(':')
+ if (index !== -1) {
+ // aka creds.split(':')
+ creds = [creds.substr(0, index), creds.substr(index + 1)]
+ }
+ }
+
+ // @TODO argumentor undefined, else array
+ // @TODO this is no good...
+ if (!isArray(creds)) creds = [].slice.call(arguments)
+
+ // essentially padd out our credentials with empty
+ if (creds.length === 0) creds = ['', '']
+ else if (creds.length === 1) creds.push('')
+ else if (creds.length !== 2) this.handleError('auth_keys')
+ creds = creds.map(cred => (isReal(cred) ? cred : ''))
+
+ // console.log({creds})
+
+ // @TODO can do 1 step further with validation as in split plugin
+ if (!isString(creds[0])) this.handleError('str_user')
+ if (!isString(creds[1])) this.handleError('str_pass')
+
+ if (!creds[0] && !creds[1]) this.delAuth()
+ else this.setAuth(`Basic ${new Buffer(creds.join(':')).toString('base64')}`)
+
+ return this
+ }
+
+ jwt(token) {
+ if (isNull(token)) return this.delAuth()
+ else if (isString(token)) return this.setAuth(`Bearer ${token}`)
+ else return this.handleError('str_jwt')
+ }
+}
+
+module.exports = function Frisbees(opts) {
+ // console.log({opts})
+ return new Frisbee(opts)
+}
diff --git a/_modules/frisbee/src/index.js b/_modules/frisbee/src/index.js
new file mode 100644
index 0000000..8cf0a5d
--- /dev/null
+++ b/_modules/frisbee/src/index.js
@@ -0,0 +1 @@
+module.exports = require('./frisbee')
diff --git a/_modules/frisbee/test-setup.js b/_modules/frisbee/test-setup.js
new file mode 100644
index 0000000..147f6b1
--- /dev/null
+++ b/_modules/frisbee/test-setup.js
@@ -0,0 +1,103 @@
+const log = require('fliplog')
+const express = require('express')
+const cors = require('cors')
+const bodyParser = require('body-parser')
+
+const app = express()
+const extended = {extended: false}
+
+// log.registerCatch()
+app.use(cors())
+
+// parse application/x-www-form-urlencoded
+app.use(bodyParser.urlencoded(extended))
+
+// parse application/json
+app.use(bodyParser.json(extended))
+
+app.all('/', (req, res, next) => {
+ /*
+ // HEAD request body must be 0 in length
+ if (req.method === 'HEAD' || req.method === 'OPTIONS') {
+ res.send(200, '');
+ return;
+ }
+ */
+
+ res.json({
+ message: 'OK',
+ })
+})
+
+app.get('/400-with-message', (req, res, next) => {
+ res.status(400).json({message: 'Oops!'})
+})
+
+app.get('/querystring', (req, res, next) => {
+ res.json(req.query)
+})
+
+app.delete('/querystring', (req, res, next) => {
+ res.json(req.query)
+})
+
+app.get('/404', (req, res, next) => {
+ // console.log('404...', {req, res, next})
+ // throw new Error('404')
+ res.sendStatus(404)
+})
+
+app.get('/404-with-valid-json', (req, res, next) => {
+ res.set('Content-Type', 'application/json').status(400).send({foo: 'baz'})
+})
+
+app.get('/404-with-invalid-json', (req, res, next) => {
+ console.log('404')
+ res.set('Content-Type', 'application/json').status(404).send('foobaz')
+})
+
+app.get('/404-with-stripe-error', (req, res, next) => {
+ res.status(404).json({
+ error: {
+ message: 'Some error happened',
+ stack: {},
+ code: 23,
+ param: 'hello_world',
+ },
+ })
+})
+
+global.app = {}
+global._server = {
+ start() {
+ global.app = app.listen(8080)
+ },
+ stop() {
+ return global.app.close()
+ },
+}
+
+// base URI for everything
+global._options = {
+ baseURI: 'http://localhost:8080',
+ headers: {
+ 'Accept': 'application/json',
+ 'Content-Type': 'application/json',
+ },
+}
+
+// setup global chai methods
+// import chai from 'chai';
+// import dirtyChai from 'dirty-chai';
+// chai.config.includeStack = true;
+// chai.config.showDiff = true;
+// // chai.use(dirtyChai);
+// global.chai = chai;
+// global.AssertionError = chai.AssertionError;
+// global.Assertion = chai.Assertion;
+// global.expect = chai.expect;
+// global.assert = chai.assert;
+
+// setTimeout(() => {
+// global._server.close
+// }, 10000)
diff --git a/_modules/frisbee/yarn.lock b/_modules/frisbee/yarn.lock
new file mode 100644
index 0000000..477d231
--- /dev/null
+++ b/_modules/frisbee/yarn.lock
@@ -0,0 +1,2342 @@
+# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
+# yarn lockfile v1
+
+
+abab@^1.0.3:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/abab/-/abab-1.0.3.tgz#b81de5f7274ec4e756d797cd834f303642724e5d"
+
+accepts@~1.3.3:
+ version "1.3.3"
+ resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.3.tgz#c3ca7434938648c3e0d9c1e328dd68b622c284ca"
+ dependencies:
+ mime-types "~2.1.11"
+ negotiator "0.6.1"
+
+acorn-globals@^3.1.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-3.1.0.tgz#fd8270f71fbb4996b004fa880ee5d46573a731bf"
+ dependencies:
+ acorn "^4.0.4"
+
+acorn@^4.0.4:
+ version "4.0.13"
+ resolved "https://registry.yarnpkg.com/acorn/-/acorn-4.0.13.tgz#105495ae5361d697bd195c825192e1ad7f253787"
+
+ajv@^4.9.1:
+ version "4.11.8"
+ resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.8.tgz#82ffb02b29e662ae53bdc20af15947706739c536"
+ dependencies:
+ co "^4.6.0"
+ json-stable-stringify "^1.0.1"
+
+align-text@^0.1.1, align-text@^0.1.3:
+ version "0.1.4"
+ resolved "https://registry.yarnpkg.com/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117"
+ dependencies:
+ kind-of "^3.0.2"
+ longest "^1.0.1"
+ repeat-string "^1.5.2"
+
+amdefine@>=0.0.4:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5"
+
+ansi-escapes@^1.4.0:
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e"
+
+ansi-regex@^2.0.0, ansi-regex@^2.1.1:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df"
+
+ansi-styles@^2.2.1:
+ version "2.2.1"
+ resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe"
+
+ansi-styles@^3.0.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.1.0.tgz#09c202d5c917ec23188caa5c9cb9179cd9547750"
+ dependencies:
+ color-convert "^1.0.0"
+
+anymatch@^1.3.0:
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-1.3.0.tgz#a3e52fa39168c825ff57b0248126ce5a8ff95507"
+ dependencies:
+ arrify "^1.0.0"
+ micromatch "^2.1.5"
+
+append-transform@^0.4.0:
+ version "0.4.0"
+ resolved "https://registry.yarnpkg.com/append-transform/-/append-transform-0.4.0.tgz#d76ebf8ca94d276e247a36bad44a4b74ab611991"
+ dependencies:
+ default-require-extensions "^1.0.0"
+
+argparse@^1.0.7:
+ version "1.0.9"
+ resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.9.tgz#73d83bc263f86e97f8cc4f6bae1b0e90a7d22c86"
+ dependencies:
+ sprintf-js "~1.0.2"
+
+arr-diff@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf"
+ dependencies:
+ arr-flatten "^1.0.1"
+
+arr-flatten@^1.0.1:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1"
+
+array-equal@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/array-equal/-/array-equal-1.0.0.tgz#8c2a5ef2472fd9ea742b04c77a75093ba2757c93"
+
+array-flatten@1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2"
+
+array-unique@^0.2.1:
+ version "0.2.1"
+ resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53"
+
+arrify@^1.0.0, arrify@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d"
+
+asn1@~0.2.3:
+ version "0.2.3"
+ resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86"
+
+assert-plus@1.0.0, assert-plus@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525"
+
+assert-plus@^0.2.0:
+ version "0.2.0"
+ resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.2.0.tgz#d74e1b87e7affc0db8aadb7021f3fe48101ab234"
+
+async@^1.4.0:
+ version "1.5.2"
+ resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a"
+
+async@^2.1.4:
+ version "2.5.0"
+ resolved "https://registry.yarnpkg.com/async/-/async-2.5.0.tgz#843190fd6b7357a0b9e1c956edddd5ec8462b54d"
+ dependencies:
+ lodash "^4.14.0"
+
+asynckit@^0.4.0:
+ version "0.4.0"
+ resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
+
+aws-sign2@~0.6.0:
+ version "0.6.0"
+ resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.6.0.tgz#14342dd38dbcc94d0e5b87d763cd63612c0e794f"
+
+aws4@^1.2.1:
+ version "1.6.0"
+ resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e"
+
+babel-code-frame@^6.22.0:
+ version "6.22.0"
+ resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.22.0.tgz#027620bee567a88c32561574e7fd0801d33118e4"
+ dependencies:
+ chalk "^1.1.0"
+ esutils "^2.0.2"
+ js-tokens "^3.0.0"
+
+babel-core@^6.0.0, babel-core@^6.24.1:
+ version "6.25.0"
+ resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.25.0.tgz#7dd42b0463c742e9d5296deb3ec67a9322dad729"
+ dependencies:
+ babel-code-frame "^6.22.0"
+ babel-generator "^6.25.0"
+ babel-helpers "^6.24.1"
+ babel-messages "^6.23.0"
+ babel-register "^6.24.1"
+ babel-runtime "^6.22.0"
+ babel-template "^6.25.0"
+ babel-traverse "^6.25.0"
+ babel-types "^6.25.0"
+ babylon "^6.17.2"
+ convert-source-map "^1.1.0"
+ debug "^2.1.1"
+ json5 "^0.5.0"
+ lodash "^4.2.0"
+ minimatch "^3.0.2"
+ path-is-absolute "^1.0.0"
+ private "^0.1.6"
+ slash "^1.0.0"
+ source-map "^0.5.0"
+
+babel-generator@^6.18.0, babel-generator@^6.25.0:
+ version "6.25.0"
+ resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.25.0.tgz#33a1af70d5f2890aeb465a4a7793c1df6a9ea9fc"
+ dependencies:
+ babel-messages "^6.23.0"
+ babel-runtime "^6.22.0"
+ babel-types "^6.25.0"
+ detect-indent "^4.0.0"
+ jsesc "^1.3.0"
+ lodash "^4.2.0"
+ source-map "^0.5.0"
+ trim-right "^1.0.1"
+
+babel-helpers@^6.24.1:
+ version "6.24.1"
+ resolved "https://registry.yarnpkg.com/babel-helpers/-/babel-helpers-6.24.1.tgz#3471de9caec388e5c850e597e58a26ddf37602b2"
+ dependencies:
+ babel-runtime "^6.22.0"
+ babel-template "^6.24.1"
+
+babel-jest@^20.0.3:
+ version "20.0.3"
+ resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-20.0.3.tgz#e4a03b13dc10389e140fc645d09ffc4ced301671"
+ dependencies:
+ babel-core "^6.0.0"
+ babel-plugin-istanbul "^4.0.0"
+ babel-preset-jest "^20.0.3"
+
+babel-messages@^6.23.0:
+ version "6.23.0"
+ resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e"
+ dependencies:
+ babel-runtime "^6.22.0"
+
+babel-plugin-istanbul@^4.0.0:
+ version "4.1.4"
+ resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-4.1.4.tgz#18dde84bf3ce329fddf3f4103fae921456d8e587"
+ dependencies:
+ find-up "^2.1.0"
+ istanbul-lib-instrument "^1.7.2"
+ test-exclude "^4.1.1"
+
+babel-plugin-jest-hoist@^20.0.3:
+ version "20.0.3"
+ resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-20.0.3.tgz#afedc853bd3f8dc3548ea671fbe69d03cc2c1767"
+
+babel-preset-jest@^20.0.3:
+ version "20.0.3"
+ resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-20.0.3.tgz#cbacaadecb5d689ca1e1de1360ebfc66862c178a"
+ dependencies:
+ babel-plugin-jest-hoist "^20.0.3"
+
+babel-register@^6.24.1:
+ version "6.24.1"
+ resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.24.1.tgz#7e10e13a2f71065bdfad5a1787ba45bca6ded75f"
+ dependencies:
+ babel-core "^6.24.1"
+ babel-runtime "^6.22.0"
+ core-js "^2.4.0"
+ home-or-tmp "^2.0.0"
+ lodash "^4.2.0"
+ mkdirp "^0.5.1"
+ source-map-support "^0.4.2"
+
+babel-runtime@^6.22.0, babel-runtime@^6.9.2:
+ version "6.23.0"
+ resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.23.0.tgz#0a9489f144de70efb3ce4300accdb329e2fc543b"
+ dependencies:
+ core-js "^2.4.0"
+ regenerator-runtime "^0.10.0"
+
+babel-template@^6.16.0, babel-template@^6.24.1, babel-template@^6.25.0:
+ version "6.25.0"
+ resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.25.0.tgz#665241166b7c2aa4c619d71e192969552b10c071"
+ dependencies:
+ babel-runtime "^6.22.0"
+ babel-traverse "^6.25.0"
+ babel-types "^6.25.0"
+ babylon "^6.17.2"
+ lodash "^4.2.0"
+
+babel-traverse@^6.18.0, babel-traverse@^6.25.0:
+ version "6.25.0"
+ resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.25.0.tgz#2257497e2fcd19b89edc13c4c91381f9512496f1"
+ dependencies:
+ babel-code-frame "^6.22.0"
+ babel-messages "^6.23.0"
+ babel-runtime "^6.22.0"
+ babel-types "^6.25.0"
+ babylon "^6.17.2"
+ debug "^2.2.0"
+ globals "^9.0.0"
+ invariant "^2.2.0"
+ lodash "^4.2.0"
+
+babel-types@^6.18.0, babel-types@^6.25.0:
+ version "6.25.0"
+ resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.25.0.tgz#70afb248d5660e5d18f811d91c8303b54134a18e"
+ dependencies:
+ babel-runtime "^6.22.0"
+ esutils "^2.0.2"
+ lodash "^4.2.0"
+ to-fast-properties "^1.0.1"
+
+babylon@^6.17.2, babylon@^6.17.4:
+ version "6.17.4"
+ resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.17.4.tgz#3e8b7402b88d22c3423e137a1577883b15ff869a"
+
+balanced-match@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
+
+base64-js@^1.0.2:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.2.1.tgz#a91947da1f4a516ea38e5b4ec0ec3773675e0886"
+
+bcrypt-pbkdf@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz#63bc5dcb61331b92bc05fd528953c33462a06f8d"
+ dependencies:
+ tweetnacl "^0.14.3"
+
+body-parser@*:
+ version "1.17.2"
+ resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.17.2.tgz#f8892abc8f9e627d42aedafbca66bf5ab99104ee"
+ dependencies:
+ bytes "2.4.0"
+ content-type "~1.0.2"
+ debug "2.6.7"
+ depd "~1.1.0"
+ http-errors "~1.6.1"
+ iconv-lite "0.4.15"
+ on-finished "~2.3.0"
+ qs "6.4.0"
+ raw-body "~2.2.0"
+ type-is "~1.6.15"
+
+boom@2.x.x:
+ version "2.10.1"
+ resolved "https://registry.yarnpkg.com/boom/-/boom-2.10.1.tgz#39c8918ceff5799f83f9492a848f625add0c766f"
+ dependencies:
+ hoek "2.x.x"
+
+brace-expansion@^1.1.7:
+ version "1.1.8"
+ resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.8.tgz#c07b211c7c952ec1f8efd51a77ef0d1d3990a292"
+ dependencies:
+ balanced-match "^1.0.0"
+ concat-map "0.0.1"
+
+braces@^1.8.2:
+ version "1.8.5"
+ resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7"
+ dependencies:
+ expand-range "^1.8.1"
+ preserve "^0.2.0"
+ repeat-element "^1.1.2"
+
+browser-resolve@^1.11.2:
+ version "1.11.2"
+ resolved "https://registry.yarnpkg.com/browser-resolve/-/browser-resolve-1.11.2.tgz#8ff09b0a2c421718a1051c260b32e48f442938ce"
+ dependencies:
+ resolve "1.1.7"
+
+bser@1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/bser/-/bser-1.0.2.tgz#381116970b2a6deea5646dd15dd7278444b56169"
+ dependencies:
+ node-int64 "^0.4.0"
+
+bser@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/bser/-/bser-2.0.0.tgz#9ac78d3ed5d915804fd87acb158bc797147a1719"
+ dependencies:
+ node-int64 "^0.4.0"
+
+buffer@^4.6.0:
+ version "4.9.1"
+ resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.1.tgz#6d1bb601b07a4efced97094132093027c95bc298"
+ dependencies:
+ base64-js "^1.0.2"
+ ieee754 "^1.1.4"
+ isarray "^1.0.0"
+
+builtin-modules@^1.0.0:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f"
+
+bytes@2.4.0:
+ version "2.4.0"
+ resolved "https://registry.yarnpkg.com/bytes/-/bytes-2.4.0.tgz#7d97196f9d5baf7f6935e25985549edd2a6c2339"
+
+callsites@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50"
+
+camelcase@^1.0.2:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-1.2.1.tgz#9bb5304d2e0b56698b2c758b08a3eaa9daa58a39"
+
+camelcase@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a"
+
+caseless@^0.11.0:
+ version "0.11.0"
+ resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.11.0.tgz#715b96ea9841593cc33067923f5ec60ebda4f7d7"
+
+caseless@~0.12.0:
+ version "0.12.0"
+ resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
+
+center-align@^0.1.1:
+ version "0.1.3"
+ resolved "https://registry.yarnpkg.com/center-align/-/center-align-0.1.3.tgz#aa0d32629b6ee972200411cbd4461c907bc2b7ad"
+ dependencies:
+ align-text "^0.1.3"
+ lazy-cache "^1.0.3"
+
+chain-able@3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/chain-able/-/chain-able-3.0.0.tgz#dcffe8b04f3da210941a23843bc1332bb288ca9f"
+
+chalk@^1.1.0, chalk@^1.1.3:
+ version "1.1.3"
+ resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98"
+ dependencies:
+ ansi-styles "^2.2.1"
+ escape-string-regexp "^1.0.2"
+ has-ansi "^2.0.0"
+ strip-ansi "^3.0.0"
+ supports-color "^2.0.0"
+
+ci-info@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.0.0.tgz#dc5285f2b4e251821683681c381c3388f46ec534"
+
+cliui@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/cliui/-/cliui-2.1.0.tgz#4b475760ff80264c762c3a1719032e91c7fea0d1"
+ dependencies:
+ center-align "^0.1.1"
+ right-align "^0.1.1"
+ wordwrap "0.0.2"
+
+cliui@^3.2.0:
+ version "3.2.0"
+ resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d"
+ dependencies:
+ string-width "^1.0.1"
+ strip-ansi "^3.0.1"
+ wrap-ansi "^2.0.0"
+
+co@^4.6.0:
+ version "4.6.0"
+ resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184"
+
+code-point-at@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
+
+color-convert@^1.0.0:
+ version "1.9.0"
+ resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.0.tgz#1accf97dd739b983bf994d56fec8f95853641b7a"
+ dependencies:
+ color-name "^1.1.1"
+
+color-name@^1.1.1:
+ version "1.1.3"
+ resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
+
+combined-stream@^1.0.5, combined-stream@~1.0.5:
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.5.tgz#938370a57b4a51dea2c77c15d5c5fdf895164009"
+ dependencies:
+ delayed-stream "~1.0.0"
+
+concat-map@0.0.1:
+ version "0.0.1"
+ resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
+
+content-disposition@0.5.2:
+ version "0.5.2"
+ resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.2.tgz#0cf68bb9ddf5f2be7961c3a85178cb85dba78cb4"
+
+content-type-parser@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/content-type-parser/-/content-type-parser-1.0.1.tgz#c3e56988c53c65127fb46d4032a3a900246fdc94"
+
+content-type@~1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.2.tgz#b7d113aee7a8dd27bd21133c4dc2529df1721eed"
+
+convert-source-map@^1.1.0, convert-source-map@^1.4.0:
+ version "1.5.0"
+ resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.0.tgz#9acd70851c6d5dfdd93d9282e5edf94a03ff46b5"
+
+cookie-signature@1.0.6:
+ version "1.0.6"
+ resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c"
+
+cookie@0.3.1:
+ version "0.3.1"
+ resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb"
+
+core-js@^2.4.0:
+ version "2.4.1"
+ resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.4.1.tgz#4de911e667b0eae9124e34254b53aea6fc618d3e"
+
+cors@*:
+ version "2.8.4"
+ resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.4.tgz#2bd381f2eb201020105cd50ea59da63090694686"
+ dependencies:
+ object-assign "^4"
+ vary "^1"
+
+cryptiles@2.x.x:
+ version "2.0.5"
+ resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8"
+ dependencies:
+ boom "2.x.x"
+
+cssom@0.3.x, "cssom@>= 0.3.2 < 0.4.0":
+ version "0.3.2"
+ resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.2.tgz#b8036170c79f07a90ff2f16e22284027a243848b"
+
+"cssstyle@>= 0.2.37 < 0.3.0":
+ version "0.2.37"
+ resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-0.2.37.tgz#541097234cb2513c83ceed3acddc27ff27987d54"
+ dependencies:
+ cssom "0.3.x"
+
+dashdash@^1.12.0:
+ version "1.14.1"
+ resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0"
+ dependencies:
+ assert-plus "^1.0.0"
+
+debug@2.6.7:
+ version "2.6.7"
+ resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.7.tgz#92bad1f6d05bbb6bba22cca88bcd0ec894c2861e"
+ dependencies:
+ ms "2.0.0"
+
+debug@^2.1.1, debug@^2.2.0, debug@^2.6.3:
+ version "2.6.8"
+ resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.8.tgz#e731531ca2ede27d188222427da17821d68ff4fc"
+ dependencies:
+ ms "2.0.0"
+
+decamelize@^1.0.0, decamelize@^1.1.1:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290"
+
+deep-is@~0.1.3:
+ version "0.1.3"
+ resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34"
+
+default-require-extensions@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/default-require-extensions/-/default-require-extensions-1.0.0.tgz#f37ea15d3e13ffd9b437d33e1a75b5fb97874cb8"
+ dependencies:
+ strip-bom "^2.0.0"
+
+delayed-stream@~1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
+
+depd@1.1.0, depd@~1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.0.tgz#e1bd82c6aab6ced965b97b88b17ed3e528ca18c3"
+
+destroy@~1.0.4:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80"
+
+detect-indent@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208"
+ dependencies:
+ repeating "^2.0.0"
+
+diff@^3.2.0:
+ version "3.3.0"
+ resolved "https://registry.yarnpkg.com/diff/-/diff-3.3.0.tgz#056695150d7aa93237ca7e378ac3b1682b7963b9"
+
+ecc-jsbn@~0.1.1:
+ version "0.1.1"
+ resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505"
+ dependencies:
+ jsbn "~0.1.0"
+
+ee-first@1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
+
+encodeurl@~1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.1.tgz#79e3d58655346909fe6f0f45a5de68103b294d20"
+
+encoding@^0.1.11:
+ version "0.1.12"
+ resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb"
+ dependencies:
+ iconv-lite "~0.4.13"
+
+errno@^0.1.4:
+ version "0.1.4"
+ resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.4.tgz#b896e23a9e5e8ba33871fc996abd3635fc9a1c7d"
+ dependencies:
+ prr "~0.0.0"
+
+error-ex@^1.2.0:
+ version "1.3.1"
+ resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.1.tgz#f855a86ce61adc4e8621c3cda21e7a7612c3a8dc"
+ dependencies:
+ is-arrayish "^0.2.1"
+
+escape-html@~1.0.3:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988"
+
+escape-string-regexp@^1.0.2:
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
+
+escodegen@^1.6.1:
+ version "1.8.1"
+ resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.8.1.tgz#5a5b53af4693110bebb0867aa3430dd3b70a1018"
+ dependencies:
+ esprima "^2.7.1"
+ estraverse "^1.9.1"
+ esutils "^2.0.2"
+ optionator "^0.8.1"
+ optionalDependencies:
+ source-map "~0.2.0"
+
+esprima@^2.7.1:
+ version "2.7.3"
+ resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581"
+
+esprima@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.0.tgz#4499eddcd1110e0b218bacf2fa7f7f59f55ca804"
+
+estraverse@^1.9.1:
+ version "1.9.3"
+ resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-1.9.3.tgz#af67f2dc922582415950926091a4005d29c9bb44"
+
+esutils@^2.0.2:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b"
+
+etag@~1.8.0:
+ version "1.8.0"
+ resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.0.tgz#6f631aef336d6c46362b51764044ce216be3c051"
+
+exec-sh@^0.2.0:
+ version "0.2.0"
+ resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.2.0.tgz#14f75de3f20d286ef933099b2ce50a90359cef10"
+ dependencies:
+ merge "^1.1.3"
+
+expand-brackets@^0.1.4:
+ version "0.1.5"
+ resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b"
+ dependencies:
+ is-posix-bracket "^0.1.0"
+
+expand-range@^1.8.1:
+ version "1.8.2"
+ resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337"
+ dependencies:
+ fill-range "^2.1.0"
+
+express@*:
+ version "4.15.3"
+ resolved "https://registry.yarnpkg.com/express/-/express-4.15.3.tgz#bab65d0f03aa80c358408972fc700f916944b662"
+ dependencies:
+ accepts "~1.3.3"
+ array-flatten "1.1.1"
+ content-disposition "0.5.2"
+ content-type "~1.0.2"
+ cookie "0.3.1"
+ cookie-signature "1.0.6"
+ debug "2.6.7"
+ depd "~1.1.0"
+ encodeurl "~1.0.1"
+ escape-html "~1.0.3"
+ etag "~1.8.0"
+ finalhandler "~1.0.3"
+ fresh "0.5.0"
+ merge-descriptors "1.0.1"
+ methods "~1.1.2"
+ on-finished "~2.3.0"
+ parseurl "~1.3.1"
+ path-to-regexp "0.1.7"
+ proxy-addr "~1.1.4"
+ qs "6.4.0"
+ range-parser "~1.2.0"
+ send "0.15.3"
+ serve-static "1.12.3"
+ setprototypeof "1.0.3"
+ statuses "~1.3.1"
+ type-is "~1.6.15"
+ utils-merge "1.0.0"
+ vary "~1.1.1"
+
+extend@~3.0.0:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444"
+
+extglob@^0.3.1:
+ version "0.3.2"
+ resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1"
+ dependencies:
+ is-extglob "^1.0.0"
+
+extsprintf@1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.0.2.tgz#e1080e0658e300b06294990cc70e1502235fd550"
+
+fast-levenshtein@~2.0.4:
+ version "2.0.6"
+ resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
+
+fb-watchman@^1.8.0:
+ version "1.9.2"
+ resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-1.9.2.tgz#a24cf47827f82d38fb59a69ad70b76e3b6ae7383"
+ dependencies:
+ bser "1.0.2"
+
+fb-watchman@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.0.tgz#54e9abf7dfa2f26cd9b1636c588c1afc05de5d58"
+ dependencies:
+ bser "^2.0.0"
+
+filename-regex@^2.0.0:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26"
+
+fileset@^2.0.2:
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/fileset/-/fileset-2.0.3.tgz#8e7548a96d3cc2327ee5e674168723a333bba2a0"
+ dependencies:
+ glob "^7.0.3"
+ minimatch "^3.0.3"
+
+fill-range@^2.1.0:
+ version "2.2.3"
+ resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.3.tgz#50b77dfd7e469bc7492470963699fe7a8485a723"
+ dependencies:
+ is-number "^2.1.0"
+ isobject "^2.0.0"
+ randomatic "^1.1.3"
+ repeat-element "^1.1.2"
+ repeat-string "^1.5.2"
+
+finalhandler@~1.0.3:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.0.3.tgz#ef47e77950e999780e86022a560e3217e0d0cc89"
+ dependencies:
+ debug "2.6.7"
+ encodeurl "~1.0.1"
+ escape-html "~1.0.3"
+ on-finished "~2.3.0"
+ parseurl "~1.3.1"
+ statuses "~1.3.1"
+ unpipe "~1.0.0"
+
+find-up@^1.0.0:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f"
+ dependencies:
+ path-exists "^2.0.0"
+ pinkie-promise "^2.0.0"
+
+find-up@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7"
+ dependencies:
+ locate-path "^2.0.0"
+
+fliplog@^1.0.4:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/fliplog/-/fliplog-1.0.4.tgz#c66e064e1cb95473c0e037cb5855ab5da46b4441"
+ dependencies:
+ chain-able "3.0.0"
+
+for-in@^1.0.1:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80"
+
+for-own@^0.1.4:
+ version "0.1.5"
+ resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.5.tgz#5265c681a4f294dabbf17c9509b6763aa84510ce"
+ dependencies:
+ for-in "^1.0.1"
+
+forever-agent@~0.6.1:
+ version "0.6.1"
+ resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
+
+form-data@~2.1.1:
+ version "2.1.4"
+ resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.1.4.tgz#33c183acf193276ecaa98143a69e94bfee1750d1"
+ dependencies:
+ asynckit "^0.4.0"
+ combined-stream "^1.0.5"
+ mime-types "^2.1.12"
+
+forwarded@~0.1.0:
+ version "0.1.0"
+ resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.0.tgz#19ef9874c4ae1c297bcf078fde63a09b66a84363"
+
+fresh@0.5.0:
+ version "0.5.0"
+ resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.0.tgz#f474ca5e6a9246d6fd8e0953cfa9b9c805afa78e"
+
+frisbee@^1.5.0:
+ version "1.5.0"
+ resolved "https://registry.yarnpkg.com/frisbee/-/frisbee-1.5.0.tgz#ae507b76f0fc092dfe208ced1513f2726cb555f5"
+ dependencies:
+ babel-runtime "^6.9.2"
+ buffer "^4.6.0"
+ caseless "^0.11.0"
+ qs "^6.2.0"
+
+fs.realpath@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
+
+get-caller-file@^1.0.1:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.2.tgz#f702e63127e7e231c160a80c1554acb70d5047e5"
+
+getpass@^0.1.1:
+ version "0.1.7"
+ resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa"
+ dependencies:
+ assert-plus "^1.0.0"
+
+glob-base@^0.3.0:
+ version "0.3.0"
+ resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4"
+ dependencies:
+ glob-parent "^2.0.0"
+ is-glob "^2.0.0"
+
+glob-parent@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28"
+ dependencies:
+ is-glob "^2.0.0"
+
+glob@^7.0.3, glob@^7.0.5, glob@^7.1.1:
+ version "7.1.2"
+ resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15"
+ dependencies:
+ fs.realpath "^1.0.0"
+ inflight "^1.0.4"
+ inherits "2"
+ minimatch "^3.0.4"
+ once "^1.3.0"
+ path-is-absolute "^1.0.0"
+
+globals@^9.0.0:
+ version "9.18.0"
+ resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a"
+
+graceful-fs@^4.1.11, graceful-fs@^4.1.2:
+ version "4.1.11"
+ resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658"
+
+growly@^1.3.0:
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081"
+
+handlebars@^4.0.3:
+ version "4.0.10"
+ resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.0.10.tgz#3d30c718b09a3d96f23ea4cc1f403c4d3ba9ff4f"
+ dependencies:
+ async "^1.4.0"
+ optimist "^0.6.1"
+ source-map "^0.4.4"
+ optionalDependencies:
+ uglify-js "^2.6"
+
+har-schema@^1.0.5:
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-1.0.5.tgz#d263135f43307c02c602afc8fe95970c0151369e"
+
+har-validator@~4.2.1:
+ version "4.2.1"
+ resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-4.2.1.tgz#33481d0f1bbff600dd203d75812a6a5fba002e2a"
+ dependencies:
+ ajv "^4.9.1"
+ har-schema "^1.0.5"
+
+has-ansi@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91"
+ dependencies:
+ ansi-regex "^2.0.0"
+
+has-flag@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa"
+
+hawk@~3.1.3:
+ version "3.1.3"
+ resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4"
+ dependencies:
+ boom "2.x.x"
+ cryptiles "2.x.x"
+ hoek "2.x.x"
+ sntp "1.x.x"
+
+hoek@2.x.x:
+ version "2.16.3"
+ resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed"
+
+home-or-tmp@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8"
+ dependencies:
+ os-homedir "^1.0.0"
+ os-tmpdir "^1.0.1"
+
+hosted-git-info@^2.1.4:
+ version "2.5.0"
+ resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.5.0.tgz#6d60e34b3abbc8313062c3b798ef8d901a07af3c"
+
+html-encoding-sniffer@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-1.0.1.tgz#79bf7a785ea495fe66165e734153f363ff5437da"
+ dependencies:
+ whatwg-encoding "^1.0.1"
+
+http-errors@~1.6.1:
+ version "1.6.1"
+ resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.1.tgz#5f8b8ed98aca545656bf572997387f904a722257"
+ dependencies:
+ depd "1.1.0"
+ inherits "2.0.3"
+ setprototypeof "1.0.3"
+ statuses ">= 1.3.1 < 2"
+
+http-signature@~1.1.0:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.1.1.tgz#df72e267066cd0ac67fb76adf8e134a8fbcf91bf"
+ dependencies:
+ assert-plus "^0.2.0"
+ jsprim "^1.2.2"
+ sshpk "^1.7.0"
+
+iconv-lite@0.4.13:
+ version "0.4.13"
+ resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.13.tgz#1f88aba4ab0b1508e8312acc39345f36e992e2f2"
+
+iconv-lite@0.4.15:
+ version "0.4.15"
+ resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.15.tgz#fe265a218ac6a57cfe854927e9d04c19825eddeb"
+
+iconv-lite@~0.4.13:
+ version "0.4.18"
+ resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.18.tgz#23d8656b16aae6742ac29732ea8f0336a4789cf2"
+
+ieee754@^1.1.4:
+ version "1.1.8"
+ resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.8.tgz#be33d40ac10ef1926701f6f08a2d86fbfd1ad3e4"
+
+inflight@^1.0.4:
+ version "1.0.6"
+ resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
+ dependencies:
+ once "^1.3.0"
+ wrappy "1"
+
+inherits@2, inherits@2.0.3:
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
+
+invariant@^2.2.0:
+ version "2.2.2"
+ resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.2.tgz#9e1f56ac0acdb6bf303306f338be3b204ae60360"
+ dependencies:
+ loose-envify "^1.0.0"
+
+invert-kv@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6"
+
+ipaddr.js@1.3.0:
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.3.0.tgz#1e03a52fdad83a8bbb2b25cbf4998b4cffcd3dec"
+
+is-arrayish@^0.2.1:
+ version "0.2.1"
+ resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d"
+
+is-buffer@^1.1.5:
+ version "1.1.5"
+ resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.5.tgz#1f3b26ef613b214b88cbca23cc6c01d87961eecc"
+
+is-builtin-module@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-1.0.0.tgz#540572d34f7ac3119f8f76c30cbc1b1e037affbe"
+ dependencies:
+ builtin-modules "^1.0.0"
+
+is-ci@^1.0.10:
+ version "1.0.10"
+ resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.0.10.tgz#f739336b2632365061a9d48270cd56ae3369318e"
+ dependencies:
+ ci-info "^1.0.0"
+
+is-dotfile@^1.0.0:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1"
+
+is-equal-shallow@^0.1.3:
+ version "0.1.3"
+ resolved "https://registry.yarnpkg.com/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz#2238098fc221de0bcfa5d9eac4c45d638aa1c534"
+ dependencies:
+ is-primitive "^2.0.0"
+
+is-extendable@^0.1.1:
+ version "0.1.1"
+ resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89"
+
+is-extglob@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0"
+
+is-finite@^1.0.0:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa"
+ dependencies:
+ number-is-nan "^1.0.0"
+
+is-fullwidth-code-point@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb"
+ dependencies:
+ number-is-nan "^1.0.0"
+
+is-glob@^2.0.0, is-glob@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863"
+ dependencies:
+ is-extglob "^1.0.0"
+
+is-number@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f"
+ dependencies:
+ kind-of "^3.0.2"
+
+is-number@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195"
+ dependencies:
+ kind-of "^3.0.2"
+
+is-posix-bracket@^0.1.0:
+ version "0.1.1"
+ resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4"
+
+is-primitive@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575"
+
+is-stream@^1.0.1:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
+
+is-typedarray@~1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
+
+is-utf8@^0.2.0:
+ version "0.2.1"
+ resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72"
+
+isarray@1.0.0, isarray@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
+
+isexe@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
+
+isobject@^2.0.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89"
+ dependencies:
+ isarray "1.0.0"
+
+isomorphic-fetch@*:
+ version "2.2.1"
+ resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz#611ae1acf14f5e81f729507472819fe9733558a9"
+ dependencies:
+ node-fetch "^1.0.1"
+ whatwg-fetch ">=0.10.0"
+
+isstream@~0.1.2:
+ version "0.1.2"
+ resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
+
+istanbul-api@^1.1.1:
+ version "1.1.11"
+ resolved "https://registry.yarnpkg.com/istanbul-api/-/istanbul-api-1.1.11.tgz#fcc0b461e2b3bda71e305155138238768257d9de"
+ dependencies:
+ async "^2.1.4"
+ fileset "^2.0.2"
+ istanbul-lib-coverage "^1.1.1"
+ istanbul-lib-hook "^1.0.7"
+ istanbul-lib-instrument "^1.7.4"
+ istanbul-lib-report "^1.1.1"
+ istanbul-lib-source-maps "^1.2.1"
+ istanbul-reports "^1.1.1"
+ js-yaml "^3.7.0"
+ mkdirp "^0.5.1"
+ once "^1.4.0"
+
+istanbul-lib-coverage@^1.0.1, istanbul-lib-coverage@^1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-1.1.1.tgz#73bfb998885299415c93d38a3e9adf784a77a9da"
+
+istanbul-lib-hook@^1.0.7:
+ version "1.0.7"
+ resolved "https://registry.yarnpkg.com/istanbul-lib-hook/-/istanbul-lib-hook-1.0.7.tgz#dd6607f03076578fe7d6f2a630cf143b49bacddc"
+ dependencies:
+ append-transform "^0.4.0"
+
+istanbul-lib-instrument@^1.4.2, istanbul-lib-instrument@^1.7.2, istanbul-lib-instrument@^1.7.4:
+ version "1.7.4"
+ resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-1.7.4.tgz#e9fd920e4767f3d19edc765e2d6b3f5ccbd0eea8"
+ dependencies:
+ babel-generator "^6.18.0"
+ babel-template "^6.16.0"
+ babel-traverse "^6.18.0"
+ babel-types "^6.18.0"
+ babylon "^6.17.4"
+ istanbul-lib-coverage "^1.1.1"
+ semver "^5.3.0"
+
+istanbul-lib-report@^1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-1.1.1.tgz#f0e55f56655ffa34222080b7a0cd4760e1405fc9"
+ dependencies:
+ istanbul-lib-coverage "^1.1.1"
+ mkdirp "^0.5.1"
+ path-parse "^1.0.5"
+ supports-color "^3.1.2"
+
+istanbul-lib-source-maps@^1.1.0, istanbul-lib-source-maps@^1.2.1:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.1.tgz#a6fe1acba8ce08eebc638e572e294d267008aa0c"
+ dependencies:
+ debug "^2.6.3"
+ istanbul-lib-coverage "^1.1.1"
+ mkdirp "^0.5.1"
+ rimraf "^2.6.1"
+ source-map "^0.5.3"
+
+istanbul-reports@^1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-1.1.1.tgz#042be5c89e175bc3f86523caab29c014e77fee4e"
+ dependencies:
+ handlebars "^4.0.3"
+
+jest-changed-files@^20.0.3:
+ version "20.0.3"
+ resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-20.0.3.tgz#9394d5cc65c438406149bef1bf4d52b68e03e3f8"
+
+jest-cli@^20.0.4:
+ version "20.0.4"
+ resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-20.0.4.tgz#e532b19d88ae5bc6c417e8b0593a6fe954b1dc93"
+ dependencies:
+ ansi-escapes "^1.4.0"
+ callsites "^2.0.0"
+ chalk "^1.1.3"
+ graceful-fs "^4.1.11"
+ is-ci "^1.0.10"
+ istanbul-api "^1.1.1"
+ istanbul-lib-coverage "^1.0.1"
+ istanbul-lib-instrument "^1.4.2"
+ istanbul-lib-source-maps "^1.1.0"
+ jest-changed-files "^20.0.3"
+ jest-config "^20.0.4"
+ jest-docblock "^20.0.3"
+ jest-environment-jsdom "^20.0.3"
+ jest-haste-map "^20.0.4"
+ jest-jasmine2 "^20.0.4"
+ jest-message-util "^20.0.3"
+ jest-regex-util "^20.0.3"
+ jest-resolve-dependencies "^20.0.3"
+ jest-runtime "^20.0.4"
+ jest-snapshot "^20.0.3"
+ jest-util "^20.0.3"
+ micromatch "^2.3.11"
+ node-notifier "^5.0.2"
+ pify "^2.3.0"
+ slash "^1.0.0"
+ string-length "^1.0.1"
+ throat "^3.0.0"
+ which "^1.2.12"
+ worker-farm "^1.3.1"
+ yargs "^7.0.2"
+
+jest-config@^20.0.4:
+ version "20.0.4"
+ resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-20.0.4.tgz#e37930ab2217c913605eff13e7bd763ec48faeea"
+ dependencies:
+ chalk "^1.1.3"
+ glob "^7.1.1"
+ jest-environment-jsdom "^20.0.3"
+ jest-environment-node "^20.0.3"
+ jest-jasmine2 "^20.0.4"
+ jest-matcher-utils "^20.0.3"
+ jest-regex-util "^20.0.3"
+ jest-resolve "^20.0.4"
+ jest-validate "^20.0.3"
+ pretty-format "^20.0.3"
+
+jest-diff@^20.0.3:
+ version "20.0.3"
+ resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-20.0.3.tgz#81f288fd9e675f0fb23c75f1c2b19445fe586617"
+ dependencies:
+ chalk "^1.1.3"
+ diff "^3.2.0"
+ jest-matcher-utils "^20.0.3"
+ pretty-format "^20.0.3"
+
+jest-docblock@^20.0.3:
+ version "20.0.3"
+ resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-20.0.3.tgz#17bea984342cc33d83c50fbe1545ea0efaa44712"
+
+jest-environment-jsdom@^20.0.3:
+ version "20.0.3"
+ resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-20.0.3.tgz#048a8ac12ee225f7190417713834bb999787de99"
+ dependencies:
+ jest-mock "^20.0.3"
+ jest-util "^20.0.3"
+ jsdom "^9.12.0"
+
+jest-environment-node@^20.0.3:
+ version "20.0.3"
+ resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-20.0.3.tgz#d488bc4612af2c246e986e8ae7671a099163d403"
+ dependencies:
+ jest-mock "^20.0.3"
+ jest-util "^20.0.3"
+
+jest-haste-map@^20.0.4:
+ version "20.0.4"
+ resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-20.0.4.tgz#653eb55c889ce3c021f7b94693f20a4159badf03"
+ dependencies:
+ fb-watchman "^2.0.0"
+ graceful-fs "^4.1.11"
+ jest-docblock "^20.0.3"
+ micromatch "^2.3.11"
+ sane "~1.6.0"
+ worker-farm "^1.3.1"
+
+jest-jasmine2@^20.0.4:
+ version "20.0.4"
+ resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-20.0.4.tgz#fcc5b1411780d911d042902ef1859e852e60d5e1"
+ dependencies:
+ chalk "^1.1.3"
+ graceful-fs "^4.1.11"
+ jest-diff "^20.0.3"
+ jest-matcher-utils "^20.0.3"
+ jest-matchers "^20.0.3"
+ jest-message-util "^20.0.3"
+ jest-snapshot "^20.0.3"
+ once "^1.4.0"
+ p-map "^1.1.1"
+
+jest-matcher-utils@^20.0.3:
+ version "20.0.3"
+ resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-20.0.3.tgz#b3a6b8e37ca577803b0832a98b164f44b7815612"
+ dependencies:
+ chalk "^1.1.3"
+ pretty-format "^20.0.3"
+
+jest-matchers@^20.0.3:
+ version "20.0.3"
+ resolved "https://registry.yarnpkg.com/jest-matchers/-/jest-matchers-20.0.3.tgz#ca69db1c32db5a6f707fa5e0401abb55700dfd60"
+ dependencies:
+ jest-diff "^20.0.3"
+ jest-matcher-utils "^20.0.3"
+ jest-message-util "^20.0.3"
+ jest-regex-util "^20.0.3"
+
+jest-message-util@^20.0.3:
+ version "20.0.3"
+ resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-20.0.3.tgz#6aec2844306fcb0e6e74d5796c1006d96fdd831c"
+ dependencies:
+ chalk "^1.1.3"
+ micromatch "^2.3.11"
+ slash "^1.0.0"
+
+jest-mock@^20.0.3:
+ version "20.0.3"
+ resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-20.0.3.tgz#8bc070e90414aa155c11a8d64c869a0d5c71da59"
+
+jest-regex-util@^20.0.3:
+ version "20.0.3"
+ resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-20.0.3.tgz#85bbab5d133e44625b19faf8c6aa5122d085d762"
+
+jest-resolve-dependencies@^20.0.3:
+ version "20.0.3"
+ resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-20.0.3.tgz#6e14a7b717af0f2cb3667c549de40af017b1723a"
+ dependencies:
+ jest-regex-util "^20.0.3"
+
+jest-resolve@^20.0.4:
+ version "20.0.4"
+ resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-20.0.4.tgz#9448b3e8b6bafc15479444c6499045b7ffe597a5"
+ dependencies:
+ browser-resolve "^1.11.2"
+ is-builtin-module "^1.0.0"
+ resolve "^1.3.2"
+
+jest-runtime@^20.0.4:
+ version "20.0.4"
+ resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-20.0.4.tgz#a2c802219c4203f754df1404e490186169d124d8"
+ dependencies:
+ babel-core "^6.0.0"
+ babel-jest "^20.0.3"
+ babel-plugin-istanbul "^4.0.0"
+ chalk "^1.1.3"
+ convert-source-map "^1.4.0"
+ graceful-fs "^4.1.11"
+ jest-config "^20.0.4"
+ jest-haste-map "^20.0.4"
+ jest-regex-util "^20.0.3"
+ jest-resolve "^20.0.4"
+ jest-util "^20.0.3"
+ json-stable-stringify "^1.0.1"
+ micromatch "^2.3.11"
+ strip-bom "3.0.0"
+ yargs "^7.0.2"
+
+jest-snapshot@^20.0.3:
+ version "20.0.3"
+ resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-20.0.3.tgz#5b847e1adb1a4d90852a7f9f125086e187c76566"
+ dependencies:
+ chalk "^1.1.3"
+ jest-diff "^20.0.3"
+ jest-matcher-utils "^20.0.3"
+ jest-util "^20.0.3"
+ natural-compare "^1.4.0"
+ pretty-format "^20.0.3"
+
+jest-util@^20.0.3:
+ version "20.0.3"
+ resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-20.0.3.tgz#0c07f7d80d82f4e5a67c6f8b9c3fe7f65cfd32ad"
+ dependencies:
+ chalk "^1.1.3"
+ graceful-fs "^4.1.11"
+ jest-message-util "^20.0.3"
+ jest-mock "^20.0.3"
+ jest-validate "^20.0.3"
+ leven "^2.1.0"
+ mkdirp "^0.5.1"
+
+jest-validate@^20.0.3:
+ version "20.0.3"
+ resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-20.0.3.tgz#d0cfd1de4f579f298484925c280f8f1d94ec3cab"
+ dependencies:
+ chalk "^1.1.3"
+ jest-matcher-utils "^20.0.3"
+ leven "^2.1.0"
+ pretty-format "^20.0.3"
+
+jest@*:
+ version "20.0.4"
+ resolved "https://registry.yarnpkg.com/jest/-/jest-20.0.4.tgz#3dd260c2989d6dad678b1e9cc4d91944f6d602ac"
+ dependencies:
+ jest-cli "^20.0.4"
+
+js-tokens@^3.0.0:
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b"
+
+js-yaml@^3.7.0:
+ version "3.9.0"
+ resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.9.0.tgz#4ffbbf25c2ac963b8299dc74da7e3740de1c18ce"
+ dependencies:
+ argparse "^1.0.7"
+ esprima "^4.0.0"
+
+jsbn@~0.1.0:
+ version "0.1.1"
+ resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
+
+jsdom@^9.12.0:
+ version "9.12.0"
+ resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-9.12.0.tgz#e8c546fffcb06c00d4833ca84410fed7f8a097d4"
+ dependencies:
+ abab "^1.0.3"
+ acorn "^4.0.4"
+ acorn-globals "^3.1.0"
+ array-equal "^1.0.0"
+ content-type-parser "^1.0.1"
+ cssom ">= 0.3.2 < 0.4.0"
+ cssstyle ">= 0.2.37 < 0.3.0"
+ escodegen "^1.6.1"
+ html-encoding-sniffer "^1.0.1"
+ nwmatcher ">= 1.3.9 < 2.0.0"
+ parse5 "^1.5.1"
+ request "^2.79.0"
+ sax "^1.2.1"
+ symbol-tree "^3.2.1"
+ tough-cookie "^2.3.2"
+ webidl-conversions "^4.0.0"
+ whatwg-encoding "^1.0.1"
+ whatwg-url "^4.3.0"
+ xml-name-validator "^2.0.1"
+
+jsesc@^1.3.0:
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b"
+
+json-schema@0.2.3:
+ version "0.2.3"
+ resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13"
+
+json-stable-stringify@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af"
+ dependencies:
+ jsonify "~0.0.0"
+
+json-stringify-safe@~5.0.1:
+ version "5.0.1"
+ resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
+
+json5@^0.5.0:
+ version "0.5.1"
+ resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821"
+
+jsonify@~0.0.0:
+ version "0.0.0"
+ resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73"
+
+jsprim@^1.2.2:
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.0.tgz#a3b87e40298d8c380552d8cc7628a0bb95a22918"
+ dependencies:
+ assert-plus "1.0.0"
+ extsprintf "1.0.2"
+ json-schema "0.2.3"
+ verror "1.3.6"
+
+kind-of@^3.0.2:
+ version "3.2.2"
+ resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64"
+ dependencies:
+ is-buffer "^1.1.5"
+
+kind-of@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57"
+ dependencies:
+ is-buffer "^1.1.5"
+
+lazy-cache@^1.0.3:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-1.0.4.tgz#a1d78fc3a50474cb80845d3b3b6e1da49a446e8e"
+
+lcid@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835"
+ dependencies:
+ invert-kv "^1.0.0"
+
+leven@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/leven/-/leven-2.1.0.tgz#c2e7a9f772094dee9d34202ae8acce4687875580"
+
+levn@~0.3.0:
+ version "0.3.0"
+ resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee"
+ dependencies:
+ prelude-ls "~1.1.2"
+ type-check "~0.3.2"
+
+load-json-file@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0"
+ dependencies:
+ graceful-fs "^4.1.2"
+ parse-json "^2.2.0"
+ pify "^2.0.0"
+ pinkie-promise "^2.0.0"
+ strip-bom "^2.0.0"
+
+locate-path@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e"
+ dependencies:
+ p-locate "^2.0.0"
+ path-exists "^3.0.0"
+
+lodash@^4.14.0, lodash@^4.2.0:
+ version "4.17.4"
+ resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae"
+
+longest@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097"
+
+loose-envify@^1.0.0:
+ version "1.3.1"
+ resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848"
+ dependencies:
+ js-tokens "^3.0.0"
+
+makeerror@1.0.x:
+ version "1.0.11"
+ resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.11.tgz#e01a5c9109f2af79660e4e8b9587790184f5a96c"
+ dependencies:
+ tmpl "1.0.x"
+
+media-typer@0.3.0:
+ version "0.3.0"
+ resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
+
+merge-descriptors@1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61"
+
+merge@^1.1.3:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/merge/-/merge-1.2.0.tgz#7531e39d4949c281a66b8c5a6e0265e8b05894da"
+
+methods@~1.1.2:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee"
+
+micromatch@^2.1.5, micromatch@^2.3.11:
+ version "2.3.11"
+ resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565"
+ dependencies:
+ arr-diff "^2.0.0"
+ array-unique "^0.2.1"
+ braces "^1.8.2"
+ expand-brackets "^0.1.4"
+ extglob "^0.3.1"
+ filename-regex "^2.0.0"
+ is-extglob "^1.0.0"
+ is-glob "^2.0.1"
+ kind-of "^3.0.2"
+ normalize-path "^2.0.1"
+ object.omit "^2.0.0"
+ parse-glob "^3.0.4"
+ regex-cache "^0.4.2"
+
+mime-db@~1.27.0:
+ version "1.27.0"
+ resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.27.0.tgz#820f572296bbd20ec25ed55e5b5de869e5436eb1"
+
+mime-types@^2.1.12, mime-types@~2.1.11, mime-types@~2.1.15, mime-types@~2.1.7:
+ version "2.1.15"
+ resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.15.tgz#a4ebf5064094569237b8cf70046776d09fc92aed"
+ dependencies:
+ mime-db "~1.27.0"
+
+mime@1.3.4:
+ version "1.3.4"
+ resolved "https://registry.yarnpkg.com/mime/-/mime-1.3.4.tgz#115f9e3b6b3daf2959983cb38f149a2d40eb5d53"
+
+minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4:
+ version "3.0.4"
+ resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
+ dependencies:
+ brace-expansion "^1.1.7"
+
+minimist@0.0.8:
+ version "0.0.8"
+ resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d"
+
+minimist@^1.1.1:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284"
+
+minimist@~0.0.1:
+ version "0.0.10"
+ resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf"
+
+mkdirp@^0.5.1:
+ version "0.5.1"
+ resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903"
+ dependencies:
+ minimist "0.0.8"
+
+ms@2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
+
+natural-compare@^1.4.0:
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
+
+negotiator@0.6.1:
+ version "0.6.1"
+ resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9"
+
+node-fetch@^1.0.1, node-fetch@^1.7.1:
+ version "1.7.1"
+ resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.1.tgz#899cb3d0a3c92f952c47f1b876f4c8aeabd400d5"
+ dependencies:
+ encoding "^0.1.11"
+ is-stream "^1.0.1"
+
+node-int64@^0.4.0:
+ version "0.4.0"
+ resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b"
+
+node-notifier@^5.0.2:
+ version "5.1.2"
+ resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-5.1.2.tgz#2fa9e12605fa10009d44549d6fcd8a63dde0e4ff"
+ dependencies:
+ growly "^1.3.0"
+ semver "^5.3.0"
+ shellwords "^0.1.0"
+ which "^1.2.12"
+
+normalize-package-data@^2.3.2:
+ version "2.4.0"
+ resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.4.0.tgz#12f95a307d58352075a04907b84ac8be98ac012f"
+ dependencies:
+ hosted-git-info "^2.1.4"
+ is-builtin-module "^1.0.0"
+ semver "2 || 3 || 4 || 5"
+ validate-npm-package-license "^3.0.1"
+
+normalize-path@^2.0.1:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9"
+ dependencies:
+ remove-trailing-separator "^1.0.1"
+
+number-is-nan@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d"
+
+"nwmatcher@>= 1.3.9 < 2.0.0":
+ version "1.4.1"
+ resolved "https://registry.yarnpkg.com/nwmatcher/-/nwmatcher-1.4.1.tgz#7ae9b07b0ea804db7e25f05cb5fe4097d4e4949f"
+
+oauth-sign@~0.8.1:
+ version "0.8.2"
+ resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43"
+
+object-assign@^4, object-assign@^4.1.0:
+ version "4.1.1"
+ resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
+
+object.omit@^2.0.0:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa"
+ dependencies:
+ for-own "^0.1.4"
+ is-extendable "^0.1.1"
+
+on-finished@~2.3.0:
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947"
+ dependencies:
+ ee-first "1.1.1"
+
+once@^1.3.0, once@^1.4.0:
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
+ dependencies:
+ wrappy "1"
+
+optimist@^0.6.1:
+ version "0.6.1"
+ resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686"
+ dependencies:
+ minimist "~0.0.1"
+ wordwrap "~0.0.2"
+
+optionator@^0.8.1:
+ version "0.8.2"
+ resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64"
+ dependencies:
+ deep-is "~0.1.3"
+ fast-levenshtein "~2.0.4"
+ levn "~0.3.0"
+ prelude-ls "~1.1.2"
+ type-check "~0.3.2"
+ wordwrap "~1.0.0"
+
+os-homedir@^1.0.0:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3"
+
+os-locale@^1.4.0:
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-1.4.0.tgz#20f9f17ae29ed345e8bde583b13d2009803c14d9"
+ dependencies:
+ lcid "^1.0.0"
+
+os-tmpdir@^1.0.1:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
+
+p-limit@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.1.0.tgz#b07ff2d9a5d88bec806035895a2bab66a27988bc"
+
+p-locate@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43"
+ dependencies:
+ p-limit "^1.1.0"
+
+p-map@^1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/p-map/-/p-map-1.1.1.tgz#05f5e4ae97a068371bc2a5cc86bfbdbc19c4ae7a"
+
+parse-glob@^3.0.4:
+ version "3.0.4"
+ resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c"
+ dependencies:
+ glob-base "^0.3.0"
+ is-dotfile "^1.0.0"
+ is-extglob "^1.0.0"
+ is-glob "^2.0.0"
+
+parse-json@^2.2.0:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9"
+ dependencies:
+ error-ex "^1.2.0"
+
+parse5@^1.5.1:
+ version "1.5.1"
+ resolved "https://registry.yarnpkg.com/parse5/-/parse5-1.5.1.tgz#9b7f3b0de32be78dc2401b17573ccaf0f6f59d94"
+
+parseurl@~1.3.1:
+ version "1.3.1"
+ resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.1.tgz#c8ab8c9223ba34888aa64a297b28853bec18da56"
+
+path-exists@^2.0.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b"
+ dependencies:
+ pinkie-promise "^2.0.0"
+
+path-exists@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515"
+
+path-is-absolute@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
+
+path-parse@^1.0.5:
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1"
+
+path-to-regexp@0.1.7:
+ version "0.1.7"
+ resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c"
+
+path-type@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441"
+ dependencies:
+ graceful-fs "^4.1.2"
+ pify "^2.0.0"
+ pinkie-promise "^2.0.0"
+
+performance-now@^0.2.0:
+ version "0.2.0"
+ resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-0.2.0.tgz#33ef30c5c77d4ea21c5a53869d91b56d8f2555e5"
+
+pify@^2.0.0, pify@^2.3.0:
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c"
+
+pinkie-promise@^2.0.0:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa"
+ dependencies:
+ pinkie "^2.0.0"
+
+pinkie@^2.0.0:
+ version "2.0.4"
+ resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870"
+
+prelude-ls@~1.1.2:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54"
+
+preserve@^0.2.0:
+ version "0.2.0"
+ resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b"
+
+pretty-format@^20.0.3:
+ version "20.0.3"
+ resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-20.0.3.tgz#020e350a560a1fe1a98dc3beb6ccffb386de8b14"
+ dependencies:
+ ansi-regex "^2.1.1"
+ ansi-styles "^3.0.0"
+
+private@^0.1.6:
+ version "0.1.7"
+ resolved "https://registry.yarnpkg.com/private/-/private-0.1.7.tgz#68ce5e8a1ef0a23bb570cc28537b5332aba63ef1"
+
+proxy-addr@~1.1.4:
+ version "1.1.4"
+ resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-1.1.4.tgz#27e545f6960a44a627d9b44467e35c1b6b4ce2f3"
+ dependencies:
+ forwarded "~0.1.0"
+ ipaddr.js "1.3.0"
+
+prr@~0.0.0:
+ version "0.0.0"
+ resolved "https://registry.yarnpkg.com/prr/-/prr-0.0.0.tgz#1a84b85908325501411853d0081ee3fa86e2926a"
+
+punycode@^1.4.1:
+ version "1.4.1"
+ resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e"
+
+qs@*, qs@^6.2.0:
+ version "6.5.0"
+ resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.0.tgz#8d04954d364def3efc55b5a0793e1e2c8b1e6e49"
+
+qs@6.4.0, qs@~6.4.0:
+ version "6.4.0"
+ resolved "https://registry.yarnpkg.com/qs/-/qs-6.4.0.tgz#13e26d28ad6b0ffaa91312cd3bf708ed351e7233"
+
+randomatic@^1.1.3:
+ version "1.1.7"
+ resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-1.1.7.tgz#c7abe9cc8b87c0baa876b19fde83fd464797e38c"
+ dependencies:
+ is-number "^3.0.0"
+ kind-of "^4.0.0"
+
+range-parser@~1.2.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e"
+
+raw-body@~2.2.0:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.2.0.tgz#994976cf6a5096a41162840492f0bdc5d6e7fb96"
+ dependencies:
+ bytes "2.4.0"
+ iconv-lite "0.4.15"
+ unpipe "1.0.0"
+
+read-pkg-up@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02"
+ dependencies:
+ find-up "^1.0.0"
+ read-pkg "^1.0.0"
+
+read-pkg@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28"
+ dependencies:
+ load-json-file "^1.0.0"
+ normalize-package-data "^2.3.2"
+ path-type "^1.0.0"
+
+regenerator-runtime@^0.10.0:
+ version "0.10.5"
+ resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz#336c3efc1220adcedda2c9fab67b5a7955a33658"
+
+regex-cache@^0.4.2:
+ version "0.4.3"
+ resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.3.tgz#9b1a6c35d4d0dfcef5711ae651e8e9d3d7114145"
+ dependencies:
+ is-equal-shallow "^0.1.3"
+ is-primitive "^2.0.0"
+
+remove-trailing-separator@^1.0.1:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.0.2.tgz#69b062d978727ad14dc6b56ba4ab772fd8d70511"
+
+repeat-element@^1.1.2:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.2.tgz#ef089a178d1483baae4d93eb98b4f9e4e11d990a"
+
+repeat-string@^1.5.2:
+ version "1.6.1"
+ resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637"
+
+repeating@^2.0.0:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda"
+ dependencies:
+ is-finite "^1.0.0"
+
+request@^2.79.0:
+ version "2.81.0"
+ resolved "https://registry.yarnpkg.com/request/-/request-2.81.0.tgz#c6928946a0e06c5f8d6f8a9333469ffda46298a0"
+ dependencies:
+ aws-sign2 "~0.6.0"
+ aws4 "^1.2.1"
+ caseless "~0.12.0"
+ combined-stream "~1.0.5"
+ extend "~3.0.0"
+ forever-agent "~0.6.1"
+ form-data "~2.1.1"
+ har-validator "~4.2.1"
+ hawk "~3.1.3"
+ http-signature "~1.1.0"
+ is-typedarray "~1.0.0"
+ isstream "~0.1.2"
+ json-stringify-safe "~5.0.1"
+ mime-types "~2.1.7"
+ oauth-sign "~0.8.1"
+ performance-now "^0.2.0"
+ qs "~6.4.0"
+ safe-buffer "^5.0.1"
+ stringstream "~0.0.4"
+ tough-cookie "~2.3.0"
+ tunnel-agent "^0.6.0"
+ uuid "^3.0.0"
+
+require-directory@^2.1.1:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42"
+
+require-main-filename@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1"
+
+resolve@1.1.7:
+ version "1.1.7"
+ resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b"
+
+resolve@^1.3.2:
+ version "1.3.3"
+ resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.3.3.tgz#655907c3469a8680dc2de3a275a8fdd69691f0e5"
+ dependencies:
+ path-parse "^1.0.5"
+
+right-align@^0.1.1:
+ version "0.1.3"
+ resolved "https://registry.yarnpkg.com/right-align/-/right-align-0.1.3.tgz#61339b722fe6a3515689210d24e14c96148613ef"
+ dependencies:
+ align-text "^0.1.1"
+
+rimraf@^2.6.1:
+ version "2.6.1"
+ resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.1.tgz#c2338ec643df7a1b7fe5c54fa86f57428a55f33d"
+ dependencies:
+ glob "^7.0.5"
+
+safe-buffer@^5.0.1:
+ version "5.1.1"
+ resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853"
+
+sane@~1.6.0:
+ version "1.6.0"
+ resolved "https://registry.yarnpkg.com/sane/-/sane-1.6.0.tgz#9610c452307a135d29c1fdfe2547034180c46775"
+ dependencies:
+ anymatch "^1.3.0"
+ exec-sh "^0.2.0"
+ fb-watchman "^1.8.0"
+ minimatch "^3.0.2"
+ minimist "^1.1.1"
+ walker "~1.0.5"
+ watch "~0.10.0"
+
+sax@^1.2.1:
+ version "1.2.4"
+ resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
+
+"semver@2 || 3 || 4 || 5", semver@^5.3.0:
+ version "5.3.0"
+ resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f"
+
+send@0.15.3:
+ version "0.15.3"
+ resolved "https://registry.yarnpkg.com/send/-/send-0.15.3.tgz#5013f9f99023df50d1bd9892c19e3defd1d53309"
+ dependencies:
+ debug "2.6.7"
+ depd "~1.1.0"
+ destroy "~1.0.4"
+ encodeurl "~1.0.1"
+ escape-html "~1.0.3"
+ etag "~1.8.0"
+ fresh "0.5.0"
+ http-errors "~1.6.1"
+ mime "1.3.4"
+ ms "2.0.0"
+ on-finished "~2.3.0"
+ range-parser "~1.2.0"
+ statuses "~1.3.1"
+
+serve-static@1.12.3:
+ version "1.12.3"
+ resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.12.3.tgz#9f4ba19e2f3030c547f8af99107838ec38d5b1e2"
+ dependencies:
+ encodeurl "~1.0.1"
+ escape-html "~1.0.3"
+ parseurl "~1.3.1"
+ send "0.15.3"
+
+set-blocking@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7"
+
+setprototypeof@1.0.3:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.0.3.tgz#66567e37043eeb4f04d91bd658c0cbefb55b8e04"
+
+shellwords@^0.1.0:
+ version "0.1.0"
+ resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.0.tgz#66afd47b6a12932d9071cbfd98a52e785cd0ba14"
+
+slash@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55"
+
+sntp@1.x.x:
+ version "1.0.9"
+ resolved "https://registry.yarnpkg.com/sntp/-/sntp-1.0.9.tgz#6541184cc90aeea6c6e7b35e2659082443c66198"
+ dependencies:
+ hoek "2.x.x"
+
+source-map-support@^0.4.2:
+ version "0.4.15"
+ resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.15.tgz#03202df65c06d2bd8c7ec2362a193056fef8d3b1"
+ dependencies:
+ source-map "^0.5.6"
+
+source-map@^0.4.4:
+ version "0.4.4"
+ resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.4.4.tgz#eba4f5da9c0dc999de68032d8b4f76173652036b"
+ dependencies:
+ amdefine ">=0.0.4"
+
+source-map@^0.5.0, source-map@^0.5.3, source-map@^0.5.6, source-map@~0.5.1:
+ version "0.5.6"
+ resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412"
+
+source-map@~0.2.0:
+ version "0.2.0"
+ resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.2.0.tgz#dab73fbcfc2ba819b4de03bd6f6eaa48164b3f9d"
+ dependencies:
+ amdefine ">=0.0.4"
+
+spdx-correct@~1.0.0:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-1.0.2.tgz#4b3073d933ff51f3912f03ac5519498a4150db40"
+ dependencies:
+ spdx-license-ids "^1.0.2"
+
+spdx-expression-parse@~1.0.0:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz#9bdf2f20e1f40ed447fbe273266191fced51626c"
+
+spdx-license-ids@^1.0.2:
+ version "1.2.2"
+ resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz#c9df7a3424594ade6bd11900d596696dc06bac57"
+
+sprintf-js@~1.0.2:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
+
+sshpk@^1.7.0:
+ version "1.13.1"
+ resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.13.1.tgz#512df6da6287144316dc4c18fe1cf1d940739be3"
+ dependencies:
+ asn1 "~0.2.3"
+ assert-plus "^1.0.0"
+ dashdash "^1.12.0"
+ getpass "^0.1.1"
+ optionalDependencies:
+ bcrypt-pbkdf "^1.0.0"
+ ecc-jsbn "~0.1.1"
+ jsbn "~0.1.0"
+ tweetnacl "~0.14.0"
+
+"statuses@>= 1.3.1 < 2", statuses@~1.3.1:
+ version "1.3.1"
+ resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.3.1.tgz#faf51b9eb74aaef3b3acf4ad5f61abf24cb7b93e"
+
+string-length@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/string-length/-/string-length-1.0.1.tgz#56970fb1c38558e9e70b728bf3de269ac45adfac"
+ dependencies:
+ strip-ansi "^3.0.0"
+
+string-width@^1.0.1, string-width@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3"
+ dependencies:
+ code-point-at "^1.0.0"
+ is-fullwidth-code-point "^1.0.0"
+ strip-ansi "^3.0.0"
+
+stringstream@~0.0.4:
+ version "0.0.5"
+ resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878"
+
+strip-ansi@^3.0.0, strip-ansi@^3.0.1:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf"
+ dependencies:
+ ansi-regex "^2.0.0"
+
+strip-bom@3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3"
+
+strip-bom@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e"
+ dependencies:
+ is-utf8 "^0.2.0"
+
+supports-color@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"
+
+supports-color@^3.1.2:
+ version "3.2.3"
+ resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6"
+ dependencies:
+ has-flag "^1.0.0"
+
+symbol-tree@^3.2.1:
+ version "3.2.2"
+ resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.2.tgz#ae27db38f660a7ae2e1c3b7d1bc290819b8519e6"
+
+test-exclude@^4.1.1:
+ version "4.1.1"
+ resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-4.1.1.tgz#4d84964b0966b0087ecc334a2ce002d3d9341e26"
+ dependencies:
+ arrify "^1.0.1"
+ micromatch "^2.3.11"
+ object-assign "^4.1.0"
+ read-pkg-up "^1.0.1"
+ require-main-filename "^1.0.1"
+
+throat@^3.0.0:
+ version "3.2.0"
+ resolved "https://registry.yarnpkg.com/throat/-/throat-3.2.0.tgz#50cb0670edbc40237b9e347d7e1f88e4620af836"
+
+tmpl@1.0.x:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1"
+
+to-fast-properties@^1.0.1:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47"
+
+tough-cookie@^2.3.2, tough-cookie@~2.3.0:
+ version "2.3.2"
+ resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.2.tgz#f081f76e4c85720e6c37a5faced737150d84072a"
+ dependencies:
+ punycode "^1.4.1"
+
+tr46@~0.0.3:
+ version "0.0.3"
+ resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a"
+
+trim-right@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003"
+
+tunnel-agent@^0.6.0:
+ version "0.6.0"
+ resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd"
+ dependencies:
+ safe-buffer "^5.0.1"
+
+tweetnacl@^0.14.3, tweetnacl@~0.14.0:
+ version "0.14.5"
+ resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
+
+type-check@~0.3.2:
+ version "0.3.2"
+ resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72"
+ dependencies:
+ prelude-ls "~1.1.2"
+
+type-is@~1.6.15:
+ version "1.6.15"
+ resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.15.tgz#cab10fb4909e441c82842eafe1ad646c81804410"
+ dependencies:
+ media-typer "0.3.0"
+ mime-types "~2.1.15"
+
+uglify-js@^2.6:
+ version "2.8.29"
+ resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.29.tgz#29c5733148057bb4e1f75df35b7a9cb72e6a59dd"
+ dependencies:
+ source-map "~0.5.1"
+ yargs "~3.10.0"
+ optionalDependencies:
+ uglify-to-browserify "~1.0.0"
+
+uglify-to-browserify@~1.0.0:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz#6e0924d6bda6b5afe349e39a6d632850a0f882b7"
+
+unpipe@1.0.0, unpipe@~1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec"
+
+utils-merge@1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.0.tgz#0294fb922bb9375153541c4f7096231f287c8af8"
+
+uuid@^3.0.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.1.0.tgz#3dd3d3e790abc24d7b0d3a034ffababe28ebbc04"
+
+validate-npm-package-license@^3.0.1:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz#2804babe712ad3379459acfbe24746ab2c303fbc"
+ dependencies:
+ spdx-correct "~1.0.0"
+ spdx-expression-parse "~1.0.0"
+
+vary@^1, vary@~1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.1.tgz#67535ebb694c1d52257457984665323f587e8d37"
+
+verror@1.3.6:
+ version "1.3.6"
+ resolved "https://registry.yarnpkg.com/verror/-/verror-1.3.6.tgz#cff5df12946d297d2baaefaa2689e25be01c005c"
+ dependencies:
+ extsprintf "1.0.2"
+
+walker@~1.0.5:
+ version "1.0.7"
+ resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.7.tgz#2f7f9b8fd10d677262b18a884e28d19618e028fb"
+ dependencies:
+ makeerror "1.0.x"
+
+watch@~0.10.0:
+ version "0.10.0"
+ resolved "https://registry.yarnpkg.com/watch/-/watch-0.10.0.tgz#77798b2da0f9910d595f1ace5b0c2258521f21dc"
+
+webidl-conversions@^3.0.0:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871"
+
+webidl-conversions@^4.0.0:
+ version "4.0.1"
+ resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.1.tgz#8015a17ab83e7e1b311638486ace81da6ce206a0"
+
+whatwg-encoding@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.1.tgz#3c6c451a198ee7aec55b1ec61d0920c67801a5f4"
+ dependencies:
+ iconv-lite "0.4.13"
+
+whatwg-fetch@>=0.10.0:
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz#9c84ec2dcf68187ff00bc64e1274b442176e1c84"
+
+whatwg-url@^4.3.0:
+ version "4.8.0"
+ resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-4.8.0.tgz#d2981aa9148c1e00a41c5a6131166ab4683bbcc0"
+ dependencies:
+ tr46 "~0.0.3"
+ webidl-conversions "^3.0.0"
+
+which-module@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f"
+
+which@^1.2.12:
+ version "1.2.14"
+ resolved "https://registry.yarnpkg.com/which/-/which-1.2.14.tgz#9a87c4378f03e827cecaf1acdf56c736c01c14e5"
+ dependencies:
+ isexe "^2.0.0"
+
+window-size@0.1.0:
+ version "0.1.0"
+ resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d"
+
+wordwrap@0.0.2:
+ version "0.0.2"
+ resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f"
+
+wordwrap@~0.0.2:
+ version "0.0.3"
+ resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107"
+
+wordwrap@~1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb"
+
+worker-farm@^1.3.1:
+ version "1.4.1"
+ resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.4.1.tgz#a438bc993a7a7d133bcb6547c95eca7cff4897d8"
+ dependencies:
+ errno "^0.1.4"
+ xtend "^4.0.1"
+
+wrap-ansi@^2.0.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85"
+ dependencies:
+ string-width "^1.0.1"
+ strip-ansi "^3.0.1"
+
+wrappy@1:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
+
+xml-name-validator@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-2.0.1.tgz#4d8b8f1eccd3419aa362061becef515e1e559635"
+
+xmlhttprequest@^1.8.0:
+ version "1.8.0"
+ resolved "https://registry.yarnpkg.com/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz#67fe075c5c24fef39f9d65f5f7b7fe75171968fc"
+
+xtend@^4.0.1:
+ version "4.0.1"
+ resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af"
+
+y18n@^3.2.1:
+ version "3.2.1"
+ resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41"
+
+yargs-parser@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-5.0.0.tgz#275ecf0d7ffe05c77e64e7c86e4cd94bf0e1228a"
+ dependencies:
+ camelcase "^3.0.0"
+
+yargs@^7.0.2:
+ version "7.1.0"
+ resolved "https://registry.yarnpkg.com/yargs/-/yargs-7.1.0.tgz#6ba318eb16961727f5d284f8ea003e8d6154d0c8"
+ dependencies:
+ camelcase "^3.0.0"
+ cliui "^3.2.0"
+ decamelize "^1.1.1"
+ get-caller-file "^1.0.1"
+ os-locale "^1.4.0"
+ read-pkg-up "^1.0.1"
+ require-directory "^2.1.1"
+ require-main-filename "^1.0.1"
+ set-blocking "^2.0.0"
+ string-width "^1.0.2"
+ which-module "^1.0.0"
+ y18n "^3.2.1"
+ yargs-parser "^5.0.0"
+
+yargs@~3.10.0:
+ version "3.10.0"
+ resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.10.0.tgz#f7ee7bd857dd7c1d2d38c0e74efbd681d1431fd1"
+ dependencies:
+ camelcase "^1.0.2"
+ cliui "^2.1.0"
+ decamelize "^1.0.0"
+ window-size "0.1.0"
diff --git a/_modules/lego-cli/async.js b/_modules/lego-cli/async.js
new file mode 100644
index 0000000..3ac9878
--- /dev/null
+++ b/_modules/lego-cli/async.js
@@ -0,0 +1 @@
+// https://github.com/MatAtBread/nodent-compiler/blob/master/lib/output.js
diff --git a/_modules/lego-cli/index.js b/_modules/lego-cli/index.js
new file mode 100644
index 0000000..8631cb1
--- /dev/null
+++ b/_modules/lego-cli/index.js
@@ -0,0 +1,54 @@
+// @TODO can also use `on-the-fly` to compile into a bundle on the fly
+
+// this file is just when using in dev mode so huge relative paths aren't required
+const {resolve} = require('path')
+const moduleAlias = require('module-alias')
+
+const res = rel => resolve(__dirname, rel)
+moduleAlias.addPath(res('../../../'))
+moduleAlias.addPath(res('../../'))
+moduleAlias.addPath(res('../../src'))
+moduleAlias.addPath(res('./node_modules'))
+
+// const CLI = require('fluent-cli')
+// const File = require('file-chain')
+
+const {exists, read, write} = require('flipfile')
+const Script = require('script-chain')
+const execa = require('execa')
+const find = require('chain-able-find')
+const fwf = require('funwithflags')
+const log = require('fliplog')
+const {Chain, isUndefined} = require('chain-able')
+const pkg = require('../../package.json')
+
+const deps = {
+ find,
+ execa,
+ Script,
+ // CLI,
+ resolve,
+ fwf,
+ log,
+ exists,
+ read,
+ write,
+ pkg,
+ Chain,
+ // File,
+ script: () => new Script(),
+}
+
+// @TODO: needs yarn-or-npm script
+/**
+ * @prop {string} dir directory to resolve everything to
+ * @type {ChainedMap}
+ */
+class AppCLI extends Chain {
+ dep(name) {
+ return isUndefined(name) ? deps : deps[name]
+ }
+ script() {
+ return new Script()
+ }
+}
diff --git a/_modules/lego-cli/plugins/ast/babel.js b/_modules/lego-cli/plugins/ast/babel.js
new file mode 100644
index 0000000..d2c7b42
--- /dev/null
+++ b/_modules/lego-cli/plugins/ast/babel.js
@@ -0,0 +1,17 @@
+module.exports = {
+ /**
+ * @since 0.0.1
+ * @tutorial https://github.com/babel
+ * @param {string} string code source
+ * @param {Object} [config=null] babel options
+ * @return {string} transformed babel output
+ */
+ babel(string, config = null) {
+ // return new Script().add().bin('babel').raw('src/ --out-dir dist').run()
+ const babel = require('babel-core')
+ // result = babel.transform(str, {allowReturnOutsideFunction: true});
+ const parsedAst = babel.parse(string, {allowReturnOutsideFunction: true})
+ const {code, map, ast} = babel.transformFromAst(parsedAst, string, config)
+ return code
+ },
+}
diff --git a/_modules/lego-cli/plugins/ast/buble.js b/_modules/lego-cli/plugins/ast/buble.js
new file mode 100644
index 0000000..6fb5bf5
--- /dev/null
+++ b/_modules/lego-cli/plugins/ast/buble.js
@@ -0,0 +1,13 @@
+module.exports = {
+ buble() {
+ const sourcemaps = true
+ const scripts = this.script()
+ .add()
+ .bin('buble')
+ .raw('-i dist')
+ .raw('-o dist')
+ .raw('--no forOf,dangerousForOf,computedProperty,spreadRest')
+ if (sourcemaps) scripts.raw('-m inline')
+ return scripts.run()
+ },
+}
diff --git a/_modules/lego-cli/plugins/ast/lebab.js b/_modules/lego-cli/plugins/ast/lebab.js
new file mode 100644
index 0000000..9464b80
--- /dev/null
+++ b/_modules/lego-cli/plugins/ast/lebab.js
@@ -0,0 +1,647 @@
+const {resolve} = require('path')
+const {execSync} = require('child_process')
+const log = require('fliplog')
+const lebab = require('lebab')
+const {read, write, del} = require('flipfile')
+const {GlobSync} = require('flipfile/glob')
+const ChainedMap = require('chain-able')
+
+/**
+ * @TODO:
+ * - [ ] should put the transformers as middleware
+ * - [ ] use file-chain now that it is extracted
+ * - [ ] run eslint on transformed files
+ */
+class File {
+ /**
+ * @param {Object} obj
+ */
+ constructor(obj) {
+ const {debug, abs} = obj
+ this.abs = abs
+ this._debug = !!debug
+ }
+
+ /**
+ * reads file
+ * @see File.contents
+ * @param {boolean} [force=false]
+ * @return {File}
+ */
+ load(force = false) {
+ if (this.contents !== undefined && force === false) {
+ return this
+ }
+
+ this.contents = read(this.abs)
+
+ log.blue('loaded content').data(this.abs, this.contents).echo(this._debug)
+
+ return this
+ }
+
+ del() {
+ del(this.abs)
+ return this
+ }
+
+ /**
+ * @return {File}
+ */
+ lebab() {
+ const features = ['let', 'arrow', 'commonjs', 'includes']
+ const {code, warnings} = lebab.transform(this.contents, features)
+
+ log.bold('label-ed').verbose().data({code, warnings}).echo(this._debug)
+
+ this.contents = code
+
+ return this
+ }
+
+ /**
+ * @param {string} from
+ * @param {string} to
+ * @return {File}
+ */
+ changeExtension(from, to) {
+ const abs = this.abs
+
+ this.abs = this.abs.replace(from, to).replace('//', '/')
+
+ log
+ .underline('changed path')
+ .data({from: abs, to: this.abs})
+ .echo(this._debug)
+
+ return this
+ }
+
+ /**
+ * @param {string} from
+ * @param {string} to
+ * @return {File}
+ */
+ changeDir(from, to) {
+ // const {input, temp} = dirs
+
+ const abs = this.abs
+
+ this.abs = this.abs.replace(from, to)
+ // const toDir = resolve(dir, './ts') .replace(dir, './')
+
+ log
+ .underline('changed dir')
+ .data({before: abs, after: this.abs, from, to})
+ .echo(this._debug)
+
+ return this
+ }
+
+ /**
+ * removes public/private/protected class properties
+ * since babel does not like them, currently
+ *
+ * @return {Magic}
+ */
+ removeModifiers() {
+ log.blue('data').verbose().data().echo(this._debug)
+
+ this.contents = this.contents.replace(
+ /( {0,4}public|private|protected )/gim,
+ ''
+ )
+
+ return this
+ }
+
+ /**
+ * @return {File}
+ */
+ write() {
+ const {abs, contents} = this
+
+ log.green('writing').data({abs, contents}).echo(this._debug)
+
+ write(abs, contents)
+
+ return this
+ }
+}
+
+class Magic extends ChainedMap {
+ /**
+ * @param {any} parent
+ */
+ constructor(parent) {
+ super(parent)
+
+ this.globs = {}
+
+ this.files = {
+ js: [],
+ other: [],
+ }
+
+ this.dirs = {}
+ this._debug = false
+ }
+
+ /**
+ * @param {Boolean} [should=true]
+ * @return {Magic}
+ */
+ debug(should = true) {
+ return this.set('debug', should)
+ }
+
+ /**
+ * @param {string} glob
+ * @return {Magic}
+ */
+ setGlob(glob) {
+ this.globs = {
+ glob,
+ opts: {stat: true, absolute: true},
+ }
+
+ return this
+ }
+
+ /**
+ * @param {Object} dirs
+ * @return {Magic}
+ */
+ setDirs(dirs) {
+ let {js, ts, temp, dist, dir} = dirs
+
+ // if not a single folder, split n pop
+ // if (js.includes('/')) js = js.split('/').pop()
+ // if (ts.includes('/')) ts = ts.split('/').pop()
+ // if (temp.includes('/')) temp = temp.split('/').pop()
+
+ // store on instance
+ this.dirs = {js, ts, temp, dir}
+
+ return this
+ }
+
+ /**
+ * @see Magic.files, Magic.globs, File
+ * @return {Magic}
+ */
+ gatherFiles() {
+ // extract variables
+ const {glob, opts} = this.globs
+
+ // do globbing
+ const found = new GlobSync(glob, opts).found
+
+ const debug = this.get('debug')
+
+ // add to instance
+ this.files = found.map(abs => new File({abs, debug}))
+
+ // const otherGlob = new GlobSync(other, opts).found
+ // other: otherGlob
+ // .filter(abs => !abs.includes('.js'))
+ // .map(abs => new File({abs, debug})),
+
+ return this
+ }
+
+ // --- handle
+
+ /**
+ * @see File.lebab
+ * @return {Magic}
+ */
+ lebab() {
+ this.files.forEach(file => {
+ file.load().lebab().write()
+ })
+
+ return this
+ }
+
+ /**
+ * @see Magic.gatherFiles, Magic.setDirs
+ * @return {Magic}
+ */
+ toTypeScript() {
+ // clean
+ execSync(`rm -f -r ${this.dirs.ts}/`, {stdio: 'inherit'})
+
+ // copy js dir to typescript dir
+ execSync(`cp -R -f ${this.dirs.js} ${this.dirs.ts}/`, {stdio: 'inherit'})
+
+ this.setGlob(this.dirs.ts + '/**/*.js')
+
+ return this
+ }
+ saveTypeScript() {
+ // then convert the js files
+ this.files.forEach(file => {
+ // file._debug = true
+ file
+ .load()
+ .del() // del .js, we already loaded contents
+ .changeExtension('.js', '.ts')
+ .write()
+ })
+ }
+
+ /**
+ * @see Magic.gatherFiles, Magic.setDirs
+ * @return {Magic}
+ */
+ toTemp() {
+ // clean
+ execSync(`rm -f -r ${this.dirs.temp}/`, {stdio: 'inherit'})
+
+ // copy ts dir to temp dir
+ execSync(`cp -R -f ${this.dirs.ts} ${this.dirs.temp}/`, {stdio: 'inherit'})
+
+ this.setGlob(this.dirs.temp + '/**/*.ts')
+
+ return this
+ }
+ saveTemp() {
+ this.files.forEach(file => {
+ file.load().del().changeExtension('.ts', '.js').removeModifiers().write()
+ })
+ return this
+ }
+}
+
+// @TODO: add options
+// @TODO: also add scripts with scriptflip...
+// const dirs = {
+// dir: __dirname,
+// js: 'test',
+// ts: 'typescript',
+// temp: 'temp',
+// dist: 'dist',
+// }
+
+const dirs = {
+ dir: __dirname,
+ ts: 'three/src',
+ temp: 'three/temp',
+ dist: 'three/dist',
+}
+
+let toTypescript = false
+let toTemp = false
+
+// toTypescript = true
+// toTemp = false
+
+if (toTypescript !== false) {
+ const magic = new Magic()
+
+ magic
+ .debug(false)
+ .setDirs(dirs)
+ .toTypeScript()
+ .gatherFiles()
+ .lebab()
+ .saveTypeScript()
+}
+
+if (toTemp !== false) {
+ const magic = new Magic()
+
+ magic.setDirs(dirs).toTemp().gatherFiles().saveTemp()
+}
+
+if (dirs.dist) {
+ const execa = require('execa')
+ execa('babel', [dirs.temp, '--out-dir=' + dirs.dist], {stdio: 'inherit'})
+}
+
+module.exports = Magic
+
+const {resolve} = require('path')
+const {execSync} = require('child_process')
+const log = require('fliplog')
+const lebab = require('lebab')
+const {read, write, del} = require('flipfile')
+const {GlobSync} = require('flipfile/glob')
+const ChainedMap = require('chain-able')
+
+/**
+ * @TODO:
+ * - [ ] should put the transformers as middleware
+ * - [ ] use file-chain now that it is extracted
+ * - [ ] run eslint on transformed files
+ */
+class File {
+ /**
+ * @param {Object} obj
+ */
+ constructor(obj) {
+ const {debug, abs} = obj
+ this.abs = abs
+ this._debug = !!debug
+ }
+
+ /**
+ * reads file
+ * @see File.contents
+ * @param {boolean} [force=false]
+ * @return {File}
+ */
+ load(force = false) {
+ if (this.contents !== undefined && force === false) {
+ return this
+ }
+
+ this.contents = read(this.abs)
+
+ log.blue('loaded content').data(this.abs, this.contents).echo(this._debug)
+
+ return this
+ }
+
+ del() {
+ del(this.abs)
+ return this
+ }
+
+ /**
+ * @return {File}
+ */
+ lebab() {
+ const features = ['let', 'arrow', 'commonjs', 'includes']
+ const {code, warnings} = lebab.transform(this.contents, features)
+
+ log.bold('label-ed').verbose().data({code, warnings}).echo(this._debug)
+
+ this.contents = code
+
+ return this
+ }
+
+ /**
+ * @param {string} from
+ * @param {string} to
+ * @return {File}
+ */
+ changeExtension(from, to) {
+ const abs = this.abs
+
+ this.abs = this.abs.replace(from, to).replace('//', '/')
+
+ log
+ .underline('changed path')
+ .data({from: abs, to: this.abs})
+ .echo(this._debug)
+
+ return this
+ }
+
+ /**
+ * @param {string} from
+ * @param {string} to
+ * @return {File}
+ */
+ changeDir(from, to) {
+ // const {input, temp} = dirs
+
+ const abs = this.abs
+
+ this.abs = this.abs.replace(from, to)
+ // const toDir = resolve(dir, './ts') .replace(dir, './')
+
+ log
+ .underline('changed dir')
+ .data({before: abs, after: this.abs, from, to})
+ .echo(this._debug)
+
+ return this
+ }
+
+ /**
+ * removes public/private/protected class properties
+ * since babel does not like them, currently
+ *
+ * @return {Magic}
+ */
+ removeModifiers() {
+ log.blue('data').verbose().data().echo(this._debug)
+
+ this.contents = this.contents.replace(
+ /( {0,4}public|private|protected )/gim,
+ ''
+ )
+
+ return this
+ }
+
+ /**
+ * @return {File}
+ */
+ write() {
+ const {abs, contents} = this
+
+ log.green('writing').data({abs, contents}).echo(this._debug)
+
+ write(abs, contents)
+
+ return this
+ }
+}
+
+class Magic extends ChainedMap {
+ /**
+ * @param {any} parent
+ */
+ constructor(parent) {
+ super(parent)
+
+ this.globs = {}
+
+ this.files = {
+ js: [],
+ other: [],
+ }
+
+ this.dirs = {}
+ this._debug = false
+ }
+
+ /**
+ * @param {Boolean} [should=true]
+ * @return {Magic}
+ */
+ debug(should = true) {
+ return this.set('debug', should)
+ }
+
+ /**
+ * @param {string} glob
+ * @return {Magic}
+ */
+ setGlob(glob) {
+ this.globs = {
+ glob,
+ opts: {stat: true, absolute: true},
+ }
+
+ return this
+ }
+
+ /**
+ * @param {Object} dirs
+ * @return {Magic}
+ */
+ setDirs(dirs) {
+ let {js, ts, temp, dist, dir} = dirs
+
+ // if not a single folder, split n pop
+ // if (js.includes('/')) js = js.split('/').pop()
+ // if (ts.includes('/')) ts = ts.split('/').pop()
+ // if (temp.includes('/')) temp = temp.split('/').pop()
+
+ // store on instance
+ this.dirs = {js, ts, temp, dir}
+
+ return this
+ }
+
+ /**
+ * @see Magic.files, Magic.globs, File
+ * @return {Magic}
+ */
+ gatherFiles() {
+ // extract variables
+ const {glob, opts} = this.globs
+
+ // do globbing
+ const found = new GlobSync(glob, opts).found
+
+ const debug = this.get('debug')
+
+ // add to instance
+ this.files = found.map(abs => new File({abs, debug}))
+
+ // const otherGlob = new GlobSync(other, opts).found
+ // other: otherGlob
+ // .filter(abs => !abs.includes('.js'))
+ // .map(abs => new File({abs, debug})),
+
+ return this
+ }
+
+ // --- handle
+
+ /**
+ * @see File.lebab
+ * @return {Magic}
+ */
+ lebab() {
+ this.files.forEach(file => {
+ file.load().lebab().write()
+ })
+
+ return this
+ }
+
+ /**
+ * @see Magic.gatherFiles, Magic.setDirs
+ * @return {Magic}
+ */
+ toTypeScript() {
+ // clean
+ execSync(`rm -f -r ${this.dirs.ts}/`, {stdio: 'inherit'})
+
+ // copy js dir to typescript dir
+ execSync(`cp -R -f ${this.dirs.js} ${this.dirs.ts}/`, {stdio: 'inherit'})
+
+ this.setGlob(this.dirs.ts + '/**/*.js')
+
+ return this
+ }
+ saveTypeScript() {
+ // then convert the js files
+ this.files.forEach(file => {
+ // file._debug = true
+ file
+ .load()
+ .del() // del .js, we already loaded contents
+ .changeExtension('.js', '.ts')
+ .write()
+ })
+ }
+
+ /**
+ * @see Magic.gatherFiles, Magic.setDirs
+ * @return {Magic}
+ */
+ toTemp() {
+ // clean
+ execSync(`rm -f -r ${this.dirs.temp}/`, {stdio: 'inherit'})
+
+ // copy ts dir to temp dir
+ execSync(`cp -R -f ${this.dirs.ts} ${this.dirs.temp}/`, {stdio: 'inherit'})
+
+ this.setGlob(this.dirs.temp + '/**/*.ts')
+
+ return this
+ }
+ saveTemp() {
+ this.files.forEach(file => {
+ file.load().del().changeExtension('.ts', '.js').removeModifiers().write()
+ })
+ return this
+ }
+}
+
+// @TODO: add options
+// @TODO: also add scripts with scriptflip...
+// const dirs = {
+// dir: __dirname,
+// js: 'test',
+// ts: 'typescript',
+// temp: 'temp',
+// dist: 'dist',
+// }
+
+const dirs = {
+ dir: __dirname,
+ ts: 'three/src',
+ temp: 'three/temp',
+ dist: 'three/dist',
+}
+
+let toTypescript = false
+let toTemp = false
+
+// toTypescript = true
+// toTemp = false
+
+if (toTypescript !== false) {
+ const magic = new Magic()
+
+ magic
+ .debug(false)
+ .setDirs(dirs)
+ .toTypeScript()
+ .gatherFiles()
+ .lebab()
+ .saveTypeScript()
+}
+
+if (toTemp !== false) {
+ const magic = new Magic()
+
+ magic.setDirs(dirs).toTemp().gatherFiles().saveTemp()
+}
+
+if (dirs.dist) {
+ const execa = require('execa')
+ execa('babel', [dirs.temp, '--out-dir=' + dirs.dist], {stdio: 'inherit'})
+}
+
+module.exports = Magic
diff --git a/_modules/lego-cli/plugins/ast/processing.js b/_modules/lego-cli/plugins/ast/processing.js
new file mode 100644
index 0000000..7dc905f
--- /dev/null
+++ b/_modules/lego-cli/plugins/ast/processing.js
@@ -0,0 +1 @@
+// https://github.com/processing-js/processing-js/blob/master/src/Parser/Parser.js#L305
diff --git a/_modules/lego-cli/plugins/ast/typescript.js b/_modules/lego-cli/plugins/ast/typescript.js
new file mode 100644
index 0000000..800d811
--- /dev/null
+++ b/_modules/lego-cli/plugins/ast/typescript.js
@@ -0,0 +1,25 @@
+module.exports = {
+ ts(TSC_SOURCE, TSC_OUT) {
+ const {read, write} = this.dep()
+ const ts = require('typescript')
+ const source = read(TSC_SOURCE)
+
+ let result = ts.transpileModule(source, {
+ compilerOptions: {module: ts.ModuleKind.CommonJS},
+ })
+ write(require.resolve(TSC_OUT), result.outputText)
+
+ console.log(JSON.stringify(result))
+ process.exit()
+ },
+ tsc(buildTests = false) {
+ const {script} = this.dep()
+
+ if (buildTests) {
+ const flags =
+ '--pretty --sourceMap --allowJs --project test --outDir test-dist'
+ return script('tsc', flags)
+ }
+ return script('tsc')
+ },
+}
diff --git a/_modules/lego-cli/plugins/bundle/browserify.js b/_modules/lego-cli/plugins/bundle/browserify.js
new file mode 100644
index 0000000..431d841
--- /dev/null
+++ b/_modules/lego-cli/plugins/bundle/browserify.js
@@ -0,0 +1,6 @@
+module.exports = {
+ name: 'browserify',
+ browserify() {
+ // browserify src -o dists/browserified/index.js
+ },
+}
diff --git a/_modules/lego-cli/plugins/bundle/optimizejs.js b/_modules/lego-cli/plugins/bundle/optimizejs.js
new file mode 100644
index 0000000..8626bc8
--- /dev/null
+++ b/_modules/lego-cli/plugins/bundle/optimizejs.js
@@ -0,0 +1,16 @@
+module.exports = {
+ name: 'optimizejs',
+
+ /**
+ * @since 0.0.1
+ * @tutorial https://github.com/nolanlawson/optimize-js
+ * @param {string} input
+ * @return {string} optimized output
+ */
+ optimize(input) {
+ const optimizeJs = require('optimize-js')
+ return optimizeJs(input, {
+ sourceMap: true,
+ })
+ },
+}
diff --git a/_modules/lego-cli/plugins/bundle/rollup.js b/_modules/lego-cli/plugins/bundle/rollup.js
new file mode 100644
index 0000000..35b5587
--- /dev/null
+++ b/_modules/lego-cli/plugins/bundle/rollup.js
@@ -0,0 +1,14 @@
+module.exports = {
+ name: 'rollup',
+
+ rollup(flags = '', ROLLUP_CONFIG_CLI) {
+ if (Array.isArray(flags)) return flags.map(flag => this.rollup(flag))
+ const config = ROLLUP_CONFIG_CLI
+ const {script} = this.dep()
+
+ return script('rollup', '-c ' + require.resolve(config) + ' ' + flags)
+ },
+ rollupNode(buildFile = './build', overrides = {}) {
+ return require(buildFile)(overrides)
+ },
+}
diff --git a/_modules/lego-cli/plugins/docs/README.md b/_modules/lego-cli/plugins/docs/README.md
new file mode 100644
index 0000000..5257695
--- /dev/null
+++ b/_modules/lego-cli/plugins/docs/README.md
@@ -0,0 +1 @@
+https://github.com/jsdoc3/jsdoc/issues/250
diff --git a/_modules/lego-cli/plugins/docs/doctrine.js b/_modules/lego-cli/plugins/docs/doctrine.js
new file mode 100644
index 0000000..c7ef175
--- /dev/null
+++ b/_modules/lego-cli/plugins/docs/doctrine.js
@@ -0,0 +1,165 @@
+var doctrineAPI = require('doctrine')
+
+var parsed = doctrineAPI.parse(
+ [
+ `
+ /**
+ * @classdesc this is to avoid circular requires
+ * because MergeChain & MethodChain extend this
+ * yet .method & .merge use those chains
+ *
+ * @since 4.0.0-alpha.1
+ * @inheritdoc
+ * @class ChainedMapBase
+ * @member ChainedMapBase
+ * @category Chainable
+ * @extends {Chainable}
+ * @type {Chainable}
+ *
+ * @types ChainedMapBase
+ * @tests ChainedMap
+ *
+ * @prop {Meta} meta
+ * @prop {Map} store
+ *
+ * {@link https://ponyfoo.com/articles/es6-maps-in-depth pony-map}
+ * {@link https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Map mozilla-map}
+ * @see {@link pony-map}
+ * @see {@link mozilla-map}
+ *
+ * @see ChainedMap
+ * @see Chainable
+ * @see MergeChain
+ * @see MethodChain
+ * @see ChainedMap
+ *
+ */
+ `,
+ `
+ /**
+ * @param {*} x value
+ * @return {boolean} isDate
+ *
+ * @since 3.0.0
+ * @memberOf is
+ * @func isDate
+ *
+ * @example
+ *
+ * isDate(new Date())
+ * //=> true
+ * isDate(Date.now())
+ * //=> false
+ * isDate(1)
+ * //=> false
+ * isDate('')
+ * //=> false
+ *
+ * @example
+ *
+ * const e = {}
+ * eh[Symbol.toStringTag] = '[Object Date]'
+ * isDate(eh)
+ * //=> true
+ *
+ * @example
+ *
+ * class Eh extends Date()
+ * isDate(new Eh())
+ * //=> true
+ */
+ `,
+ // '/**',
+ // ' * This function comment is parsed by doctrine',
+ // ' * @param {{ok:String}} userName',
+ // '*/',
+ ].join('\n'),
+ {unwrap: true}
+)
+
+var ast = {
+ description: '/**',
+ tags: [
+ {
+ title: 'classdesc',
+ description:
+ 'this is to avoid circular requires\n because MergeChain & MethodChain extend this\n yet .method & .merge use those chains',
+ },
+ {title: 'since', description: '4.0.0-alpha.1'},
+ {title: 'inheritdoc', description: null},
+ {
+ title: 'class',
+ description: null,
+ type: null,
+ name: 'ChainedMapBase',
+ },
+ {
+ title: 'member',
+ description: null,
+ type: null,
+ name: 'ChainedMapBase',
+ },
+ {title: 'category', description: 'Chainable'},
+ {
+ title: 'extends',
+ description: null,
+ type: {type: 'NameExpression', name: 'Chainable'},
+ name: null,
+ },
+ {
+ title: 'type',
+ description: null,
+ type: {type: 'NameExpression', name: 'Chainable'},
+ },
+ {title: 'types', description: 'ChainedMapBase'},
+ {title: 'tests', description: 'ChainedMap'},
+ {
+ title: 'prop',
+ description: null,
+ type: {type: 'NameExpression', name: 'Meta'},
+ name: 'meta',
+ },
+ {
+ title: 'prop',
+ description:
+ '{@link https://ponyfoo.com/articles/es6-maps-in-depth pony-map}\n{@link https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Map mozilla-map}',
+ type: {type: 'NameExpression', name: 'Map'},
+ name: 'store',
+ },
+ {title: 'see', description: '{@link pony-map}'},
+ {title: 'see', description: '{@link mozilla-map}'},
+ {title: 'see', description: 'ChainedMap'},
+ {title: 'see', description: 'Chainable'},
+ {title: 'see', description: 'MergeChain'},
+ {title: 'see', description: 'MethodChain'},
+ {title: 'see', description: 'ChainedMap\n\n/\n\n\n/**'},
+ {
+ title: 'param',
+ description: 'value',
+ type: {type: 'AllLiteral'},
+ name: 'x',
+ },
+ {
+ title: 'return',
+ description: 'isDate',
+ type: {type: 'NameExpression', name: 'boolean'},
+ },
+ {title: 'since', description: '3.0.0'},
+ {title: 'memberOf', description: 'is'},
+ {title: 'func', description: null, name: 'isDate'},
+ {
+ title: 'example',
+ description:
+ 'isDate(new Date())\n //=> true\n isDate(Date.now())\n //=> false\n isDate(1)\n //=> false\n isDate(\'\')\n //=> false',
+ },
+ {
+ title: 'example',
+ description:
+ 'const e = {}\n eh[Symbol.toStringTag] = \'[Object Date]\'\n isDate(eh)\n //=> true',
+ },
+ {
+ title: 'example',
+ description: 'class Eh extends Date()\n isDate(new Eh())\n //=> true\n/',
+ },
+ ],
+}
diff --git a/_modules/lego-cli/plugins/docs/dox.js b/_modules/lego-cli/plugins/docs/dox.js
new file mode 100644
index 0000000..5a3d7b6
--- /dev/null
+++ b/_modules/lego-cli/plugins/docs/dox.js
@@ -0,0 +1,53 @@
+// const dox = require('dox')
+const dox = require('../../../../_modules/_dox')
+const log = require('fliplog')
+
+const docblock = `
+/**
+ * @classdesc this is to avoid circular requires
+ * because MergeChain & MethodChain extend this
+ * yet .method & .merge use those chains
+ *
+ * @since 4.0.0-alpha.1
+ * @inheritdoc
+ * @class ChainedMapBase
+ * @member ChainedMapBase
+ * @category Chainable
+ * @extends {Chainable}
+ * @type {Chainable}
+ *
+ * @types ChainedMapBase
+ * @tests ChainedMap
+ *
+ * @prop {Meta} meta
+ * @prop {Map} store
+ *
+ * {@link https://ponyfoo.com/articles/es6-maps-in-depth pony-map}
+ * {@link https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Map mozilla-map}
+ * @see {@link pony-map}
+ * @see {@link mozilla-map}
+ *
+ * @see ChainedMap
+ * @see Chainable
+ * @see MergeChain
+ * @see MethodChain
+ * @see ChainedMap
+ *
+ */
+// function eh() {}
+`
+
+/**
+ *
+ */
+function doxPlugin() {
+ const files = [docblock]
+ files.forEach(file => {
+ const obj = dox.parseComments(file)
+ log.json({obj}).echo()
+ })
+
+ return this
+}
+
+doxPlugin()
diff --git a/_modules/lego-cli/plugins/docs/doxdox.js b/_modules/lego-cli/plugins/docs/doxdox.js
new file mode 100644
index 0000000..78ce5bd
--- /dev/null
+++ b/_modules/lego-cli/plugins/docs/doxdox.js
@@ -0,0 +1,70 @@
+module.exports = {
+ /**
+ * https://github.com/nhnent/tui.jsdoc-template
+ * @param {Array} files
+ * @return {AppCli} @chainable
+ */
+ doxdox(files) {
+ console.log(
+ 'had issue with requiring absolute before, but should be fixed in latest'
+ )
+ console.log(
+ `doxdox 'src/**/*.js' --layout markdown --output docs/doxdox.md`
+ )
+ return this
+ // jsdoc2md --config=jsdoc.json
+ // jsdoc2md --source src --config=jsdoc.json
+ // https://github.com/jsdoc3/jsdoc/blob/master/lib/jsdoc/env.js
+ // https://github.com/jsdoc3/jsdoc/blob/master/cli.js
+ // jsdoc src --recurse --template='node_modules/tui-jsdoc-template' --destination='docgen' --readme='README.md' ENV.conf.plugins="['node_modules/jsdoc-babel', 'plugins/markdown']"
+ // jsdoc --include 'src' --recurse --template='node_modules/tui-jsdoc-template' --destination='docgen' --readme='README.md'
+ //
+ // --template 'node_modules/tui-jsdoc-template'
+ // jsdoc src --recurse --destination 'docgen'
+ //
+ // require('fliplog').trackConsole();
+ //
+ // * @module jsdoc/opts/args
+ // * @requires jsdoc/opts/argparser
+ //
+ //
+ // ./jsdoc/jsdoc src --recurse --destination 'docgen' --plugins "node_modules/jsdoc-babel,plugins/markdown"
+ // node ./node_modules/jsdoc/jsdoc src --recurse --destination 'docgen' --plugins "node_modules/jsdoc-babel,node_modules/jsdoc/plugins/markdown.js"
+
+ // const doxdox = require('doxdox')
+ const doxdox = require('../../../nofundocs/doxdox')
+ files = this.docFiles(files)
+
+ log
+ .data({
+ files,
+ config: {
+ // parser: 'dox',
+ // layout: 'Markdown',
+ pkg: this.pkgjson,
+ },
+ })
+ .echo()
+
+ log.white('files: ').data(files).echo()
+
+ // stupid paths
+ doxdox
+ .parseInputs(files, {
+ // parser: 'dox',
+ // layout: 'markdown',
+ parser: require.resolve('doxdox-parser-dox').replace(process.cwd(), ''),
+ layout: require
+ .resolve('doxdox-plugin-markdown')
+ .replace(process.cwd(), ''),
+ pkg: this.pkgjson,
+ })
+ .then(content => {
+ log.cyan('writing docs').echo()
+ log.white('content: ' + content).echo()
+ File.src('./docs/docs.md', this.dir).setContent(content).write()
+ })
+
+ return this
+ },
+}
diff --git a/_modules/lego-cli/plugins/docs/esdoc.js b/_modules/lego-cli/plugins/docs/esdoc.js
new file mode 100644
index 0000000..93f2487
--- /dev/null
+++ b/_modules/lego-cli/plugins/docs/esdoc.js
@@ -0,0 +1,9 @@
+module.exports = {
+ /**
+ * https://github.com/esdoc/esdoc
+ * https://github.com/jsdoc3/jsdoc/issues/833
+ * http://stackoverflow.com/questions/25314979/documenting-side-effects-of-javascript-methods
+ * https://github.com/google/closure-compiler/wiki/Annotating-JavaScript-for-the-Closure-Compiler#nosideeffects-modifies-thisarguments
+ */
+ esdoc() {},
+}
diff --git a/_modules/lego-cli/plugins/docs/flowdoc.js b/_modules/lego-cli/plugins/docs/flowdoc.js
new file mode 100644
index 0000000..8ce76e8
--- /dev/null
+++ b/_modules/lego-cli/plugins/docs/flowdoc.js
@@ -0,0 +1,25 @@
+module.exports = {
+ name: 'flowdocs',
+ /**
+ * @since 0.0.1
+ * https://github.com/Kegsay/flow-jsdoc
+ * @desc jsdocs with flow support
+ * @param {Array} files
+ * @return {AppCli} @chainable
+ */
+ flowdocs(files) {
+ files = this.docFiles(files)
+
+ const babel = require('babel-core')
+ files.forEach(file => {
+ const {code} = babel.transform('code', {
+ plugins: ['jsdoc'],
+ })
+ const content = code
+
+ log.cyan('writing docs').echo()
+ log.white('content: ' + content).data(file).echo()
+ })
+ return this
+ },
+}
diff --git a/_modules/lego-cli/plugins/docs/jsdoc.js b/_modules/lego-cli/plugins/docs/jsdoc.js
new file mode 100644
index 0000000..ee56dd8
--- /dev/null
+++ b/_modules/lego-cli/plugins/docs/jsdoc.js
@@ -0,0 +1,26 @@
+module.exports = {
+ /**
+ * @since 0.0.1
+ * @see https://github.com/nhnent/tui.jsdoc-template
+ * @param {Array} files
+ * @return {AppCli} @chainable
+ */
+ jsdocs(files) {
+ files = this.docFiles(files)
+
+ const jsdoc = require('jsdoc-api')
+ let jsdocOpts = this.getPkg().jsdoc || this.getPkg().jsdocs
+
+ if (!jsdocOpts && exists(resolve(this.dir, './jsdoc.js'))) {
+ jsdocOpts = require(resolve(this.dir, './jsdoc.js')) // eslint-disable-line
+ }
+ if (!jsdocOpts && exists(resolve(this.dir, './jsdoc.json'))) {
+ jsdocOpts = require(resolve(this.dir, './jsdoc.json')) // eslint-disable-line
+ }
+
+ jsdocOpts.files = files
+ log.data({jsdocOpts}).text('jsdoc opts').echo()
+ jsdoc.explainSync(jsdocOpts)
+ return this
+ },
+}
diff --git a/_modules/lego-cli/plugins/docs/jsdoc2md.js b/_modules/lego-cli/plugins/docs/jsdoc2md.js
new file mode 100644
index 0000000..d8956c7
--- /dev/null
+++ b/_modules/lego-cli/plugins/docs/jsdoc2md.js
@@ -0,0 +1,16 @@
+module.exports = {
+ /**
+ * @since 0.0.1
+ * @param {Array} pattern array of glob patterns
+ * @return {AppCli} @chainable
+ */
+ jsdoc2md(pattern = ['disted/**/*.js']) {
+ const {log} = this.deps()
+ const jsdoc2md = require('jsdoc-to-markdown')
+
+ const docs = jsdoc2md.renderSync({files: pattern})
+ log.quick(docs)
+
+ return this
+ },
+}
diff --git a/_modules/lego-cli/plugins/docs/jsdox.js b/_modules/lego-cli/plugins/docs/jsdox.js
new file mode 100644
index 0000000..a926251
--- /dev/null
+++ b/_modules/lego-cli/plugins/docs/jsdox.js
@@ -0,0 +1,17 @@
+module.exports = {
+ /**
+ * @tutorial http://jsdox.org/
+ * @param {Array} files
+ * @return {AppCli} @chainable
+ */
+ jsdox(files) {
+ const jsdox = require('jsdox')
+
+ files.forEach(file => {
+ // , templateDir, cb, fileCb
+ jsdox.generateForDir(file, this.getPkg().folders.docs || 'docgen')
+ })
+
+ return this
+ },
+}
diff --git a/_modules/lego-cli/plugins/docs/tsdoc.js b/_modules/lego-cli/plugins/docs/tsdoc.js
new file mode 100644
index 0000000..666075d
--- /dev/null
+++ b/_modules/lego-cli/plugins/docs/tsdoc.js
@@ -0,0 +1,13 @@
+module.exports = {
+ /**
+ * @TODO `typedoc --exclude 'loader/LoaderAPI.ts' --target es6 --excludeExternals --includeDeclarations --out tsdox src`
+ * @since 0.0.1
+ * @see https://www.npmjs.com/package/tsd-jsdoc
+ * @see http://ts2jsdoc.js.org/
+ * @param {Array} files
+ * @return {AppCli} @chainable
+ */
+ tsdocs(files) {
+ return this
+ },
+}
diff --git a/_modules/lego-cli/plugins/fs/copy.js b/_modules/lego-cli/plugins/fs/copy.js
new file mode 100644
index 0000000..b6c7131
--- /dev/null
+++ b/_modules/lego-cli/plugins/fs/copy.js
@@ -0,0 +1,36 @@
+module.exports = {
+ /* prettier-ignore */
+ copy(root = false) {
+ const script = this.deps().script
+
+ // @TODO: dist & root (does it ever need to be in dist except for buble?)
+ const scripts = script()
+ .add()
+ .bin('flow-remove-types')
+ .raw('src/')
+ .flag('pretty')
+ .flag('quiet')
+ .flag('all')
+ .flag('out-dir')
+ .arg('./dist')
+
+ if (root) {
+ scripts
+ .add()
+ .bin('flow-remove-types')
+ .raw('src/'
+ .flag('pretty')
+ .flag('quiet')
+ .flag('all')
+ .flag('out-dir')
+ .arg('./')
+ }
+
+ scripts.remember = {
+ start() {},
+ finish() {},
+ }
+
+ scripts.toString()
+ }
+}
diff --git a/_modules/lego-cli/plugins/fs/find.js b/_modules/lego-cli/plugins/fs/find.js
new file mode 100644
index 0000000..c2b0678
--- /dev/null
+++ b/_modules/lego-cli/plugins/fs/find.js
@@ -0,0 +1,35 @@
+module.exports = {
+ /**
+ * @since 0.0.1
+ * @desc finds docfiles using a glob
+ * @param {Array} pattern array of glob patterns
+ * @return {Array} file
+ */
+ docFiles(pattern = ['disted/**/*.js']) {
+ const {log, globby, find} = this.deps()
+
+ if (Array.isArray(pattern) === false) {
+ // pattern = ['disted/**/*.js']
+ pattern = [pattern]
+ }
+ log.blue('docs pattern').json({pattern, dir: this.dir}).echo(true)
+
+ const files = globby.sync(pattern, {
+ cwd: this.dir,
+ absolute: true,
+ })
+
+ return files
+ },
+
+ /**
+ * @since 0.0.1
+ * @param {Array} pattern array of glob patterns
+ * @return {AppCli} @chainable
+ */
+ docs(pattern = ['disted/**/*.js']) {
+ this.doxdox([pattern])
+ // this.docFiles(pattern)
+ return this
+ },
+}
diff --git a/_modules/lego-cli/plugins/generate/doc-to-assert.js b/_modules/lego-cli/plugins/generate/doc-to-assert.js
new file mode 100644
index 0000000..ef89066
--- /dev/null
+++ b/_modules/lego-cli/plugins/generate/doc-to-assert.js
@@ -0,0 +1 @@
+// https://www.npmjs.com/package/jsdoc-to-assert
diff --git a/_modules/lego-cli/plugins/generate/dojo.js b/_modules/lego-cli/plugins/generate/dojo.js
new file mode 100644
index 0000000..1b9c32e
--- /dev/null
+++ b/_modules/lego-cli/plugins/generate/dojo.js
@@ -0,0 +1 @@
+// https://github.com/dojo/meta
diff --git a/_modules/lego-cli/plugins/generate/skeleton.js b/_modules/lego-cli/plugins/generate/skeleton.js
new file mode 100644
index 0000000..35439c2
--- /dev/null
+++ b/_modules/lego-cli/plugins/generate/skeleton.js
@@ -0,0 +1,21 @@
+module.exports = {
+ /**
+ * @since 0.0.1
+ * @desc regenerate interactively
+ * @return {AppCLI} @chainable
+ */
+ skeleton() {
+ const gen = require('../interactive/interactive')
+ gen(this.dir)
+ return this
+ },
+
+ /**
+ * @since 0.0.1
+ * @param {string} dir
+ * @return {AppCLI} @chainable
+ */
+ // static init(dir) {
+ // return new AppCLI(dir)
+ // }
+}
diff --git a/_modules/lego-cli/plugins/lint/autofix.js b/_modules/lego-cli/plugins/lint/autofix.js
new file mode 100644
index 0000000..41eb25d
--- /dev/null
+++ b/_modules/lego-cli/plugins/lint/autofix.js
@@ -0,0 +1,104 @@
+const {resolve} = require('path')
+const {read, write, isDir} = require('flipfile')
+const globby = require('globby')
+const log = require('fliplog')
+
+class CLI {
+ constructor(dir) {
+ this.dir = dir
+ }
+
+ find(pattern = ['src/**/*.js', '!node_modules']) {
+ this.found = globby.sync(pattern, {
+ cwd: this.dir,
+ absolute: true,
+ })
+ return this.found
+ }
+
+ mapFiles() {
+ const mapped = this.found
+ .map(abs => {
+ if (isDir(abs)) return null
+ return {
+ source: read(abs),
+ filename: abs,
+ }
+ })
+ .filter(file => file)
+ .map(file => ({source: this.prettier(file), abs: file.abs}))
+ .map(file => this.eslint(file))
+ log.quick(mapped)
+ }
+
+ eslint(file, config = require('../../.eslintrc.js')) {
+ const {source, filename} = file
+ const eslint = require('eslint')
+ const {linter} = eslint
+
+ const colored = log.colored(source, 'cyan')
+ log.cyan('before\n').data(colored).echo() // "var foo = bar;"
+
+ const messages = linter.verify(source, config, {filename})
+ const code = linter.getSourceCode()
+
+ log.yellow('messages').data(messages).echo()
+ if (!code || !code.text) {
+ log.red('could not handle this file ').data({filename}).echo()
+ return source
+ }
+ // log.yellow('code').fmtobj(code).echo()
+ log.blue(code.text).echo() // "var foo = bar;"
+ return code.text
+ }
+
+ /**
+ * @since 0.0.1
+ * @tutorial https://github.com/prettier/prettier
+ * @param {string} code
+ * @param {Object} [config=null] prettier options
+ * @return {string} prettified output
+ */
+ prettier(file, config = null) {
+ const {filename, source} = file
+ const prettier = require('prettier')
+
+ return prettier.format(source, {
+ // Indent lines with tabs
+ useTabs: false,
+
+ // Fit code within this line limit
+ printWidth: 80,
+
+ // Number of spaces it should use per tab
+ tabWidth: 2,
+
+ // If true, will use single instead of double quotes
+ singleQuote: true,
+
+ // Controls the printing of trailing commas wherever possible. Valid options:
+ // "none" - No trailing commas
+ // "es5" - Trailing commas where valid in ES5 (objects, arrays, etc)
+ // "all" - Trailing commas wherever possible (function arguments)
+ trailingComma: 'es5',
+
+ // Controls the printing of spaces inside object literals
+ bracketSpacing: true,
+
+ // If true, puts the `>` of a multi-line jsx element at the end of
+ // the last line instead of being alone on the next line
+ jsxBracketSameLine: false,
+
+ // Which parser to use. Valid options are "flow" and "babylon"
+ parser: 'babylon',
+
+ // Whether to add a semicolon at the end of every line (semi: true),
+ // or only at the beginning of lines that may introduce ASI failures (semi: false)
+ semi: false,
+ })
+ }
+}
+
+const cli = new CLI(resolve('../../'))
+cli.find()
+cli.mapFiles()
diff --git a/_modules/lego-cli/plugins/lint/prettier.js b/_modules/lego-cli/plugins/lint/prettier.js
new file mode 100644
index 0000000..348b536
--- /dev/null
+++ b/_modules/lego-cli/plugins/lint/prettier.js
@@ -0,0 +1,46 @@
+module.exports = {
+ /**
+ * @since 0.0.1
+ * @tutorial https://github.com/prettier/prettier
+ * @param {string} code
+ * @param {Object} [config=null] prettier options
+ * @return {string} prettified output
+ */
+ prettier(code, config = null) {
+ const prettier = require('prettier')
+
+ return prettier.format(code, {
+ // Indent lines with tabs
+ useTabs: false,
+
+ // Fit code within this line limit
+ printWidth: 80,
+
+ // Number of spaces it should use per tab
+ tabWidth: 2,
+
+ // If true, will use single instead of double quotes
+ singleQuote: true,
+
+ // Controls the printing of trailing commas wherever possible. Valid options:
+ // "none" - No trailing commas
+ // "es5" - Trailing commas where valid in ES5 (objects, arrays, etc)
+ // "all" - Trailing commas wherever possible (function arguments)
+ trailingComma: 'es5',
+
+ // Controls the printing of spaces inside object literals
+ bracketSpacing: true,
+
+ // If true, puts the `>` of a multi-line jsx element at the end of
+ // the last line instead of being alone on the next line
+ jsxBracketSameLine: false,
+
+ // Which parser to use. Valid options are "flow" and "babylon"
+ parser: 'babylon',
+
+ // Whether to add a semicolon at the end of every line (semi: true),
+ // or only at the beginning of lines that may introduce ASI failures (semi: false)
+ semi: false,
+ })
+ },
+}
diff --git a/_modules/lego-cli/plugins/make/Makefile.1 b/_modules/lego-cli/plugins/make/Makefile.1
new file mode 100644
index 0000000..31e74c4
--- /dev/null
+++ b/_modules/lego-cli/plugins/make/Makefile.1
@@ -0,0 +1,17 @@
+GITBOOK = node_modules/.bin/gitbook
+JSDOC = node_modules/.bin/jsdoc
+LESS = node_modules/.bin/lessc
+
+
+JSDOC_FILES := $(shell find jsdoc -type f | sort)
+LESS_FILES := $(shell find less -name '*.less' | sort)
+
+docs/%: $(VERSION)/docs/%
+ mkdir -p '$(@D)'
+ cp '$<' '$@'
+
+.PHONY: gitbook
+gitbook: check-version
+ $(GITBOOK) build manual './manual'
+ find './manual' -name '*.html' -print0 \
+ | xargs -0 perl -p -i -e 's/ data-revision="[^"]*"//g'
diff --git a/_modules/lego-cli/plugins/minify/butternut.js b/_modules/lego-cli/plugins/minify/butternut.js
new file mode 100644
index 0000000..f1bcba3
--- /dev/null
+++ b/_modules/lego-cli/plugins/minify/butternut.js
@@ -0,0 +1 @@
+// https://github.com/Rich-Harris/butternut
diff --git a/_modules/lego-cli/plugins/scripts/argv.js b/_modules/lego-cli/plugins/scripts/argv.js
new file mode 100644
index 0000000..38ab238
--- /dev/null
+++ b/_modules/lego-cli/plugins/scripts/argv.js
@@ -0,0 +1,52 @@
+const argvs = fwf(process.argv.slice(2))
+
+/**
+ * http://blog.millermedeiros.com/inline-docs/
+ * http://dailyjs.com/post/framework-part-46
+ * https://documentjs.com/docs/index.html (too old)
+ *
+ * @see https://github.com/yeoman/generator/blob/master/jsdoc.json
+ * @desc takes in argv, calls method on CLI
+ * @param {AppCli} cli
+ * @return {void}
+ * @type {Function}
+ */
+function handle(cli) {
+ log.registerCatch()
+
+ delete argvs._
+
+ const argv = Object.values(argvs)
+ const argk = Object.keys(argvs)
+
+ log.emoji('flag').cyan('argv/flags:').data(argvs).echo()
+
+ argk.forEach((method, i) => {
+ const val = argv[i]
+ log.emoji('phone').blue('cli: ' + method).data(val).echo(true)
+
+ if (cli[method]) {
+ cli[method](val, argvs)
+ }
+ else {
+ log.emoji('find').blue('no method for: ' + method).data(val).echo(true)
+ }
+ })
+}
+
+
+
+
+// --- docs ---
+
+
+
+
+/**
+ * @since 0.0.1
+ * @return {AppCli} @chainable
+ */
+handle() {
+ handle(this)
+ return this
+}
diff --git a/_modules/lego-cli/plugins/scripts/cmd.js b/_modules/lego-cli/plugins/scripts/cmd.js
new file mode 100644
index 0000000..0aaea89
--- /dev/null
+++ b/_modules/lego-cli/plugins/scripts/cmd.js
@@ -0,0 +1,11 @@
+module.exports = {
+ /**
+ * @since 0.0.1
+ * @param {ChainedMap | *} parent
+ */
+ constructor(parent) {
+ super(parent)
+
+ this.scriptChain = () => new Script()
+ },
+}
diff --git a/_modules/lego-cli/plugins/scripts/npm.js b/_modules/lego-cli/plugins/scripts/npm.js
new file mode 100644
index 0000000..378759a
--- /dev/null
+++ b/_modules/lego-cli/plugins/scripts/npm.js
@@ -0,0 +1,15 @@
+module.exports = {
+ /**
+ * @since 0.0.1
+ * @param {any} names npm scripts to run
+ * @return {CLI} @chainable
+ */
+ npm(names = null) {
+ const scripts = this.scriptChain().debug(false)
+
+ toarr(names).forEach(name => scripts.add().npm(name))
+ scripts.run()
+
+ return this
+ },
+}
diff --git a/_modules/lego-cli/plugins/scripts/open.js b/_modules/lego-cli/plugins/scripts/open.js
new file mode 100644
index 0000000..6d29164
--- /dev/null
+++ b/_modules/lego-cli/plugins/scripts/open.js
@@ -0,0 +1,6 @@
+module.exports = {
+ // https://github.com/sindresorhus/open-editor
+ openFile(files, editor = 'atom') {
+ require('open-editor')(files)
+ },
+}
diff --git a/_modules/lego-cli/plugins/scripts/pkg.js b/_modules/lego-cli/plugins/scripts/pkg.js
new file mode 100644
index 0000000..ad07582
--- /dev/null
+++ b/_modules/lego-cli/plugins/scripts/pkg.js
@@ -0,0 +1,33 @@
+module.exports = {
+ /**
+ * @since 0.0.1
+ * @desc requires pkgjson using this.dir
+ * @return {AppCLI} @chainable
+ */
+ setup() {
+ const pkgPath = resolve(this.dir, './package.json')
+
+ log.green('pkg: ').data({pkgPath, dir: this.dir}).echo(this.get('debug'))
+
+ // eslint-disable-next-line
+ this.pkgjson = require(pkgPath)
+
+ return this
+ },
+
+ /**
+ * @protected
+ * @since 0.0.1
+ * @see this.setup
+ * @desc regenerate interactively
+ * @return {AppCLI} @chainable
+ */
+ getPkg() {
+ if (!this.pkgjson) this.setup()
+
+ // defaults
+ if (!this.pkgjson) this.pkgjson.folders = {}
+
+ return this.pkgjson
+ },
+}
diff --git a/_modules/lego-cli/plugins/scripts/test.js b/_modules/lego-cli/plugins/scripts/test.js
new file mode 100644
index 0000000..f9c4a0c
--- /dev/null
+++ b/_modules/lego-cli/plugins/scripts/test.js
@@ -0,0 +1,6 @@
+module.exports = {
+ test(built = false) {
+ return script('ava', !built ? '--verbose' : 'test-dist/built.js')
+ // return script('test')
+ },
+}
diff --git a/_modules/lego-cli/plugins/scripts/yarn.js b/_modules/lego-cli/plugins/scripts/yarn.js
new file mode 100644
index 0000000..ac20470
--- /dev/null
+++ b/_modules/lego-cli/plugins/scripts/yarn.js
@@ -0,0 +1 @@
+console.log('todo')
diff --git a/bench/vs-vanilla-simple.js b/bench/vs-vanilla-simple.js
new file mode 100644
index 0000000..072cb84
--- /dev/null
+++ b/bench/vs-vanilla-simple.js
@@ -0,0 +1,153 @@
+const R = require('ramda')
+const timer = require('fliptime')
+const log = require('fliplog')
+const Bench = require('../_modules/bench-chain')
+const ChainedMap = require('../src/ChainedMap')
+const ChainedMapBase = require('../src/ChainedMapBase')
+const Composed = require('../src/compose/compose')
+const addPoolingTo = require('../src/deps/cache/pooler')
+
+const copy = x => { for (let prop in x) x[prop] = x[prop] }
+
+class Vanilla {
+ constructor(parent) {
+ this.parent = parent
+ this.data = {}
+ }
+}
+
+const PreComposed = Composed()
+class Pooled extends PreComposed {}
+
+function PooledMap(p) {
+ var _this = new ChainedMapBase(p)
+ return _this
+}
+copy(PooledMap)
+addPoolingTo(PooledMap)
+
+// log.quick(PooledMap.getPooled())
+// Object.assign(PooledMap, PooledMap.prototype)
+// log.quick({PooledMap, Proto: PooledMap.prototype.prototype})
+addPoolingTo(Pooled)
+// addPoolingTo(PreComposed)
+// addPoolingTo(ChainedMap)
+
+// extends Map
+class Ramda {
+ constructor(parent) {
+ this.parent = parent
+ // super()
+ this.data = {}
+ this.className = this.constructor.name
+ }
+ [Symbol.toPrimitive]() {
+ return R.toString(this.data)
+ }
+ // https://github.com/ramda/ramda/issues/546
+ [Symbol.iterator]() {
+ return R.arrayToIterator(this.data)
+ }
+ set(key, val) {
+ this.data = R.set(R.lensProp(key), val, this.data)
+ return this
+ }
+ get(key) {
+ return R.get(R.lensProp(key), this.data)
+ }
+ end() {
+ return R.path('parent', this)
+ }
+ when() {
+ return R.when.apply(this, arguments)
+ }
+ values() {
+ return R.values(this.data)
+ }
+ keys() {
+ return R.keys(this.data)
+ }
+ length() {
+ return R.size(this.data)
+ }
+ has(key) {
+ return R.has(R.lensProp(key), this.data)
+ }
+ tap(key, fn) {
+ this.data = R.tap(R.lensProp(key), this.data, fn)
+ return this
+ }
+ remove(key) {
+ this.data = R.remove(R.lensProp(key), this.data)
+ return this
+ }
+ from(obj) {
+ this.data = R.merge(obj, this.data)
+ return this
+ }
+ merge(obj) {
+ this.data = R.merge(obj, this.data)
+ return this
+ }
+ clear() {
+ this.data = R.evolve([null], this.data)
+ return this
+ }
+ entries() {
+ return R.toPairs(this.data)
+ }
+}
+
+function benchRamda(Klass) {
+ return new Klass()
+ .set('eh', 'eh!')
+ .set('two', 2)
+ .set('bool', true)
+ .set('nill', null)
+ .entries()
+}
+
+// log.quick(benchRamda(Ramda))
+
+function benchChainPooled(Klass) {
+ const instance = Klass.getPooled()
+ .set('eh', 'eh!')
+ .set('two', 2)
+ .set('bool', true)
+ .set('nill', null)
+ const entries = instance.store.entries()
+ Klass.release(instance)
+ return entries
+}
+
+
+function benchChain(Klass) {
+ return new Klass()
+ .set('eh', 'eh!')
+ .set('two', 2)
+ .set('bool', true)
+ .set('nill', null)
+ .entries(false)
+}
+
+function benchVanilla(Klass) {
+ const vanilla = new Klass()
+ vanilla.data.eh = 'eh!'
+ vanilla.data.two = 2
+ vanilla.data.bool = true
+ vanilla.data.nill = null
+
+ return vanilla.data
+}
+
+// log.quick(benchChain(ChainedMap), benchVanilla(Vanilla))
+
+Bench.init(__dirname, 'vanilla-simple')
+ .add('chain', () => benchChain(ChainedMap))
+ .add('vanilla', () => benchVanilla(Vanilla))
+ .add('precomposed', () => benchChain(PreComposed))
+ .add('map', () => benchChain(Map))
+ .add('pooled', () => benchChainPooled(Pooled))
+ .add('pooledext', () => benchChainPooled(PooledMap))
+ .add('ramda', () => benchRamda(Ramda))
+ .run()
diff --git a/build/README.md b/build/README.md
new file mode 100644
index 0000000..d92e6c0
--- /dev/null
+++ b/build/README.md
@@ -0,0 +1,19 @@
+ https://github.com/facebook/react/tree/master/scripts/rollup
+https://github.com/ramda/ramda/blob/master/scripts/build
+
+# two options:
+1. copy same folder structure
+2. custom copy, folders do not matter
+
+## copy same
+... .copy ha
+
+## custom copy
+1. find
+2. store metadata
+3. transform -
+ if function, use that,
+ if string,
+ if relative & isFilename, resolve filename
+ else if relative
+ else if absolute, use instead
diff --git a/build/bundle.js b/build/bundle.js
index 0c58c5e..c3f0b1b 100644
--- a/build/bundle.js
+++ b/build/bundle.js
@@ -44,6 +44,9 @@ const createBundle = options => {
if (format === 'amd') {
options.moduleId = moduleName
}
+
+ bundleOptions.externals = [require.resolve('../src/deps/env/debuggable.js')]
+
log.data(bundleOptions).echo()
// log.quick(bundleOptions)
diff --git a/build/cli.js b/build/cli.js
index 8a2eb45..e0c10fd 100644
--- a/build/cli.js
+++ b/build/cli.js
@@ -16,26 +16,46 @@
// - run test
// - run cov
const {resolve, basename} = require('path')
+const jetpack = require('fs-jetpack')
const fwf = require('funwithflags')
const Script = require('script-chain')
const log = require('fliplog')
const {read, write} = require('flipfile')
-const {del} = require('./util')
+const eslint = require('eslint')
// const docdown = require('docdown')
-const {stripRollup} = require('./plugins/ast')
const find = require('chain-able-find')
+const Chainable = require('../exports')
+const {del, _res, fromTo} = require('./util')
+const {stripRollup} = require('./plugins/ast')
+
+const {linter, CLIEngine} = eslint
+const res = _res(__dirname)
+const resRoot = _res('../')
-const res = rel => resolve(__dirname, rel)
-const resRoot = rel => resolve(res('../'), rel)
+const {
+ replace, pipe, dot, traverse, uniq, includes, not, and, trim,
+} = Chainable
+
+const hasColon = includes(':')
+const hasDot = includes('.')
// https://github.com/chalk/ansi-regex/blob/master/index.js
const ansiRegex = /[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-PRZcf-nqry=><]/g
-const stripAnsi = str => str.replace(ansiRegex, '')
+const stripAnsi = replace(ansiRegex, '')
const timer = log.fliptime()
timer.start('cli')
log.registerCatch()
+// startsWith '//' || '/*'
+const stripWhitespace = replace(/(\s|\t|\n)+/g, '')
+const _isComment = x =>
+ x.startsWith('//') ||
+ x.startsWith('*') ||
+ x.startsWith('/*') ||
+ x.includes('remapped from')
+const isComment = pipe(trim, stripWhitespace, _isComment)
+
// setup args
// src: [rollup, typescript, buble, babel, browserify, copy/strip]
const argvOpts = {
@@ -48,6 +68,9 @@ const argvOpts = {
'optimize',
'diff',
'doctrine',
+ 'easyexports',
+ 'cleaneasyexports',
+ 'quick',
],
string: ['format'],
default: {
@@ -60,11 +83,24 @@ const argvOpts = {
diff: false,
production: true,
doctrine: false,
+ easyexports: false,
+ cleaneasyexports: false,
format: ['amd', 'iife', 'dev', 'es', 'cjs', 'umd'],
},
}
const argvs = fwf(process.argv.slice(2), argvOpts)
-const {production, quick, tests, cov, clean, docs, diff, doctrine} = argvs
+const {
+ production,
+ quick,
+ tests,
+ cov,
+ clean,
+ docs,
+ diff,
+ doctrine,
+ easyexports,
+ cleaneasyexports,
+} = argvs
const OPTIMIZE_JS_FILE = '../dists/umd/index.js'
const TSC_SOURCE = '../dists/dev/index.js'
@@ -151,23 +187,30 @@ const testFiles = find
.results()
const toRel = filepath => filepath.replace(root, '').replace(entry, '')
-const dot = require('../src/deps/dot')
-const traverse = require('../src/deps/traverse')
-const uniq = require('../src/deps/array/uniq')
const repoPath = 'https://github.com/fluents/chain-able/blob/master'
const repoDocPath =
'https://github.com/fluents/chain-able/blob/master/docs/docdown'
const toDocPath = filepathBasename =>
(res('../docs/docdown/') + '/' + filepathBasename).replace('.js', '.md')
-const toRepoPath = filepathBasename => repoPath + filepathBasename
const toRepoDocPath = filepathBasename => repoDocPath + filepathBasename
const toBasename = filePath => basename(filePath)
-const stripDot = filePath => filePath.replace(/[.]/gim, '')
-const escapeDot = filePath => filePath.replace(/[.]/gim, '\\.')
-const slashToDot = filePath => filePath.replace(/\//gim, '.')
const toAnchor = (label, href) => `[${basename(label)}](${href || label})`
-const stripExt = filePath => filePath.replace(/\.[a-zA-Z0-9]{0,3}/, '')
+const stripDot = replace(/[.]/gim, '')
+const escapeDot = replace(/[.]/gim, '\\.')
+const slashToDot = replace(/\//gim, '.')
+const stripExt = replace(/\.[a-zA-Z0-9]{0,3}/, '')
+
+
+// ensure there is a `/` between them, say if we just resolve a filename
+const toRepoPath = filepathBasename => {
+ if (repoPath.endsWith('/') || filepathBasename.startsWith('/')) {
+ return repoPath + filepathBasename
+ }
+ else {
+ return repoPath + '/' + filepathBasename
+ }
+}
// cli class
class CLI {
@@ -260,67 +303,9 @@ class CLI {
rollupNode(overrides = {}) {
return require('./build')(overrides)
}
- doctrine() {
+ doctrine(source) {
var doctrineAPI = require('doctrine')
- var ast = doctrineAPI.parse(
- [
- `
- /**
- * {@link https://ponyfoo.com/articles/es6-maps-in-depth pony-map}
- * {@link https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Map mozilla-map}
- * @see {@link pony-map}
- * @see {@link mozilla-map}
- *
- * @see ChainedMap
- * @see Chainable
- * @see MergeChain
- * @see MethodChain
- * @see ChainedMap
- *
- */
- `,
- // `
- // /**
- // * @param {*} x value
- // * @param {any} [y] not real, for ast
- // * @return {boolean} isDate
- // *
- // * @since 3.0.0
- // * @memberOf is
- // * @func isDate
- // *
- // * @example
- // *
- // * isDate(new Date())
- // * //=> true
- // * isDate(Date.now())
- // * //=> false
- // * isDate(1)
- // * //=> false
- // * isDate('')
- // * //=> false
- // *
- // * @example
- // *
- // * const e = {}
- // * eh[Symbol.toStringTag] = '[Object Date]'
- // * isDate(eh)
- // * //=> true
- // *
- // * @example
- // *
- // * class Eh extends Date()
- // * isDate(new Eh())
- // * //=> true
- // */
- // `,
- // '/**',
- // ' * This function comment is parsed by doctrine',
- // ' * @param {{ok:String}} userName',
- // '*/',
- ].join('\n'),
- {unwrap: true, sloppy: true}
- )
+ var ast = doctrineAPI.parse(source, {unwrap: true, sloppy: true})
log.quick(ast)
}
docs() {
@@ -403,7 +388,7 @@ class CLI {
.results()
let dirs = allDirs
- .map(dir => (dir.includes('.') ? dir.replace(basename(dir), '') : dir))
+ .map(dir => (hasDot(dir) ? dir.replace(basename(dir), '') : dir))
.filter(uniq)
const docFiles = vfs.src.rel
@@ -419,7 +404,7 @@ class CLI {
let docName = doc.replace(repoDocPath, '')
// file
- if (doc.includes('.')) {
+ if (hasDot(doc)) {
docName = stripExt(docName)
}
@@ -440,8 +425,13 @@ class CLI {
// .replace(/(\[39|2m,)/gim, '')
// .replace(/\'/gim, '')
// .replace(/\,/gim, '')
- const toCode = x => x.replace(/[├─│─┐└─]/gim, '`$&`')
+ const toCode = replace(/[├─│─┐└─]/gim, '`$&`')
const treeify = log.requirePkg('treeify')
+
+ // const testColon = test(/\:$/)
+ // pipe(trim, testColon)
+ const endsWithColon = x => (/\:$/).test(x.trim())
+
try {
const tree = treeify.asTree(docsTree, true, true)
@@ -449,7 +439,7 @@ class CLI {
.split('\n')
.map(line => '- ' + toCode(line).replace('``', '` `'))
.map(line => {
- if (line.includes(':')) {
+ if (hasColon(line)) {
return line
}
else {
@@ -468,10 +458,11 @@ class CLI {
}
})
// ends with `:`
- .map(
- line =>
- ((/\:$/).test(line.trim()) ? line.substring(0, line.length - 2) : line)
- )
+ .map(line => (
+ endsWithColon(line)
+ ? line.substring(0, line.length - 2)
+ : line
+ ))
.join('\n')
// console.log(treeString)
@@ -484,7 +475,153 @@ class CLI {
// )
}
}
+ // @TODO run versions index
+ versions() {}
+ cleanEasyExports() {
+ const {flatten} = require('../exports')
+ const {fromTo} = require('./util')
+
+ const exported = flatten(fromTo.values())
+
+ exported
+ // .map(exp => {
+ // if (isNotInOutput(exp)) throw new Error(exp)
+ // return exp
+ // })
+ .forEach(exp => {
+ log.red('deleting').data(exp).echo()
+ del(exp)
+ })
+ }
+ lintEasyExports() {
+ const temp = fromTo.folder
+ const files = jetpack
+ .list(temp)
+ // @TODO example difference currying makes
+ // .filter(filename => filename.includes('.js'))
+ .filter(includes('.js'))
+ .map(filename => res(temp + '/' + filename))
+
+ files.forEach(filename => this.lintEasyExport(filename, temp))
+ // log.quick({files})
+ }
+ // https://github.com/eslint/eslint/issues/4119 Load plugin when using eslint in node via the API
+ lintEasyExport(filename, dir) {
+ // @HACK @FIXME @TODO just is ignoring this silly copied over files
+ if (!filename.includes('build/')) return
+ if (filename.includes('index.web') ||
+ filename.includes('_exported') ||
+ filename.includes('_es6') ||
+ filename.includes('runner')
+ ) return
+
+ let config = {}
+ try {
+ const configPath = require.resolve('../../.eslintrc.js')
+ config = require(configPath)
+ }
+ catch (e) {
+ // ignore, some travis issue?
+ }
+ config.rules = {
+ 'import/no-unresolved': 2,
+ // 'node/no-missing-require': 'error',
+ }
+ config.plugins.push('import')
+ // log.quick(config)
+
+ let source = read(filename)
+ log.bold(filename).echo()
+
+ source
+ .split('\n')
+ // ensure relativeish
+ .filter(and(includes('require'), includes('/')))
+ // .filter(not(isComment))
+ .map(line => {
+ // commented out lines
+ if (isComment(line)) return line
+
+ log.red(line).echo()
+ console.log('\n\n')
+ const parts = line.split('=')
+ const name = parts.shift().trim()
+ let requirePath = parts.pop()
+ if (!requirePath) {
+ // was just a comment 0.0
+ return line
+ // log.quick({parts, name})
+ }
+
+ // comment from exporting
+ requirePath = requirePath
+ .split('/*')
+ .shift()
+
+ if (requirePath.includes('.js')) {
+ // remove .js if needed
+ requirePath = requirePath
+ .split('.js')
+ .shift()
+ }
+
+ // keeps letters, numbers, `-` & `_` & `.`
+ const sillyRegExpSpecial = /(\s|\^|\$|\#|\@|\!|\&|\=|\+|\t|\n|\?|\>|\<|\{|\}|\[|\]|\|\'|\"|\`|\\|\)|\(|\:|\;|\*|\~|\%|\,)*/gmi
+ const dotSlash = /(\.\/)/gmi
+ requirePath = requirePath
+ .replace('require(', '')
+ // .replace(/[\W_-]+/g, '')
+ .replace(sillyRegExpSpecial, '')
+ .replace(dotSlash, '')
+ .replace(/'*/gmi, '')
+
+ log.blue(requirePath).echo()
+ if (!requirePath) {
+ log.quick(line)
+ }
+
+ requirePath = dir + '/' + requirePath
+
+ // ensure all paths exist
+ try {
+ require.resolve(requirePath)
+ }
+ catch (error) {
+ log.quick({error, requirePath})
+ log.catchAndThrow(error)
+ }
+ })
+ const colored = log.colored(source, 'cyan')
+ // log.cyan('before\n').data(colored).echo() // "var foo = bar;"
+ const eslintCli = new CLIEngine({
+ // configFile: configPath,
+ config,
+ })
+
+ const executed = eslintCli.executeOnText(source)
+ const {results} = executed
+ const unresolved = results[0]
+ .messages
+ .filter(msg => msg.ruleId === 'import/no-unresolved')
+ // .map(msg => msg.message)
+
+ // log.quick(unresolved)
+ // log.quick(eslintCli)
+
+ const verifiedMessages = linter.verify(source, config, {filename})
+ const code = linter.getSourceCode()
+
+ // ignoring, linting manually
+ // log.yellow('messages').data(verifiedMessages).echo()
+ // if (!code || !code.text) {
+ // log.red('could not handle this file ').data({filename}).echo()
+ // return source
+ // }
+ // log.yellow('code').fmtobj(code).echo()
+ // log.blue(code.text).echo() // "var foo = bar;"
+ // return code.text
+ }
buble() {
const sourcemaps = true
const scripts = new Script()
@@ -578,16 +715,16 @@ async function publishing() {
const rollupProdWith = opts => cli.rollupNode(prodWith(opts))
const rollupDevWith = opts => cli.rollupNode(devWith(opts))
- const prodBuilds = [
+ let prodBuilds = [
{format: 'amd', falafel: false},
- {format: 'iife', falafel: false},
{format: 'es'},
{format: 'cjs'},
+ {format: 'iife', falafel: false},
// @HACK @FIXME just needs sourceType script
{format: 'umd', verbose: true, debug: false},
]
- const devBuilds = [
+ let devBuilds = [
{
exportName: 'debugger',
debugger: true,
@@ -606,8 +743,16 @@ async function publishing() {
},
]
+ // @NOTE quick, just build one
+ if (quick) {
+ log.bold('quick').echo()
+ prodBuilds = prodBuilds.slice(prodBuilds.length - 2)
+ devBuilds = []
+ }
+
let devOps = devBuilds.map(dev => rollupDevWith(dev))
let prodOps = prodBuilds.map(prod => rollupProdWith(prod))
+
let builds = [].concat(devOps).concat(prodOps)
const built = await Promise.all(builds)
@@ -617,6 +762,14 @@ async function publishing() {
async function all() {
timer.start('cli')
+ if (cleaneasyexports) {
+ await cli.cleanEasyExports()
+ process.exit()
+ }
+ if (easyexports) {
+ await cli.lintEasyExports()
+ process.exit()
+ }
if (docs) {
await cli.docs()
process.exit()
diff --git a/build/easy-npm-files.js b/build/easy-npm-files.js
new file mode 100644
index 0000000..d33e109
--- /dev/null
+++ b/build/easy-npm-files.js
@@ -0,0 +1,874 @@
+// const ffs = require('../_modules/fluent-fs')
+const log = require('fliplog')
+const jetpack = require('fs-jetpack')
+const ConfigStore = require('configstore')
+const find = require('chain-able-find')
+const {read, write, exists} = require('flipfile')
+const {
+ curry,
+ not,
+ includes,
+ includesCount,
+ replace,
+ first,
+ isMatch,
+ isString,
+ isTrue,
+ isFunction,
+ isArray,
+ isEmpty,
+ remove,
+ reverse,
+ pipe,
+ toMatcher,
+ construct,
+ invoke,
+ hasOwnProperty,
+ toArr,
+ escapeDot,
+ includesAny,
+ includesAll,
+ all,
+ and,
+ firstToUpperCase,
+ trim,
+ uniq,
+ toString,
+ always,
+} = require('../exports')
+const {
+ forEach,
+ wrapForEach,
+ replaceLast,
+ isNegative,
+ // find
+ findIndexAt,
+ findMatching,
+ findKey,
+ findValue,
+ findValues,
+ findFirstMatch,
+ // remap
+ remapKeys,
+ remapValues,
+ remapToMatch,
+} = require('./util/__fixme')
+const {
+ getFolderName,
+ getFileName,
+ getFolderAndFileName,
+} = require('./util/_filefolder')
+const {_res, del, fromTo, isDir} = require('./util')
+
+const camelCase = str =>
+ str
+ // spaces with underscore
+ .replace(/\s+/g, '-')
+ // < underscores & dashes until whitespace or end
+ // > .toUpperCase x & '_'
+ .replace(/[.-](\w|$)/g, (m, x) => x.toUpperCase())
+
+const has = x => includes('_', x)
+
+// includesAny('_', ['/', 'require'])
+// const hasRequire = and(includes('/'), includes('require'))
+// const hasRequire = and(includes('/'), includes('require'))
+const hasRequire = and(has('/'), has('require'))
+
+const entry = process.cwd()
+const cwd = process.cwd()
+const cwdRes = _res(cwd)
+const res = _res(__dirname)
+
+// @HACK @TODO just emulating
+// const resRoot = _res(res('./FAKEROOT'))
+const resRoot = _res(fromTo.folder)
+const outputPath = resRoot('.')
+
+// @TODO pipe?
+const src = cwdRes('./src')
+
+const isRel = has('./')
+const isAbs = has('/Users')
+const isSrc = has('/src/')
+const isTooDeep = x => x.replace(outputPath, '').split('/').length >= 2
+
+const toRoot = x => {
+ // @TODO relative-to
+ if (isSrc(x)) return resRoot('./' + x.split('/src/').pop())
+ else if (isTooDeep(x)) return resRoot('./' + x.split('/').pop())
+ else if (isAbs(x)) return x
+ else if (isRel(x)) return resRoot(x)
+ else return resRoot('./' + x)
+}
+
+// only copying .js ['!*package.json', '!*.DS_Store']
+const isNotIndex = x =>
+ !x.includes('runner') && (!x.includes('index') || x.includes('indexable'))
+// not(has('index.js'))
+const isIzzez = has('/deps/is/')
+
+const remapKeysToArr = remapKeys(toArr)
+const remapValuesToArr = remapValues(toArr)
+
+// when we have files with the same name, .onConflict, log?
+const found = find
+ .init()
+ .recursive(true)
+ .ignoreDirs(['ignant', 'node_modules'])
+ .abs(true)
+ .sync(true)
+ // all folders have a filename with the same name as the folder
+ // if they did not, we could also rename all index.js files
+ // , '!*index.js'
+ .matchFiles(['**/*.js'])
+ .find(src)
+ .results()
+ .filter(isNotIndex)
+ .filter(file => !read(file).trim().startsWith('/** @ignore 🚧 '))
+
+const filesMeta = {}
+const filesObj = {}
+
+const ENV_DEBUG = false
+
+if (!ENV_DEBUG) log.filter(always(false))
+
+// const founds = wrapForEach(found)
+const hasDupeFileName = abs => {
+ // prop, pipe, lense?
+ const rel = filesObj[abs]
+ const rels = Object.values(filesObj)
+
+ const count = includesCount(rels, toString(rel))
+ log.title('has dupe file name?').data({rel, abs, count}).echo()
+
+ if (count >= 2) {
+ // log.data(count, abs)
+ }
+ return count >= 2
+}
+
+const transformFolderAndFileCamel = (abs, folder, filename) => {
+ const folderFile = folder + '/' + filename
+ const transformed = camelCase(folder + '-' + filename) + '.js'
+ return replace(folderFile, transformed, abs)
+}
+const prefixFileNameCamel = (abs, prefix) => {
+ const fileName = getFileName(abs)
+ const folderName = getFolderName(abs)
+ const folderFile = folderName + '/' + fileName
+ const transformed =
+ folderName + '/' + camelCase(prefix + '-' + fileName) + '.js'
+ return replace(folderFile, transformed, abs)
+}
+
+// @TODO either replaceLast, or toRel then replace
+const transformIzzes = (abs, folder, filename) => {
+ // @HACK @FIXME @TODO
+ // if (filename.includes('toS')) return abs
+
+ const fileName = getFileName(abs)
+ const transformedFileName = camelCase('is-' + fileName)
+ // @TODO: replaceLast (could .reverse.replace.reverse)
+ let transformedAbs = replaceLast(fileName, transformedFileName, abs)
+ return transformedAbs
+}
+
+// (x.includes('/deps/') ? x.split('/deps/').pop() : x.split('/src/').pop())
+// pipe(replace('/src/', '/'), replace('/deps/', '/'))
+const transformToFileName = x => (x ? x.split('/').pop() : x)
+
+const transformSymbol = (abs, folder, fileName) => {
+ const beginning = abs.split(`/${folder}/`).shift()
+ return beginning + '/Symbol.' + firstToUpperCase(fileName) + '.js'
+}
+const ignore = () => false
+const docBlocks = includesCount('_', '/**')
+// remove /*, //, *, spaces
+const stripCommentsWhitespace = /(\*|\s|\t|\n|\/)*/gim
+
+// @TODO !!! support returning []
+const transformToAlias = (abs, folder, fileName) => {
+ let contents = read(abs)
+
+ const docBlocksCount = docBlocks(contents)
+
+ // only keep files that have ONE docblock since we are aliasing a whole file
+ if (docBlocksCount > 1 || docBlocksCount <= 0) {
+ return abs
+ }
+
+ // log.quick(docBlocks(contents), contents)
+
+ let aliases = []
+
+ aliases = contents
+ .split('\n')
+ .filter(line => line.includes('@alias'))
+ .map(line => {
+ log.green(line).echo()
+
+ return line
+ .trim()
+ .replace('@alias', '')
+ .replace(stripCommentsWhitespace, '')
+ })
+
+ // map each alias to a new filename
+ if (aliases.length) {
+ if (!folder) folder = getFolderName(abs)
+ const aliased = aliases.map(alias => {
+ let beginning = abs.split(`/${folder}/`).shift()
+ log.data({beginning, folder}).echo()
+ return beginning + '/' + alias + '.js'
+ })
+ log.blue('aliased').data(aliased).echo()
+ return aliased
+ }
+
+ return abs
+}
+
+// @TODO transform `compose/` to `nameChain`
+// + root ones `Chain` if they don't already have it
+// @TODO !!!!!!!!!!!!!!!!!!! TRANSFORM, THIS-AS-A-CHAIN
+// key to matcher
+const map = {
+ // 'eh': 'eh',
+ 'index.web': ignore,
+ '/conditional/all': 'all',
+ '/cast/*.js': transformFolderAndFileCamel,
+ '/deps/is/*.js': transformIzzes,
+ '/flipped/*.js': transformFolderAndFileCamel,
+ '/native/*.js': transformFolderAndFileCamel,
+ // '/symbols/*.js': transformSymbol,
+ '*': transformToFileName,
+ // '**': transformToAlias,
+}
+
+// ignore original
+const mapOnlyRename = {
+ 'native/hasOwnProperty.js': true,
+}
+
+// const firstIsFunction = pipe(first, isFunction)
+const firstIsFunction = x => isFunction(x[0])
+
+// includesAny
+// (['.', '-', '_']).map(has)
+const isNotCamelCase = x =>
+ x.includes('.') || x.includes('-') || x.includes('_')
+
+const doubleExtHACK = has('.js.js')
+const doubleSlashToSingle = replace(/\/{2}/, '/')
+
+let allFound = found.concat(fromTo.keys()).filter(uniq)
+allFound.forEach(abs => (filesObj[abs] = getFileName(abs)))
+filesMeta.files = filesObj
+
+// isLast, isFirst ? kind of is .before .after if it's only flat...
+let remapped = allFound.map(abs => {
+ if (!isString(abs)) {
+ log.red('NOT_STRING').data({abs}).echo()
+ return abs
+ }
+
+ // start remap
+ fromTo.data[abs] = fromTo.data[abs] || [abs]
+ let remappedAbs = fromTo.data[abs]
+
+ // const alreadyHas = includes(remappedAbs)
+ const add = x => {
+ toArr(x).forEach(value => {
+ let rootValue = toRoot(value)
+
+ if (!rootValue.endsWith('.js')) {
+ rootValue += '.js'
+ }
+ if (rootValue.endsWith('.js.js')) {
+ rootValue = rootValue.replace('.js.js', '.js')
+ }
+ if (remappedAbs.includes(rootValue)) {
+ log.red('already has').data({rootValue}).echo(false)
+ return
+ }
+
+ // remappedAbs.push(value)
+ remappedAbs.push(rootValue)
+ })
+ remappedAbs.forEach((value, index) => {
+ remappedAbs[index] = toRoot(value)
+ if (doubleExtHACK(remappedAbs[index])) {
+ remappedAbs[index] = remappedAbs[index].split('.js').shift() + '.js'
+ }
+ })
+
+ // if (isNotCamelCase(x)) add(camelCase(escapeDot(x)))
+ }
+
+ // @NOTE
+ const aliased = transformToAlias(abs)
+ toArr(aliased).forEach(alias => add(alias))
+
+ // find if we need to remap and how we will do so
+ const matchFound = findMatching(map, abs)
+ const ignoreOriginal = findMatching(mapOnlyRename, abs)
+
+ // @TODO @HACK @FIXME --- EXAMPLE NATIVE/HASOWNPROPERTY UGH
+ if (ignoreOriginal) {
+ // log.quick({abs, ignoreOriginal})
+ }
+
+ if (matchFound) {
+ let [key, value, keys] = matchFound
+
+ log.text('found matching').data({abs, key, value, keys}).echo(false)
+
+ let [folderName, fileName] = getFolderAndFileName(abs)
+
+ if (isArray(value) && !isEmpty(value)) {
+ if (value.length > 1) {
+ value = value.map(x => (isString(x) ? replace(key, value) : x))
+
+ // @TODO was pipe, need best name
+ // what's the name for this? reducing with each value updating?
+ let transformed = abs
+ value.forEach(val => {
+ [folderName, fileName] = getFolderAndFileName(abs)
+
+ // @NOTE `OR` transformed
+ transformed = val(transformed, folderName, fileName) || transformed
+ })
+
+ // ignore files that return falsy
+ if (transformed) {
+ add(transformed)
+ }
+ }
+ else if (firstIsFunction(value)) {
+ const transformed = value[0](abs, folderName, fileName)
+ add(transformed)
+ }
+ else {
+ log.red('first is not a function').data({value: value[0]}).echo()
+ }
+ }
+ else {
+ // if (!ignoreOriginal)
+ const transformed = replace(key, value, abs)
+ add(transformed)
+ }
+
+ // @NOTE
+ // if (ignoreOriginal) {
+ // return remappedAbs
+ // }
+ }
+ else if (isIzzez(abs)) {
+ const transformed = transformIzzes(abs)
+ add(transformed)
+ }
+ else if (hasDupeFileName(abs)) {
+ // @TODO default the one to use
+ const folderName = getFolderName(abs)
+ const fileName = getFileName(abs)
+ const folder_file = folderName + '-' + fileName
+ const folderWithSlashes = '/' + folderName + '/'
+ const beforeFolder = abs.split(folderWithSlashes).shift()
+ let transformed = beforeFolder + camelCase(folder_file)
+
+ add(transformed)
+ }
+ else {
+ // if (!ignoreOriginal)
+ add(abs)
+ }
+
+ // @NOTE
+ // if (ignoreOriginal) {
+ // return remappedAbs
+ // }
+
+ const fileName = getFileName(abs)
+
+ // @TODO all snake & all camel
+ if (isNotCamelCase(fileName)) {
+ const beginning = abs.split(`/${fileName}`).shift()
+ let transformed = beginning + '/' + camelCase(fileName) + '.js'
+ // let transformed = replace(fileName, camelCase(fileName), abs)
+ // log.data({transformed, camel: camelCase(fileName), fileName, abs}).echo()
+ add(transformed)
+ }
+
+ // @TODO this should check if we resolve the conflict
+ // right now I will default it to first-come-first-serve (else)
+ if (!hasDupeFileName(abs)) {
+ // add(abs) <- keeps nested folders which is meh
+ add(transformToFileName(abs))
+
+ const [folderName] = getFolderAndFileName(abs)
+ const [alpha, omega] = abs.split(folderName)
+ let transformed = alpha + omega
+ // replace doubleslash with 1
+ transformed = doubleSlashToSingle(transformed)
+ log.data({transformed}).echo()
+ if (transformed.endsWith('/')) return remappedAbs
+ // @TODO on getter, echo, pre easy log._
+ add(transformed)
+ }
+ else {
+ log.red('has dupe').data(abs).echo()
+ // already only is added if it has not been added before
+ add(abs)
+ }
+
+ add(abs)
+
+ return remappedAbs
+ // return abs
+})
+
+fromTo.del().write()
+
+const sillyRegExpSpecial = /(\s|\^|\$|\#|\@|\!|\&|\=|\+|\t|\n|\?|\>|\<|\{|\}|\[|\]|\|\'|\"|\`|\\|\)|\(|\:|\;|\*|\~|\%|\,)*/gim
+const dotSlash = /(\.\/)/gim
+const matchRequireString = requirePath =>
+ (requirePath = requirePath
+ .replace('require(', '')
+ // .replace(/[\W_-]+/g, '')
+ .replace(sillyRegExpSpecial, '')
+ // .replace(dotSlash, '')
+ .replace(/'*/gim, ''))
+
+const isAllCapital = x =>
+ (x
+ ? x
+ .split('')
+ .map(char => {
+ // it is a letter
+ if (/[A-Z]/i.test(char)) {
+ // is it uppercase
+ return (/[A-Z]/).test(char)
+ }
+ })
+ .every(isTrue)
+ : false)
+
+const onlyLetters = x =>
+ x
+ .split('')
+ .filter(match => {
+ if (/[a-zA-Z_-]/i.test(match)) return match
+ else return false
+ })
+ .join('')
+
+// remove all initial dots, and the first slash
+const sanitizeRequire = x => x.replace(/[.]/g, '').replace('/', '')
+const stripWhitespace = replace(/(\s|\t|\n)+/g, '')
+const _isComment = x =>
+ x.startsWith('//') || x.startsWith('*') || x.startsWith('/*')
+const isComment = pipe(trim, stripWhitespace, _isComment)
+function _descend(fn, a, b) {
+ var aa = fn(a)
+ var bb = fn(b)
+ // @NOTE DESCENDING
+ return aa > bb ? -1 : aa < bb ? 1 : 0
+ // return aa < bb ? -1 : aa > bb ? 1 : 0
+}
+const descend = curry(3, _descend)
+
+// @TODO
+// abstract this,
+// should pull in either/and ast parsing for requires
+// depflip
+const remapRequire = (contents, abs) =>
+ contents
+ .split('\n')
+ .map(line => {
+ if (!(line.includes('/') && line.includes('require'))) return line
+ // if (!hasRequire(line)) return line
+ if (isComment(line)) return line
+
+ const parts = line.split('=')
+ const name = parts.shift().trim()
+
+ const requireReplacer = (match, p1, offset, string) => {
+ const ogMatch = match
+ const matchIsDir = isDir(ogMatch)
+ let matchName = match
+
+ match = sanitizeRequire(match)
+
+ // dir... @example deps/util/util.js
+ // log.color('white.underline').text('matchIsDir').data(matchIsDir).echo()
+ // then use a more specific namespace
+ if (matchIsDir) {
+ if (match.includes('/')) matchName = match.split('/').pop()
+
+ match = match + '/' + matchName + '.js'
+ }
+ if (matchIsDir) {
+ // log.data(ogMatch).echo()
+ // console.log('\n\n\n\n')
+ // log.data(fromTo.keys()).echo()
+ // log.data({match}).echo()
+ }
+
+ const findFrom = () => {
+ return fromTo.keys().filter(x => {
+ const matches =
+ isMatch(match, x) ||
+ isMatch(x, match) ||
+ x.includes(match) ||
+ match.includes(x)
+
+ if (matches) {
+ // log.data({match, x}).echo()
+ }
+ // don't want to require itself, if it is the longest
+ return matches && getFileName(abs) !== getFileName(x)
+ })
+ }
+
+ let requiresFound = []
+ // let requiresFound = findFrom()
+
+ // we know it is a dir, and we could not find it
+ if (matchIsDir && (requiresFound || requiresFound.length === 0)) {
+ const sanitizedMatchName = sanitizeRequire(matchName)
+ requiresFound = [sanitizedMatchName]
+
+ // const resolvedMatchName = resRoot(matchName)
+ // log
+ // .data({requiresFound, matchName, resolvedMatchName, sanitizedMatchName})
+ // .echo()
+
+ return sanitizedMatchName + '.js'
+ }
+
+ const requireFound = requiresFound ? requiresFound[0] : requiresFound
+
+ const descending = descend(x => x.length)
+ let requireValues = fromTo.data[requireFound] || []
+
+ let hasIs = false
+ requiresFound.forEach(val => {
+ if (val.includes('is/') || val.startsWith('is')) {
+ hasIs = true
+ }
+ })
+ if (hasIs) {
+ requireValues = requireValues.sort(descending)
+ }
+
+ let requireValue = requireValues ? requireValues.shift() : requireValues
+
+ // if one is all caps and one is not, that is not correct
+ const isRequireCaps = isAllCapital(requireValue)
+ const isMatchCaps = isAllCapital(match)
+ // if (isRequireCaps && !isMatchCaps) {
+ // requireValue = requireValues.shift() || requireValue
+ // }
+ // else if (isMatchCaps && !isRequireCaps) {
+ // requireValue = requireValues.shift() || requireValue
+ // }
+
+ // we don't want to fuzzy it up with `is`
+ // if (!hasIs) {
+ // const FuzzySet = require('./fuzzyset')
+ // const fuzzies = FuzzySet()
+ // requireValues.forEach(val => fuzzies.add(val))
+ // const fuzzyFind = fuzzies.get(match, requireValue) || requireValue
+ // // finding returns [score, find]
+ // requireValue = isArray(fuzzyFind) ? fuzzyFind.pop() : fuzzyFind
+ //
+ // // log
+ // // .bold('FUZZY_FIND')
+ // // .data(fuzzyFind)
+ // // .echo()
+ // }
+
+ // log
+ // .bold('REQUIRES_FOUND')
+ // .data({requiresFound, requireValues})
+ // .echo()
+
+ return requireValue
+ }
+
+ if (parts.length === 0) return line
+
+ const ogRequire = parts.pop().trim()
+
+ // @TODO right here can use a new name matching the parts, bingo bango bongo
+ const remappedRequires = ogRequire
+ .replace(`require('`, '')
+ .replace(')', '')
+ .replace(`'`, '')
+ .replace(/.*/, requireReplacer)
+ .split('/')
+
+ let strippedRequires = onlyLetters(ogRequire)
+ let remappedRequire = remappedRequires.pop() || getFileName(ogRequire)
+
+ // remappedRequires
+ // log
+ // .bold('require_matches')
+ // .data(({remappedRequire, ogRequire}))
+ // .echo()
+
+ if (/^undefined$/.test(remappedRequire)) {
+ let ogRemappedRequire = remappedRequire
+ remappedRequire = name
+ if (remappedRequire.includes(' '))
+ remappedRequire = name.split(' ').pop()
+ let fileNameWord = onlyLetters(getFileName(ogRequire))
+
+ // if they are named very differently
+ if (!name.includes(fileNameWord)) remappedRequire = fileNameWord
+
+ if (ogRequire.includes('is/')) {
+ if (!remappedRequire.includes('is')) {
+ remappedRequire = camelCase(`is-${remappedRequire}`)
+ }
+ }
+ }
+
+ const str = matchRequireString(ogRequire)
+
+ const absFileName = getFileName(abs)
+ const beforeFolder = abs.split(absFileName + '.js').shift()
+ let resolvedish = require('path').resolve(beforeFolder, str)
+ log
+ .data({
+ resolvedish,
+ str,
+ absFileName,
+ abs,
+ beforeFolder,
+ })
+ .echo()
+
+ let resolved = resolvedish
+ try {
+ resolved = require.resolve(resolvedish)
+ }
+ catch (error) {
+ console.log({error})
+ }
+
+ // log.data({resolved}).echo()
+
+ if (isEmpty(fromTo.data[resolved])) parseFromTo(resolved, true)
+
+ let resolveds =
+ fromTo.data[resolved] ||
+ fromTo.data[resolved + '.js'] ||
+ fromTo.data[resolvedish] ||
+ fromTo.data[resolvedish + '.js'] ||
+ []
+ // log.quick(fromTo.data)
+
+ // log.data({fromTo, resolveds}).echo()
+ // [resolveds.length - 1]
+ let reResolved = resolveds.slice(0).pop()
+ let finalFull = reResolved || remappedRequire
+ let finals = getFileName(finalFull) + '.js'
+ // log.data({finals, reResolved}).echo()
+ const sanitizedOgRequire = matchRequireString(ogRequire)
+ const comment = `/* remapped from ${sanitizedOgRequire} */`
+ return `${comment}\n${name} = require('./${finals}')`
+ })
+ .join('\n')
+
+// fromTo.keys().forEach(key => {
+// log.underline(key).data(fromTo.data[key]).echo()
+// })
+// process.exit()
+
+const fileMeta = {}
+filesMeta.file = fileMeta
+
+// key is abs
+function parseFromTo(key, onlyParse = false) {
+ const fileNames = fromTo.data[key] || []
+
+ const hash = fileNames.join('__') + key
+ fileMeta[hash] = {hash, fileNames, key}
+
+ let contents = read(key)
+ contents = `/* FROM-TO: ${key.split('/chain-able/').pop()} */\n${contents}`
+ contents = remapRequire(contents, key)
+ fileMeta[hash].contents = contents
+
+ if (onlyParse) return null
+
+ log.bold(key).data(fileNames).echo()
+
+ fileNames.forEach(fileName => {
+ if (fileName.includes('/src/')) {
+ const bad = new Error(fileName)
+ log.red('bad filename').data(bad).echo()
+ return
+ }
+
+ if (!fileName.endsWith('.js')) fileName += '.js'
+
+ // log.bold(fileName).echo()
+ // log.green(contents).echo()
+ // log.underline('__________ \n').echo()
+
+ if (exists(fileName)) {
+ log.red('already_exists').data(fileName).echo(false)
+ return
+ }
+
+ // log.italic('writing__ ' + fileName).echo()
+ // log.data({[fileName]: contents}).echo()
+ write(fileName, contents)
+ })
+}
+
+// @TODO file-chain better here
+const writeAll = () => {
+ fromTo.keys().forEach(abs => parseFromTo(abs))
+}
+
+writeAll()
+// writeAll()
+
+filesMeta.remapped = remapped
+
+remapped.forEach(remap => {
+ // log.data({remap}).echo()
+})
+
+// process.exit()
+Object.values(fileMeta).forEach(meta => {
+ let {hash, fileNames, key, contents} = meta
+
+ if (fileNames.length === 0) {
+ fileNames.push(toRoot(key))
+ }
+
+ // log.bold('hash__ ' + hash).data({fileNames}).echo()
+ fileNames.forEach(fileName => {
+ // log.italic('writing__ ' + fileName).echo()
+ if (exists(fileName)) log.red('already_exists').data(fileName).echo(false)
+ else write(fileName, contents)
+ })
+})
+
+// const replaceContentWeak = content => {
+// // ../ or ../ehoh/anythin
+// // not ../../
+// // /(\'\.\.\/)(?=[A-Z]*?)(?!\.)/
+//
+// // easier to just replace first one per line
+// return content
+// .split('\n')
+// // .map(line => line.replace('../', '../../'))
+// .map(line => line.trim().replace(/require\(\'.*\'\)$/gmi), (match, p1, offset, string) => {
+// log.quick({match, p1, offset, string})
+// })
+// .join('\n')
+// }
+const fromToComeOn = read.json(fromTo.path)
+Object.keys(fromToComeOn).forEach(abs => {
+ fromToComeOn[abs].forEach(comeOnOut => {
+ if (!exists(comeOnOut)) {
+ const content = read(abs)
+ // write(comeOnOut, remapRequire(content, comeOnOut))
+ write(comeOnOut, remapRequire(content, abs))
+ }
+ })
+
+ if (abs.includes('is/')) {
+ fromToComeOn[abs].forEach(comeOnOut => {
+ if (comeOnOut.includes('not')) return
+ if (!comeOnOut.includes('is')) return
+
+ const fileName = getFileName(comeOnOut)
+ let prefixed = prefixFileNameCamel(comeOnOut, 'not')
+ prefixed = prefixed.replace('notIs', 'isNot')
+ fromToComeOn[abs].push(prefixed)
+ const saferFileName = fileName.replace(/notIs|isNot/, 'is')
+
+ let content = `const not = require('./not.js')\n`
+ content += `const ${fileName} = require('./${saferFileName}.js')\n`
+ content += `module.exports = not(${fileName})`
+ // log.data({prefixed, content, fileName, abs}).echo()
+ write(prefixed, content)
+ })
+ }
+})
+
+fromTo.write()
+// log.prettyformat(fileMeta).echo()
+const stripExtJS = replace(/\.js$/gim, '')
+
+const hackRequire = `
+ const _require = (str) => {
+ try {
+ require.resolve(str)
+ return require(str)
+ }
+ catch (error) {
+ // console.log({error})
+ return error
+ }
+ }
+`
+let es6 = `${hackRequire}`
+let exported = `
+${hackRequire}
+const exported = {}
+module.exports = exported
+`
+const concatUniq = curry(2, (str, toAdd) => {
+ if (str.includes(toAdd)) return str
+ else str += toAdd
+})
+const _makeRequire = x => `exported['${x}'] = _require('./${x}')\n`
+const _makeExportsRequire = x => `exports.${x} = _require('./${x}')\n`
+
+const makeRequire = pipe(stripExtJS, _makeRequire)
+const makeExportsRequire = pipe(stripExtJS, _makeExportsRequire)
+
+// replace('.js', '')
+// not(has('-'))
+let flatFileNames = jetpack
+ .list(outputPath)
+ .map(stripExtJS)
+ .filter(
+ name =>
+ !isEmpty(name) &&
+ !name.includes('-') &&
+ !name.includes('_exports') &&
+ !name.includes('_es6')
+ )
+
+// flatFileNames.forEach(name => log.bold(name).echo())
+
+log.data({flatFileNames}).echo()
+const es6Add = x => (es6 = concatUniq(es6))
+const exportedAdd = x => (exported = concatUniq(es6))
+
+flatFileNames.forEach(name => {
+ exported += makeRequire(name)
+ es6 += makeExportsRequire(name)
+})
+
+exported = trim(exported)
+es6 = trim(es6)
+
+log.white(exported).echo()
+log.blue(es6).echo()
+
+const es6Path = resRoot('_es6.js')
+const exportedPath = resRoot('_exported.js')
+
+write(es6Path, es6)
+write(exportedPath, exported)
diff --git a/build/examples-test-runner.js b/build/examples-test-runner.js
new file mode 100644
index 0000000..8c8a0b2
--- /dev/null
+++ b/build/examples-test-runner.js
@@ -0,0 +1,332 @@
+/** @ignore 🚧 */
+
+// --- deps ---
+const fs = require('fs')
+const log = require('fliplog')
+const dox = require('doctrine')
+const Chainable = require('../exports')
+
+// --- check exported ---
+//
+// const exported = require('./build/FAKEROOT/_exported')
+//
+// const {filterMap} = exported
+// const izKeys = Object.keys(exported).filter(key => key.startsWith('is'))
+// const filterIzKeys = (value, key) => izKeys.includes(key)
+// const isses = filterMap(exported, filterIzKeys, value => value)
+// require('fliplog').prettyformat(isses).echo()
+//
+// log.quick(exported)
+// log.quick(Object.keys(exported))
+// log.quick({exported})
+
+
+// --- expand out ---
+
+const {Chain} = Chainable
+const {toFunction} = Chainable
+const {isEmpty, isFunction} = Chainable
+const {not, match, define} = Chainable
+const {trim, pipe, includes, replace, curry, bind} = Chainable
+
+// @TODO use `not` from `exports`
+const isNotEmpty = not(isEmpty)
+const isTruthy = x => x
+const parse = source => dox.parse(source, {
+ lineNumbers: true,
+ recoverable: true,
+ sloppy: true,
+ unwrap: true,
+})
+
+// --- todos ---
+
+// @TODO docblocks can handle it, but names are a little mangled so
+// const devSource = String(fs.readFileSync('./dists/dev/index.js'))
+// @TODO use this for each individual tests & run them safely
+// class ExampleTest extends Chain {}
+// @TODO so now, we have our stuff,
+// but if we export this way,
+// `module.exports = x =>`
+// it will not be the same...
+// a.
+// 1. check for @name
+// 2. check module.exports
+// 3. check `function name(`
+// b.
+// require the file (read & new Function)
+// assign variable name,
+// use `var name = `
+// & `new function`
+// c.
+// 1. with our exports now all named and build,
+// 2. just get fn name
+// 3. use it on the object imported from generated exports
+
+
+// --- utils ---
+
+const stripNewLines = replace(/(\r|\n)+/g, '')
+const stripWhitespace = replace(/(\s)+/g, '')
+const stripEmpty = pipe(stripNewLines, stripWhitespace)
+const _isComment = x =>
+ x.startsWith('//') ||
+ x.startsWith('*') ||
+ x.startsWith('/*')
+const isComment = pipe(trim, stripWhitespace, _isComment)
+const isClosing = x => x.includes('*/')
+const stripExt = replace(/\.[a-zA-Z0-9]{0,3}/, '')
+const isExpectation = includes('//=>')
+const matchComments = /(\/\*.*?\*\/)|(\/\/?.*?$)/gmi
+// @TODO regexp chain here
+// `/*`...`*/` | `//` | `/`
+const _stripComments = x => {
+ if (isExpectation(x)) return x
+ else return x.replace(matchComments, '')
+}
+const stripComments = pipe(trim, _stripComments)
+// @TODO handle examples that have multi asserts and know which one is which...
+const splitExpectation = line => {
+ if (isExpectation(line)) return line.split('//=>').reverse()
+ else return [null, line]
+}
+const getDocBlocksFrom = match(/\/\*\*(?![-!])[\s\S]*?\*\/\s*.+/g)
+
+// better to use ast
+// const matchFnName = x => {
+// (/^function (\w+)/)
+// (/^module\.exports\s\=/)
+// }
+
+// ---- important part ---
+
+const parseExample = example => {
+ // previous
+ let lineGivingExpectation = null
+
+ // we hit the end, like fliplog error stack parsing
+ let hitEnd = false
+
+ // split, transform, filter, extract our expectations
+ example = example.description
+ .split('\n')
+ .map(stripComments)
+ .map(stripNewLines)
+ .filter(isNotEmpty)
+ .map(_line => {
+ if (hitEnd || isClosing(_line)) {
+ hitEnd = true
+ return false
+ }
+
+ let line = stripComments(_line)
+ let [expectation, rest] = splitExpectation(line)
+
+ if (expectation) expectation = trim(expectation)
+ if (rest) rest = trim(rest)
+
+ if (expectation && rest) {
+ // return `expect(${rest}).toEqual(${expectation})`
+ return [rest, expectation]
+ }
+ else if (expectation && lineGivingExpectation) {
+ // return `expect(${lineGivingExpectation}).toEqual(${expectation})`
+ return [lineGivingExpectation, expectation]
+ }
+ else {
+ lineGivingExpectation = line
+ if (line.includes('= ')) return line
+ else return false
+ }
+ })
+ .filter(isTruthy)
+
+ // last is not example
+ example.pop()
+
+ // require('fliplog').quick(example)
+ return example
+}
+const mapExamples = examples => examples.map(parseExample)
+
+// @TODO take source in, inject @name
+const evolveDocblocks = (docblocks, source) => {
+ return docblocks
+ .join('\n')
+ .split('\n')
+ .filter(line => !line.includes('@link'))
+ .join('\n')
+}
+
+// --- ast ---
+
+const babel = require('babel-core')
+const acorn = require('acorn')
+const _falafel = require('falafel')
+
+const falafel = curry(3, _falafel)
+
+/**
+ * @icon 🌲⛓
+ */
+class AbstractSyntaxTreeChain extends Chain {
+ constructor(parent) {
+ super(parent)
+
+ this.getterOnSet = () => {
+ const set = bind(this.set, this)
+ this.set = (key, value) => {
+ if (!isFunction(this[key])) define(this, key, {value})
+ return set(key, value)
+ }
+ }
+ this.getterOnSet()
+
+ this
+ .methods(['code', 'source', 'parser'])
+ .getSet()
+ .build()
+ .parser(babel)
+ .source(parent)
+ }
+ parse() {
+ const string = this.getSource()
+ const config = {}
+ // const {parser} = this
+ const parser = babel
+ parser.parse = parser.transform
+
+ // result = babel.transform(string, {allowReturnOutsideFunction: true})
+ const parsedAst = acorn.parse(string, {allowReturnOutsideFunction: true})
+ const {code, map, ast} = babel.transformFromAst(parsedAst, string, config)
+
+ return this.from({code, map, ast})
+ }
+ walk() {
+ const code = this.get('code') || this.get('source')
+
+ const parser = acorn
+ const opts = {parser, sourceType: 'module'}
+ const traverseAst = falafel(code, opts)
+
+ let parent = {}
+ const forEach = node => {
+ let source = node.source()
+
+ // DeclareFunction
+ if (node.type === 'FunctionDeclaration') {
+ log.green('FunctionDeclaration').data(source).echo()
+ }
+ else if (node.type === 'FunctionExpression') {
+ log.blue('FunctionExpression').data(source).echo()
+ }
+ else if (node.type === 'ArrowFunctionExpression') {
+ log.blue('FunctionExpression').data(source).echo()
+ }
+
+ else if (node.type === 'Literal') {
+ // log.green('literal').data(source).echo()
+ }
+
+ else if (node.type === 'IfStatement') {
+ // log.blue('IfStatement').echo()
+ }
+
+ log.yellow(node.type).data(source).echo()
+
+ parent = node
+ }
+
+ let output = traverseAst(forEach)
+ // log.quick({output})
+ return output
+ }
+}
+
+const ASTChain = toFunction(AbstractSyntaxTreeChain)
+
+// --- examples ---
+
+// and this one is a collection
+class ExamplesTest extends Chain {
+ constructor(code) {
+ super()
+
+ const setExamples = ast => {
+ if (this.has('examples')) return
+ let examples = ast.dox.tags.filter(tag => tag.title === 'example')
+ examples = mapExamples(examples)
+
+ // require('fliplog').quick(ast.dox.tags)
+
+ this.set('examples', examples)
+ }
+
+ let docblocks = getDocBlocksFrom(code)
+ docblocks = evolveDocblocks(docblocks)
+
+ this
+ .transform('dox', parse)
+ .observe('dox', setExamples)
+ .set('dox', docblocks)
+ .set('source', docblocks)
+ }
+}
+
+// --- test data (@TODO need to do this in loop listing fs) ---
+
+// const path = require.resolve('./src/deps/is/boolean.js')
+const path = require.resolve('./src/deps/is/string.js')
+const source = String(fs.readFileSync(path))
+let name = 'isString'
+
+const examples = new ExamplesTest(source)
+
+const ast = ASTChain(examples)
+ast.source(source).walk()
+
+// --- run our actual tests ---
+
+let fn = require(path)
+let functionName = fn.name || name
+let stripFnName = replace(functionName, '')
+let extracted = examples.get('examples')
+
+let expectations = extracted[0]
+ .map(example => example.map(stripFnName).map(x => eval(x)))
+ .map(example => {
+ let [expression, expected] = example
+ let passes = fn(expression) == expected
+ return {expression, expected, passes}
+ })
+
+let data = {expectations, fn}
+if (data.expectations.length === 0) {
+ data = extracted
+
+ if (data.length === 0) {
+ data = examples
+ }
+}
+
+// --- done ---
+require('fliplog').quick(data)
+
+
+// require('fliplog').quick(isBoolean, expectations)
+// require('fliplog').quick(examples.keys())
+// require('fliplog').quick(examples.get('examples'))
+
+// const codeSource = source
+// .replace('module.exports =', 'return')
+// .split('\n')
+// .filter(not(isComment))
+// .join('\n')
+//
+// var isBoolean = new Function(codeSource)
+// require('fliplog').quick(String(isBoolean), isBoolean)
+
+// examples.get('examples').map(eval)
+
+// var eh = examples.map(example => new ExampleTest(example))
+// require('fliplog').quick({eh})
diff --git a/build/fuzzyset.js b/build/fuzzyset.js
new file mode 100644
index 0000000..129b86c
--- /dev/null
+++ b/build/fuzzyset.js
@@ -0,0 +1,300 @@
+(function() {
+ var FuzzySet = function(arr, useLevenshtein, gramSizeLower, gramSizeUpper) {
+ var fuzzyset = {
+
+ }
+
+ // default options
+ arr = arr || []
+ fuzzyset.gramSizeLower = gramSizeLower || 2
+ fuzzyset.gramSizeUpper = gramSizeUpper || 3
+ fuzzyset.useLevenshtein = (typeof useLevenshtein !== 'boolean') ? true : useLevenshtein
+
+ // define all the object functions and attributes
+ fuzzyset.exactSet = {}
+ fuzzyset.matchDict = {}
+ fuzzyset.items = {}
+
+ // helper functions
+ var levenshtein = function(str1, str2) {
+ var current = [], prev, value
+
+ for (var i = 0; i <= str2.length; i++)
+ for (var j = 0; j <= str1.length; j++) {
+ if (i && j)
+ if (str1.charAt(j - 1) === str2.charAt(i - 1))
+ value = prev
+ else
+ value = Math.min(current[j], current[j - 1], prev) + 1
+ else
+ value = i + j
+
+ prev = current[j]
+ current[j] = value
+ }
+
+ return current.pop()
+ }
+
+ // return an edit distance from 0 to 1
+ var _distance = function(str1, str2) {
+ if (str1 === null && str2 === null) throw 'Trying to compare two null values'
+ if (str1 === null || str2 === null) return 0
+ str1 = String(str1); str2 = String(str2)
+
+ var distance = levenshtein(str1, str2)
+ if (str1.length > str2.length) {
+ return 1 - distance / str1.length
+ }
+ else {
+ return 1 - distance / str2.length
+ }
+ }
+ var _nonWordRe = /[^a-zA-Z0-9\u00C0-\u00FF, ]+/
+
+ var _iterateGrams = function(value, gramSize) {
+ gramSize = gramSize || 2
+ var simplified = '-' + value.toLowerCase().replace(_nonWordRe, '') + '-',
+ lenDiff = gramSize - simplified.length,
+ results = []
+ if (lenDiff > 0) {
+ for (var i = 0; i < lenDiff; ++i) {
+ value += '-'
+ }
+ }
+ for (var i = 0; i < simplified.length - gramSize + 1; ++i) {
+ results.push(simplified.slice(i, i + gramSize))
+ }
+ return results
+ }
+
+ var _gramCounter = function(value, gramSize) {
+ // return an object where key=gram, value=number of occurrences
+ gramSize = gramSize || 2
+ var result = {},
+ grams = _iterateGrams(value, gramSize),
+ i = 0
+ for (i; i < grams.length; ++i) {
+ if (grams[i] in result) {
+ result[grams[i]] += 1
+ }
+ else {
+ result[grams[i]] = 1
+ }
+ }
+ return result
+ }
+
+ // the main functions
+ fuzzyset.get = function(value, defaultValue, minMatchScore) {
+ // check for value in set, returning defaultValue or null if none found
+ if (minMatchScore === undefined) {
+ minMatchScore = 0.33
+ }
+ var result = this._get(value, minMatchScore)
+ if (!result && typeof defaultValue !== 'undefined') {
+ return defaultValue
+ }
+ return result
+ }
+
+ fuzzyset._get = function(value, minMatchScore) {
+ var normalizedValue = this._normalizeStr(value),
+ result = this.exactSet[normalizedValue]
+ if (result) {
+ return [[1, result]]
+ }
+
+ var results = []
+ // start with high gram size and if there are no results, go to lower gram sizes
+ for (var gramSize = this.gramSizeUpper; gramSize >= this.gramSizeLower; --gramSize) {
+ results = this.__get(value, gramSize, minMatchScore)
+ if (results && results.length > 0) {
+ return results
+ }
+ }
+ return null
+ }
+
+ fuzzyset.__get = function(value, gramSize, minMatchScore) {
+ var normalizedValue = this._normalizeStr(value),
+ matches = {},
+ gramCounts = _gramCounter(normalizedValue, gramSize),
+ items = this.items[gramSize],
+ sumOfSquareGramCounts = 0,
+ gram,
+ gramCount,
+ i,
+ index,
+ otherGramCount
+
+ for (gram in gramCounts) {
+ gramCount = gramCounts[gram]
+ sumOfSquareGramCounts += Math.pow(gramCount, 2)
+ if (gram in this.matchDict) {
+ for (i = 0; i < this.matchDict[gram].length; ++i) {
+ index = this.matchDict[gram][i][0]
+ otherGramCount = this.matchDict[gram][i][1]
+ if (index in matches) {
+ matches[index] += gramCount * otherGramCount
+ }
+ else {
+ matches[index] = gramCount * otherGramCount
+ }
+ }
+ }
+ }
+
+ function isEmptyObject(obj) {
+ for (var prop in obj) {
+ if (obj.hasOwnProperty(prop))
+ return false
+ }
+ return true
+ }
+
+ if (isEmptyObject(matches)) {
+ return null
+ }
+
+ var vectorNormal = Math.sqrt(sumOfSquareGramCounts),
+ results = [],
+ matchScore
+ // build a results list of [score, str]
+ for (var matchIndex in matches) {
+ matchScore = matches[matchIndex]
+ results.push([matchScore / (vectorNormal * items[matchIndex][0]), items[matchIndex][1]])
+ }
+ var sortDescending = function(a, b) {
+ if (a[0] < b[0]) {
+ return 1
+ }
+ else if (a[0] > b[0]) {
+ return -1
+ }
+ else {
+ return 0
+ }
+ }
+ results.sort(sortDescending)
+ if (this.useLevenshtein) {
+ var newResults = [],
+ endIndex = Math.min(50, results.length)
+ // truncate somewhat arbitrarily to 50
+ for (var i = 0; i < endIndex; ++i) {
+ newResults.push([_distance(results[i][1], normalizedValue), results[i][1]])
+ }
+ results = newResults
+ results.sort(sortDescending)
+ }
+ var newResults = []
+ results.forEach(function(scoreWordPair) {
+ if (scoreWordPair[0] >= minMatchScore) {
+ newResults.push([scoreWordPair[0], this.exactSet[scoreWordPair[1]]])
+ }
+ }.bind(this))
+ return newResults
+ }
+
+ fuzzyset.add = function(value) {
+ var normalizedValue = this._normalizeStr(value)
+ if (normalizedValue in this.exactSet) {
+ return false
+ }
+
+ var i = this.gramSizeLower
+ for (i; i < this.gramSizeUpper + 1; ++i) {
+ this._add(value, i)
+ }
+ }
+
+ fuzzyset._add = function(value, gramSize) {
+ var normalizedValue = this._normalizeStr(value),
+ items = this.items[gramSize] || [],
+ index = items.length
+
+ items.push(0)
+ var gramCounts = _gramCounter(normalizedValue, gramSize),
+ sumOfSquareGramCounts = 0,
+ gram, gramCount
+ for (gram in gramCounts) {
+ gramCount = gramCounts[gram]
+ sumOfSquareGramCounts += Math.pow(gramCount, 2)
+ if (gram in this.matchDict) {
+ this.matchDict[gram].push([index, gramCount])
+ }
+ else {
+ this.matchDict[gram] = [[index, gramCount]]
+ }
+ }
+ var vectorNormal = Math.sqrt(sumOfSquareGramCounts)
+ items[index] = [vectorNormal, normalizedValue]
+ this.items[gramSize] = items
+ this.exactSet[normalizedValue] = value
+ }
+
+ fuzzyset._normalizeStr = function(str) {
+ if (Object.prototype.toString.call(str) !== '[object String]') throw 'Must use a string as argument to FuzzySet functions'
+ return str.toLowerCase()
+ }
+
+ // return length of items in set
+ fuzzyset.length = function() {
+ var count = 0,
+ prop
+ for (prop in this.exactSet) {
+ if (this.exactSet.hasOwnProperty(prop)) {
+ count += 1
+ }
+ }
+ return count
+ }
+
+ // return is set is empty
+ fuzzyset.isEmpty = function() {
+ for (var prop in this.exactSet) {
+ if (this.exactSet.hasOwnProperty(prop)) {
+ return false
+ }
+ }
+ return true
+ }
+
+ // return list of values loaded into set
+ fuzzyset.values = function() {
+ var values = [],
+ prop
+ for (prop in this.exactSet) {
+ if (this.exactSet.hasOwnProperty(prop)) {
+ values.push(this.exactSet[prop])
+ }
+ }
+ return values
+ }
+
+
+ // initialization
+ var i = fuzzyset.gramSizeLower
+ for (i; i < fuzzyset.gramSizeUpper + 1; ++i) {
+ fuzzyset.items[i] = []
+ }
+ // add all the items to the set
+ for (i = 0; i < arr.length; ++i) {
+ fuzzyset.add(arr[i])
+ }
+
+ return fuzzyset
+ }
+
+ var root = this
+ // Export the fuzzyset object for **CommonJS**, with backwards-compatibility
+ // for the old `require()` API. If we're not in CommonJS, add `_` to the
+ // global object.
+ if (typeof module !== 'undefined' && module.exports) {
+ module.exports = FuzzySet
+ root.FuzzySet = FuzzySet
+ }
+ else {
+ root.FuzzySet = FuzzySet
+ }
+})()
diff --git a/build/playground/rollup.js b/build/playground/rollup.js
index e59a355..3b72b9b 100644
--- a/build/playground/rollup.js
+++ b/build/playground/rollup.js
@@ -1,5 +1,7 @@
const {resolve} = require('path')
const log = require('fliplog')
+const nodeResolve = require('rollup-plugin-node-resolve')
+const commonjs = require('rollup-plugin-commonjs')
const {rollup} = require('rollup')
const uglify = require('rollup-plugin-uglify')
const {minify} = require('uglify-es')
@@ -10,7 +12,8 @@ const res = rel => resolve(__dirname, rel)
const replacePlugin = () => {
return replace({
- 'process.env.NODE_ENV': JSON.stringify('debug'),
+ 'process.env.NODE_ENV': JSON.stringify('production'),
+ // 'process.env.NODE_ENV': JSON.stringify('debug'),
'NO_OP': `function() {/* noop */}`,
})
}
@@ -76,12 +79,15 @@ const uglifyPlugin = () =>
)
const config = {
- entry: res('./play.js'),
- external: [],
+ // entry: res('./play.js'),
+ // entry: res('../../src/deps/fp/curry.js'),
+ entry: res('../../src/deps/is/tagEq.js'),
+ // external: [],
onwarn(warning) {
log.red(warning).echo()
},
- plugins: [replacePlugin(), bublePlugin(), uglifyPlugin()],
+ // , bublePlugin(), uglifyPlugin()
+ plugins: [replacePlugin(), nodeResolve(), commonjs()],
}
const bundleOptions = {
dest: res('./play.bundled.js'),
@@ -94,7 +100,7 @@ const bundleOptions = {
rollup(config)
.catch()
.then(ricky => {
- // has the ast, imports, exports, etc
+ // @NOTE ricky has the ast, imports, exports, etc
log.data(ricky).echo(false)
ricky.write(bundleOptions)
})
diff --git a/build/plugins/comments.js b/build/plugins/comments.js
new file mode 100644
index 0000000..65c3017
--- /dev/null
+++ b/build/plugins/comments.js
@@ -0,0 +1,22 @@
+const log = require('fliplog')
+
+function commentsPlugin(options = {}) {
+ return {
+ name: 'comments',
+ transform(code, id) {
+ if (id.includes('index.js')) return null
+ const parts = id.split('chain-able/')
+ if (parts.length <= 1) return null
+
+
+ const filename = parts.pop() || 'missing-filename'
+ const filenameComment = '/* ___filename___: ' + filename + ' */\n'
+ if (code.includes(filenameComment)) return null
+ console.log({filename})
+
+ return filenameComment + code
+ },
+ }
+}
+
+module.exports = options => commentsPlugin(options)
diff --git a/build/plugins/index.js b/build/plugins/index.js
index 1c9a390..3a1713c 100644
--- a/build/plugins/index.js
+++ b/build/plugins/index.js
@@ -5,6 +5,7 @@ const optimizejs = require('./optimizejs')
const filesize = require('./filesize')
const replace = require('./replace')
const falafelPlugin = require('./ast')
+const commentsPlugin = require('./comments')
module.exports = (version, options) => {
if (options.env === 'development') {
@@ -17,6 +18,8 @@ module.exports = (version, options) => {
const plugins = []
const add = plugin => plugins.push(plugin)
+ add(commentsPlugin(options))
+
if (options.falafel) add(falafelPlugin(options))
if (options.replace) add(replace(options))
diff --git a/build/plugins/uglify.js b/build/plugins/uglify.js
index ad3d4e7..6fecba5 100644
--- a/build/plugins/uglify.js
+++ b/build/plugins/uglify.js
@@ -5,7 +5,11 @@ const {minify} = require('uglify-es')
// https://github.com/mishoo/UglifyJS2#minify-options-structure
// should mangle...
module.exports = options => {
- const mangles = options.mangles === undefined ? true : options.mangles
+ let mangles = options.mangles === undefined ? true : options.mangles
+
+ // @TODO hard to keep it mangling top-level, so ugly with 1 letter fns
+ // mangles = false
+
const beautify = !!options.beautify
const uglifyOptions = {
@@ -49,10 +53,12 @@ module.exports = options => {
// @TODO:
// pure_funcs: true, side_effects: false,
- keep_fargs: beautify,
+
+ // @NOTE we need this one for fp/arity
+ keep_fargs: true,
+
keep_fnames: beautify, // for now
- // keep_fargs: false,
// keep_fnames: false, // for now
passes: 10,
},
diff --git a/build/size-over-time.txt b/build/size-over-time.txt
index 9cad971..11ee264 100644
--- a/build/size-over-time.txt
+++ b/build/size-over-time.txt
@@ -834,3 +834,243 @@ $ gzip-size "dists/umd/index.js" "--raw"
Done in 0.68s.
2017:15:07/12/17:19:15:45
---
+yarn run v0.27.5
+$ gzip-size "dists/umd/index.js" "--raw"
+8774
+Done in 0.53s.
+2017:30:07/13/17:00:30:48
+---
+yarn run v0.27.5
+$ gzip-size "dists/umd/index.js" "--raw"
+2357 <- traverser only (along with deps) (before any size optimization)
+Done in 0.56s.
+2017:55:07/13/17:03:55:41
+---
+yarn run v0.27.5
+$ gzip-size "dists/umd/index.js" "--raw"
+2080 <- original traverse-js size (along with deps) (with all deopts)
+Done in 0.53s.
+2017:59:07/13/17:03:59:39
+---
+yarn run v0.27.5
+$ gzip-size "dists/umd/index.js" "--raw"
+8780
+Done in 0.54s.
+2017:01:07/13/17:04:01:49
+---
+yarn run v0.27.5
+$ gzip-size "dists/umd/index.js" "--raw"
+8835
+Done in 0.51s.
+2017:59:07/15/17:01:59:43
+---
+yarn run v0.27.5
+$ gzip-size "dists/umd/index.js" "--raw"
+9162
+Done in 0.61s.
+2017:34:07/16/17:19:34:30
+---
+yarn run v0.27.5
+$ gzip-size "dists/umd/index.js" "--raw"
+9161
+Done in 0.47s.
+2017:14:07/16/17:20:14:21
+---
+yarn run v0.27.5
+$ gzip-size "dists/umd/index.js" "--raw"
+9161
+Done in 0.55s.
+2017:51:07/17/17:20:51:34
+---
+yarn run v0.27.5
+$ gzip-size "dists/umd/index.js" "--raw"
+9161
+Done in 0.59s.
+2017:58:07/17/17:20:58:46
+---
+yarn run v0.27.5
+$ gzip-size "dists/umd/index.js" "--raw"
+9161
+Done in 0.56s.
+2017:23:07/17/17:21:23:44
+---
+yarn run v0.27.5
+$ gzip-size "dists/umd/index.js" "--raw"
+9161
+Done in 0.61s.
+2017:02:07/17/17:22:02:19
+---
+yarn run v0.27.5
+$ gzip-size "dists/umd/index.js" "--raw"
+9161
+Done in 0.58s.
+2017:48:07/18/17:00:48:19
+---
+yarn run v0.27.5
+$ gzip-size "dists/umd/index.js" "--raw"
+9161
+Done in 0.54s.
+2017:50:07/18/17:00:50:01
+---
+yarn run v0.27.5
+$ gzip-size "dists/umd/index.js" "--raw"
+9161
+Done in 0.55s.
+2017:50:07/18/17:00:50:43
+---
+yarn run v0.27.5
+$ gzip-size "dists/umd/index.js" "--raw"
+9161
+Done in 0.54s.
+2017:51:07/18/17:00:51:39
+---
+yarn run v0.27.5
+$ gzip-size "dists/umd/index.js" "--raw"
+9161
+Done in 0.54s.
+2017:52:07/18/17:00:52:12
+---
+yarn run v0.27.5
+$ gzip-size "dists/umd/index.js" "--raw"
+9161
+Done in 0.58s.
+2017:53:07/18/17:00:53:59
+---
+yarn run v0.27.5
+$ gzip-size "dists/umd/index.js" "--raw"
+9161
+Done in 0.54s.
+2017:54:07/18/17:00:54:51
+---
+yarn run v0.27.5
+$ gzip-size "dists/umd/index.js" "--raw"
+9161
+Done in 0.55s.
+2017:55:07/18/17:00:55:15
+---
+yarn run v0.27.5
+$ gzip-size "dists/umd/index.js" "--raw"
+9161
+Done in 0.58s.
+2017:55:07/18/17:00:55:52
+---
+yarn run v0.27.5
+$ gzip-size "dists/umd/index.js" "--raw"
+9161
+Done in 0.55s.
+2017:56:07/18/17:00:56:24
+---
+yarn run v0.27.5
+$ gzip-size "dists/umd/index.js" "--raw"
+9161
+Done in 0.70s.
+2017:57:07/18/17:00:57:27
+---
+yarn run v0.27.5
+$ gzip-size "dists/umd/index.js" "--raw"
+12612 <- not uglified top level
+Done in 0.53s.
+2017:00:07/18/17:01:00:43
+---
+yarn run v0.27.5
+$ gzip-size "dists/umd/index.js" "--raw"
+9183 <- before trying curry in tryCatch
+Done in 0.49s.
+2017:27:07/18/17:15:27:26
+---
+yarn run v0.27.5
+$ gzip-size "dists/umd/index.js" "--raw"
+9219 <- with curry, sad
+Done in 0.57s.
+2017:28:07/18/17:15:28:24
+---
+yarn run v0.27.5
+$ gzip-size "dists/umd/index.js" "--raw"
+9216 <- currying tryCatch, so minor, why bigger for the other one? because they are both curried? sheesh
+Done in 0.56s.
+2017:30:07/18/17:15:30:38
+---
+yarn run v0.27.5
+$ gzip-size "dists/umd/index.js" "--raw"
+9371
+Done in 0.75s.
+2017:40:07/18/17:17:40:52
+---
+yarn run v0.27.5
+$ gzip-size "dists/umd/index.js" "--raw"
+9379
+Done in 0.62s.
+2017:34:07/19/17:19:34:43
+---
+yarn run v0.27.5
+$ gzip-size "dists/umd/index.js" "--raw"
+9379
+Done in 0.52s.
+2017:20:07/19/17:20:20:37
+---
+yarn run v0.27.5
+$ gzip-size "dists/umd/index.js" "--raw"
+9261
+Done in 0.56s.
+2017:55:07/19/17:21:55:07
+---
+yarn run v0.27.5
+$ gzip-size "dists/umd/index.js" "--raw"
+9303 <- refactor .equals
+Done in 0.58s.
+2017:36:07/20/17:02:36:25
+---
+yarn run v0.27.5
+$ gzip-size "dists/umd/index.js" "--raw"
+9308
+Done in 0.69s.
+2017:43:07/20/17:02:43:10
+---
+yarn run v0.27.5
+$ gzip-size "dists/umd/index.js" "--raw"
+9308
+Done in 0.54s.
+2017:54:07/20/17:02:54:35
+---
+yarn run v0.27.5
+$ gzip-size "dists/umd/index.js" "--raw"
+9308
+Done in 0.58s.
+2017:58:07/20/17:02:58:53
+---
+yarn run v0.27.5
+$ gzip-size "dists/umd/index.js" "--raw"
+9161 <- minor easy util usage (props in gc, remove if > 100 parents in traverse, remove isArray && !isArray since it is covered already, )
+Done in 0.54s.
+2017:21:07/20/17:03:21:48
+---
+yarn run v0.27.5
+$ gzip-size "dists/umd/index.js" "--raw"
+9153 <- more minor utils (or in str or num), rename .iteratee to .node, ternary in transform.remap
+Done in 0.62s.
+2017:12:07/20/17:18:12:51
+---
+yarn run v0.27.5
+$ gzip-size "dists/umd/index.js" "--raw"
+9153
+Done in 0.53s.
+2017:20:07/20/17:18:20:28
+---
+yarn run v0.27.5
+$ gzip-size "dists/umd/index.js" "--raw"
+9153
+Done in 0.59s.
+2017:24:07/20/17:18:24:16
+---
+yarn run v0.27.5
+$ gzip-size "dists/umd/index.js" "--raw"
+9153
+Done in 0.58s.
+2017:32:07/20/17:18:32:48
+---
+yarn run v0.27.5
+$ gzip-size "dists/umd/index.js" "--raw"
+9269
+Done in 0.54s.
+2017:38:07/22/17:03:38:19
+---
diff --git a/build/util/__fixme.js b/build/util/__fixme.js
new file mode 100644
index 0000000..927d2be
--- /dev/null
+++ b/build/util/__fixme.js
@@ -0,0 +1,203 @@
+const {
+ curry,
+ not,
+ includes,
+ includesCount,
+ camelCase,
+ replace,
+ first,
+ isMatch,
+ isString,
+ isTrue,
+ isFunction,
+ isArray,
+ isEmpty,
+ remove,
+ reverse,
+ pipe,
+ toMatcher,
+ construct,
+ invoke,
+ hasOwnProperty,
+ keysObjOrArray,
+} = require('../../exports')
+
+const isNegative = x => x < 0
+
+// NEED TO HAVE .LAST_INDEX_OF CAN USE COUNT, SAME WAY, AND CPY FROM LODASH | RAMDA
+
+// whether to return the key along with value...
+// first, last, nth
+const _findAt = curry(3, (haystack, predicate, position) => {
+ let findings = []
+
+ // @TODO NOT SOLID
+ const hay = isArray(haystack) ? haystack : haystack.split(predicate)
+
+ // loop obj ugh
+ hay.forEach((needle, key) => {
+ if (isMatch(needle, predicate)) findings.push(needle)
+ // if (predicate(needle, key)) findings.push(needle)
+ })
+
+ if (isEmpty(findings)) return null
+ else if (isNegative(position)) return findings[findings.length - position]
+ else return findings[position]
+})
+
+// findIndexAt
+const findIndexAt = curry(3, (haystack, predicate, position) => {
+ const finding = _findAt(haystack, predicate, position)
+ return haystack.indexOf(finding)
+})
+
+// const replaceLast = findAt('_', '_', -1)
+// const replaceLast = (pattern, replacement, str) =>
+// pipe(reverse, replace(pattern, replacement), reverse)(str)
+
+const replaceLast = (pattern, replacement, str) => {
+ // const index = findIndexAt(str, pattern, -1)
+
+ // 1
+ // const pieces = str.split(pattern)
+ // const replaced = pieces.join(pattern)
+
+ // 2
+ const index = str.lastIndexOf(pattern)
+ const pre = str.substring(0, index)
+ const second = str.substring(index)
+ const replaced = pre + second.replace(pattern, replacement)
+ // console.log({index, pre, second, pattern, replaced})
+
+ // 3
+ // const strs = str.split(pattern)
+ // let replaced = ''
+ // strs.forEach((s, index) => {
+ // if (index === strs.length) replaced += s.replace(pattern)
+ // else replaced += s
+ // })
+
+ // const replaced = str.replace(toMatcher(pattern), replacement)
+
+ return replaced
+}
+
+// @TODO could also use for in
+const forOwn = curry(2, (array, iteratee) => {
+ const nodeIsArray = isArray(array)
+ let keys = keysObjOrArray(array)
+ let index = 0
+ while (index++ < keys.length - 1) {
+ const key = nodeIsArray ? keys[index] : keys[keys[index]]
+ iteratee(keys[index], key, index, array)
+ }
+ return array
+})
+
+// forEachChain
+const forEach = curry(2, (array, iteratee) => {
+ array.forEach(iteratee)
+ return array
+})
+const wrapForEach = (array) => {
+ return {forEach: forEach(array)}
+}
+
+
+// @TODO pure-function side-effect-free to return say an array
+// with them knowing the original index
+//
+// @TODO need to remap Map too... ugh
+const _remapKeys = (transform, obj, removeOld = true) => {
+ Object.keys(obj).forEach(oldKey => {
+ const newKey = transform(obj[oldKey])
+ obj[newKey] = obj[oldKey]
+ if (isTrue(removeOld)) remove(obj[oldKey])
+ })
+}
+const _remapValues = (transform, obj) => {
+ Object.keys(obj).forEach(key => obj[key] = transform(obj[key], key))
+}
+
+// value & values, key & keys, as obj or array... goodness
+//
+// match key, if match, use that transform (first one, condition/all as og name)
+const _findKey = (predicate, obj) => Object.keys(obj).filter(predicate).shift()
+const findKey = curry(2, _findKey)
+
+// @TODO NEED FINDVALUES TO PIPE ALL RESULTS
+const _findValue = (predicate, obj) => {
+ const keys = Object.keys(obj)
+ for (let index = 0; index < keys.length; index++) {
+ const key = keys[index]
+ const value = obj[key]
+ if (predicate(value, key)) return value
+ }
+ return false
+}
+const _findValues = (predicate, obj) => {
+ const keys = Object.keys(obj)
+ const valuesFound = []
+ for (let index = 0; index < keys.length; index++) {
+ const key = keys[index]
+ const value = obj[key]
+ if (predicate(value, key)) valuesFound.push(value)
+ }
+ return valuesFound
+}
+
+const findValue = curry(2, _findValue)
+const findValues = curry(2, _findValues)
+
+const remapKeys = curry(2, _remapKeys)
+const remapValues = curry(2, _remapValues)
+
+const remapToMatch = remapKeys(toMatcher)
+const findFirstMatch = pipe(isMatch, findValue)
+
+
+// @TODO now I have a use knowing it exists...
+// find(map, prop, isMatch)
+// findKey(map, isMatch)
+// Object.keys(map).filter(isMatch)
+// remapToMatch(map)
+
+const findMatching = (obj, query) => {
+ let lastKeyFound
+ let keys = []
+
+ const keyToMatcher = (val, key) => {
+ lastKeyFound = key
+ // console.log('does it match?', {query, val, key, isMatch: isMatch(query, key)})
+ if (isMatch(query, key)) {
+ keys.push(key)
+ return true
+ }
+ return false
+ }
+
+ const value = findValues(keyToMatcher, obj)
+
+ // console.log({value, keys}, 'finding matching...')
+ if (value.length) return [lastKeyFound, value, keys]
+ else return false
+}
+
+module.exports = {
+ forEach,
+ wrapForEach,
+ replaceLast,
+ isNegative,
+ // find
+ findIndexAt,
+ findMatching,
+ findKey,
+ findValue,
+ findValues,
+ findFirstMatch,
+ // remap
+ remapKeys,
+ remapValues,
+ remapToMatch,
+ forOwn,
+}
diff --git a/build/util/_filefolder.js b/build/util/_filefolder.js
new file mode 100644
index 0000000..051f9a7
--- /dev/null
+++ b/build/util/_filefolder.js
@@ -0,0 +1,23 @@
+const {basename} = require('path')
+
+const getFolderName = file => {
+ const fileParts = file.split('/')
+ fileParts.pop()
+ return fileParts.pop()
+}
+const getFileName = (file, withExt = false) => {
+ let filename = basename(file)
+
+ if (withExt === false && filename.includes('.')) {
+ filename = filename.split('.').shift()
+ }
+
+ return filename
+}
+const getFolderAndFileName = (abs, withExt = false) => {
+ const folder = getFolderName(abs, withExt)
+ const file = getFileName(abs, withExt)
+ return [folder, file, abs]
+}
+
+module.exports = {getFolderName, getFileName, getFolderAndFileName}
diff --git a/build/util/_isDir.js b/build/util/_isDir.js
new file mode 100644
index 0000000..f00df91
--- /dev/null
+++ b/build/util/_isDir.js
@@ -0,0 +1,10 @@
+const fs = require('fs')
+
+module.exports = function isDir(file) {
+ try {
+ return fs.lstatSync(file).isDirectory()
+ }
+ catch (e) {
+ return false
+ }
+}
diff --git a/build/util/_res.js b/build/util/_res.js
new file mode 100644
index 0000000..4839703
--- /dev/null
+++ b/build/util/_res.js
@@ -0,0 +1,4 @@
+const {resolve} = require('path')
+const {curry} = require('../../')
+
+module.exports = curry(2, (dir, rel) => resolve(dir, rel))
diff --git a/build/util/_toRel.js b/build/util/_toRel.js
new file mode 100644
index 0000000..21e7651
--- /dev/null
+++ b/build/util/_toRel.js
@@ -0,0 +1,7 @@
+const {resolve} = require('path')
+const {curry} = require('../../')
+
+// replace()
+const toRel = (rootPath, filePath) => filePath.replace(rootPath, '')
+
+module.exports = curry(2, toRel)
diff --git a/build/util/fromTo.js b/build/util/fromTo.js
new file mode 100644
index 0000000..32fd812
--- /dev/null
+++ b/build/util/fromTo.js
@@ -0,0 +1,47 @@
+const ConfigStore = require('configstore')
+const {read, write, exists} = require('flipfile')
+const _res = require('./_res')
+const del = require('./_delete')
+
+const res = _res(__dirname)
+
+const path = res('../fromTo.json')
+const defaultCopied = {
+ /* ['absFrom']: 'absTo' */
+}
+const store = new ConfigStore('easy-exports', {copied: defaultCopied})
+
+// put in store instead
+const fromTo = {
+ path,
+}
+
+// @TODO file-chain here
+fromTo.read = () => {
+ if (exists(path)) fromTo.data = read.json(path)
+ else fromTo.data = {}
+
+ return fromTo
+}
+fromTo.write = () => {
+ const string = JSON.stringify(fromTo.data, null, 2)
+ write(path, string)
+ return fromTo
+}
+fromTo.del = () => {
+ del(path)
+ return fromTo
+}
+fromTo.values = () => Object.values(fromTo.data)
+fromTo.keys = () => Object.keys(fromTo.data)
+
+fromTo.read()
+
+if (process.env.DEBUG) {
+ fromTo.folder = res('../FAKEROOT')
+}
+else {
+ fromTo.folder = res('../../')
+}
+
+module.exports = fromTo
diff --git a/build/util/index.js b/build/util/index.js
index b0c473b..b651cb0 100644
--- a/build/util/index.js
+++ b/build/util/index.js
@@ -1,4 +1,8 @@
module.exports = {
argv: require('./_args'),
del: require('./_delete'),
+ res: require('./_res'),
+ _res: require('./_res'),
+ fromTo: require('./fromTo'),
+ isDir: require('./_isDir'),
}
diff --git a/build/versions/5.0.0-beta.5/index.js b/build/versions/5.0.0-beta.5/index.js
new file mode 100644
index 0000000..1f15430
--- /dev/null
+++ b/build/versions/5.0.0-beta.5/index.js
@@ -0,0 +1,10984 @@
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+ typeof define === 'function' && define.amd ? define(factory) :
+ (global.ChainAble = factory());
+}(this, (function () { 'use strict';
+
+ function unwrapExports (x) {
+ return x && x.__esModule ? x['default'] : x;
+ }
+
+ function createCommonjsModule(fn, module) {
+ return module = { exports: {} }, fn(module, module.exports), module.exports;
+ }
+
+ /* ___filename___: dist/deps/util/assign.js */
+ /**
+ * @memberOf util
+ *
+ * {@link https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/assign mozilla-object-assign}
+ * {@link https://esdiscuss.org/topic/object-assign-with-several-source-objects esdiscuss-object-assign}
+ * {@link https://github.com/facebook/react/blob/4b2eac3de7e1dbf5c2dd742fd9989974a83972cb/scripts/babel/transform-object-assign-require.js react-object-assign}
+ * {@link https://github.com/lodash/lodash/blob/master/.internal/assignValue.js lodash-assign}
+ * {@link https://github.com/ramda/ramda/blob/master/src/internal/_objectAssign.js ramda-assign}
+ * @see {@link react-object-assign}
+ * @see {@link ramda-assign}
+ * @see {@link lodash-assign}
+ * @see {@link esdiscuss-object-assign}
+ * @see {@link mozilla-object-assign}
+ *
+ * @type {Function}
+ */
+ var assign = Object.assign;
+
+ // @TODO polyfil
+
+ // --- check
+ // function shouldUseNative() {
+ // try {
+ // if (!Object.assign) {
+ // return false
+ // }
+ //
+ // // Detect buggy property enumeration order in older V8 versions.
+ //
+ // // https://bugs.chromium.org/p/v8/issues/detail?id=4118
+ // var test1 = new String('abc') // eslint-disable-line no-new-wrappers
+ // test1[5] = 'de'
+ // if (Object.getOwnPropertyNames(test1)[0] === '5') {
+ // return false
+ // }
+ //
+ // // https://bugs.chromium.org/p/v8/issues/detail?id=3056
+ // var test2 = {}
+ // for (var i = 0; i < 10; i++) {
+ // test2['_' + String.fromCharCode(i)] = i
+ // }
+ // var order2 = Object.getOwnPropertyNames(test2).map(function(n) {
+ // return test2[n]
+ // })
+ // if (order2.join('') !== '0123456789') {
+ // return false
+ // }
+ //
+ // // https://bugs.chromium.org/p/v8/issues/detail?id=3056
+ // var test3 = {}
+ // 'abcdefghijklmnopqrst'.split('').forEach(function(letter) {
+ // test3[letter] = letter
+ // })
+ // if (
+ // Object.keys(Object.assign({}, test3)).join('') !== 'abcdefghijklmnopqrst'
+ // ) {
+ // return false
+ // }
+ //
+ // return true
+ // }
+ // catch (err) {
+ // // We don't expect any of the above to throw, but better to be safe.
+ // return false
+ // }
+ // }
+
+ // --- handle
+ // function ObjectAssign(target, source) {
+ // var from
+ // var to = toObject(target)
+ // var symbols
+ //
+ // for (var s = 1; s < arguments.length; s++) {
+ // from = Object(arguments[s])
+ //
+ // for (var key in from) {
+ // if (hasOwnProperty.call(from, key)) {
+ // to[key] = from[key]
+ // }
+ // }
+ //
+ // if (getOwnPropertySymbols) {
+ // symbols = getOwnPropertySymbols(from)
+ // for (var i = 0; i < symbols.length; i++) {
+ // if (propIsEnumerable.call(from, symbols[i])) {
+ // to[symbols[i]] = from[symbols[i]]
+ // }
+ // }
+ // }
+ // }
+ //
+ // return to
+ // }
+
+ /* ___filename___: dist/deps/is/undefined.js */
+ /**
+ * @desc Checks if `value` is `undefined`.
+ * @category Lang
+ *
+ * @param {*} x value
+ * @return {boolean} isUndefined
+ *
+ * @since 4.0.0-alpha.1
+ * @memberOf is
+ * @func isUndefined
+ *
+ * @see is/nullOrUndefined
+ * @see https://github.com/infernojs/inferno/blob/master/packages/inferno-shared/src/index.ts#L57
+ *
+ * @example
+ *
+ * isUndefined(undefined)
+ * //=> true
+ * isUndefined(void 0)
+ * //=> true
+ *
+ * isUndefined(null)
+ * //=> false
+ * isUndefined(NaN)
+ * //=> false
+ * isUndefined({})
+ * //=> false
+ * isUndefined('')
+ * //=> false
+ * isUndefined(1)
+ * //=> false
+ * isUndefined(false)
+ * //=> false
+ *
+ */
+ var _undefined = function (x) { return x === undefined; };
+
+ /* ___filename___: dist/deps/symbols/iterator.js */
+ var iterator = Symbol.iterator;
+
+ // typeof Symbol !== 'undefined'
+ // ? Symbol.iterator
+ // : '@@iterator'
+
+ /* ___filename___: dist/deps/symbols/instance.js */
+ var instance = Symbol.hasInstance;
+
+ /* ___filename___: dist/deps/symbols/primitive.js */
+ var primitive = Symbol.toPrimitive;
+
+ /* ___filename___: dist/deps/is/null.js */
+ /**
+ * @param {*} x value
+ * @return {boolean} isNull
+ *
+ * @since 3.0.0
+ * @memberOf is
+ * @func isNull
+ *
+ * @example
+ *
+ * isNull(null)
+ * //=> true
+ *
+ * isNull(undefined)
+ * //=> false
+ * isNull(void 0)
+ * //=> false
+ * isNull({})
+ * //=> false
+ * isNull('')
+ * //=> false
+ * isNull(1)
+ * //=> false
+ *
+ */
+ var _null = function (x) { return x === null; };
+
+ /* ___filename___: dist/deps/is/null.js */
+
+ /* ___filename___: dist/deps/is/undefined.js */
+
+ /* ___filename___: dist/deps/is/nullOrUndefined.js */
+
+
+
+ /**
+ * @desc Checks if `value` is `null` or `undefined`.
+ * @alias isNil
+ * @category Lang
+ *
+ * @param {*} x value
+ * @return {boolean} isNullOrUndefined
+ *
+ * @since 4.0.0-alpha.1
+ * @memberOf is
+ * @func isNullOrUndefined
+ *
+ * @see is/null
+ * @see is/undefined
+ * @see https://github.com/infernojs/inferno/blob/master/packages/inferno-shared/src/index.ts#L23
+ *
+ * @example
+ *
+ * isNullOrUndefined(null)
+ * //=> true
+ * isNullOrUndefined(undefined)
+ * //=> true
+ * isNullOrUndefined(void 0)
+ * //=> true
+ *
+ * isNullOrUndefined(NaN)
+ * //=> false
+ * isNullOrUndefined({})
+ * //=> false
+ * isNullOrUndefined('')
+ * //=> false
+ * isNullOrUndefined(1)
+ * //=> false
+ * isNullOrUndefined(false)
+ * //=> false
+ *
+ */
+ var nullOrUndefined = function isNullOrUndef(x) {
+ return _undefined(x) || _null(x)
+ };
+
+ /* ___filename___: dist/deps/is/nullOrUndefined.js */
+
+ /* ___filename___: dist/deps/is/prototypeOf.js */
+
+
+ var isPrototypeOf = Object.prototype.isPrototypeOf;
+
+ /**
+ * check if arg 1 is prototype of arg 2
+ *
+ * @TODO curry2
+ * @memberOf is
+ * @name isPrototypeOf
+ * @since 3.0.0
+ *
+ * @param {Object | *} haystack check needle against
+ * @param {Object | *} needle is prototype of haystack
+ * @return {boolean} needle isPrototypeOf haystack
+ *
+ * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isPrototypeOf mozilla-obj-isprototypeof}
+ * @see {@link mozilla-obj-isprototypeof}
+ *
+ * @example
+ *
+ * class Eh extends Function {}
+ * class Canada extends Eh {}
+ * isPrototypeOf(Eh, Function) //=> true
+ * isPrototypeOf(Canada, Function) //=> true
+ * isPrototypeOf(Eh, Date) //=> false
+ *
+ * isPrototypeOf({}, Object) //=> true
+ * isPrototypeOf({}, Array) //=> false
+ *
+ */
+ var prototypeOf = function (haystack, needle) { return !nullOrUndefined(haystack) && isPrototypeOf.call(haystack, needle); };
+
+ /* ___filename___: dist/deps/fp/isPlaceholder.js */
+ var isPlaceholder = function _isPlaceholder(x) {
+ return x === '_'
+ };
+
+ /* ___filename___: dist/deps/fp/arity.js */
+ /* eslint complexity: "OFF" */
+ /* eslint consistent-return: "OFF" */
+ /* eslint max-len: "OFF" */
+ /* eslint no-unused-vars: "OFF" */
+
+ /* istanbul ignore next: metadata, one is covered, all are covered */
+ /* prettier-ignore */
+ /**
+ * @desc just for `.length` of a function?
+ * @memberOf fp
+ *
+ * @since 5.0.0
+ * @param {number} n number of arguments
+ * @param {Function} fn function to wrap
+ * @return {Function} function with params
+ *
+ * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/arity mozilla-func-arity}
+ * @see {@link mozilla-func-arity}
+ *
+ * @TODO keeping this means change uglify...
+ *
+ * @example
+ *
+ * const wan = one => console.log(one)
+ * arity(1, wan)
+ * => function(one => wan(one))
+ *
+ */
+ var arity = function _arity(n, fn) {
+ if (n === 0 || n > 5) { return function() { return fn.apply(this, arguments) } }
+ else if (n === 1) { return function($0) { return fn.apply(this, arguments) } }
+ else if (n === 2) { return function($0, $1) { return fn.apply(this, arguments) } }
+ else if (n === 3) { return function($0, $1, $2) { return fn.apply(this, arguments) } }
+ else if (n === 4) { return function($0, $1, $2, $3) { return fn.apply(this, arguments) } }
+ else if (n === 5) { return function($0, $1, $2, $3, $4) { return fn.apply(this, arguments) } }
+
+ // @NOTE ignoring
+ // else if (n === 6) return function(a0, a1, a2, a3, a4, a5) { return fn.apply(this, arguments) }
+ // else if (n === 7) return function(a0, a1, a2, a3, a4, a5, a6) { return fn.apply(this, arguments) }
+ // else if (n === 8) return function(a0, a1, a2, a3, a4, a5, a6, a7) { return fn.apply(this, arguments) }
+ // else if (n === 9) return function(a0, a1, a2, a3, a4, a5, a6, a7, a8) { return fn.apply(this, arguments) }
+ // else if (n === 10) return function(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) { return fn.apply(this, arguments) }
+ };
+
+ /* ___filename___: dist/deps/fp/isPlaceholder.js */
+
+ /* ___filename___: dist/deps/fp/arity.js */
+
+ /* ___filename___: dist/deps/fp/curry.js */
+
+
+
+
+ /**
+ * Returns a curried equivalent of the provided function, with the specified
+ * arity. The curried function has two unusual capabilities. First, its
+ * arguments needn't be provided one at a time. If `g` is `R.curryN(3, f)`, the
+ * following are equivalent:
+ *
+ * - `g(1)(2)(3)`
+ * - `g(1)(2, 3)`
+ * - `g(1, 2)(3)`
+ * - `g(1, 2, 3)`
+ *
+ * Secondly, the special placeholder value [`R.__`](#__) may be used to specify
+ * "gaps", allowing partial application of any combination of arguments,
+ * regardless of their positions. If `g` is as above and `_` is [`R.__`](#__),
+ * the following are equivalent:
+ *
+ * - `g(1, 2, 3)`
+ * - `g(_, 2, 3)(1)`
+ * - `g(_, _, 3)(1)(2)`
+ * - `g(_, _, 3)(1, 2)`
+ * - `g(_, 2)(1)(3)`
+ * - `g(_, 2)(1, 3)`
+ * - `g(_, 2)(_, 3)(1)`
+ *
+ * @func
+ * @memberOf fp
+ * @since 5.0.0-beta.1
+ * @ramda v0.5.0
+ * @category Function
+ * @sig Number -> (* -> a) -> (* -> a)
+ *
+ * @param {Number} length The arity of the curried function.
+ * @param {Array} received An array of arguments received thus far.
+ * @param {Function} fn The function to curry.
+ * @return {Function} A new, curried function.
+ *
+ * {@link https://github.com/ramda/ramda/blob/master/src/uncurryN.js ramda-uncurry}
+ * {@link https://github.com/ramda/ramda/blob/master/src/curryN.js ramda-curry}
+ * {@link https://github.com/lodash/lodash/blob/master/curry.js lodash-curry}
+ * @see {@link ramda-curry}
+ * @see {@link lodash-curry}
+ * @see {@link ramda-uncurry}
+ *
+ * @types fp
+ * @tests fp/curry
+ *
+ * @example
+ *
+ * var sumArgs = (...args) => R.sum(args);
+ *
+ * var curriedAddFourNumbers = R.curryN(4, sumArgs);
+ * var f = curriedAddFourNumbers(1, 2);
+ * var g = f(3);
+ * g(4); //=> 10
+ *
+ */
+ function _curryN(length, received, fn) {
+ return function() {
+ var arguments$1 = arguments;
+
+ var combined = [];
+ var argsIdx = 0;
+ var left = length;
+ var combinedIdx = 0;
+
+ while (combinedIdx < received.length || argsIdx < arguments.length) {
+ var result = (void 0);
+
+ if (
+ combinedIdx < received.length &&
+ (!isPlaceholder(received[combinedIdx]) || argsIdx >= arguments$1.length)
+ ) {
+ result = received[combinedIdx];
+ }
+ else {
+ result = arguments$1[argsIdx++];
+ // argsIdx += 1
+ }
+ combined[combinedIdx++] = result;
+ if (!isPlaceholder(result)) {
+ left -= 1;
+ }
+ // combinedIdx += 1
+ }
+ return left <= 0
+ ? fn.apply(this, combined)
+ : arity(left, _curryN(length, combined, fn))
+ }
+ }
+
+ /**
+ * Returns a curried equivalent of the provided function, with the specified
+ * arity. The curried function has two unusual capabilities. First, its
+ * arguments needn't be provided one at a time. If `g` is `R.curryN(3, f)`, the
+ * following are equivalent:
+ *
+ * - `g(1)(2)(3)`
+ * - `g(1)(2, 3)`
+ * - `g(1, 2)(3)`
+ * - `g(1, 2, 3)`
+ *
+ * Secondly, the special placeholder value [`R.__`](#__) may be used to specify
+ * "gaps", allowing partial application of any combination of arguments,
+ * regardless of their positions. If `g` is as above and `_` is [`R.__`](#__),
+ * the following are equivalent:
+ *
+ * - `g(1, 2, 3)`
+ * - `g(_, 2, 3)(1)`
+ * - `g(_, _, 3)(1)(2)`
+ * - `g(_, _, 3)(1, 2)`
+ * - `g(_, 2)(1)(3)`
+ * - `g(_, 2)(1, 3)`
+ * - `g(_, 2)(_, 3)(1)`
+ *
+ * @func
+ * @memberOf fp
+ * @since v0.5.0
+ * @category Function
+ * @sig Number -> (* -> a) -> (* -> a)
+ *
+ * @param {Number} length The arity for the returned function.
+ * @param {Function} fn The function to curry.
+ * @return {Function} A new, curried function.
+ *
+ * @see ramda
+ *
+ * @example
+ *
+ * var sumArgs = (...args) => R.sum(args);
+ *
+ * var curriedAddFourNumbers = R.curryN(4, sumArgs);
+ * var f = curriedAddFourNumbers(1, 2);
+ * var g = f(3);
+ * g(4); //=> 10
+ *
+ */
+ var curry = function curryN(length, fn) {
+ return arity(length, _curryN(length, [], fn))
+ };
+
+ /* ___filename___: dist/deps/is/in.js */
+ /**
+ * @desc prop is in Object(obj)
+ * @since 5.0.0
+ * @memberOf is
+ *
+ * @func
+ * @type {Function}
+ * @name isIn
+ *
+ * @param {Object} obj object to check property of
+ * @param {Primitive} prop property in obj
+ * @return {boolean} property
+ *
+ * @example
+ *
+ * isIn({eh: true}, 'eh') //=> true
+ * isIn({eh: true}, 'oh') //=> false
+ *
+ */
+ var _in = function (obj, prop) { return prop in Object(obj); };
+
+ /* ___filename___: dist/deps/is/in.js */
+
+ /* ___filename___: dist/deps/is/hasIn.js */
+
+
+
+ /**
+ * @desc isIn, but first checks it is not null
+ * @since 5.0.0
+ * @memberOf is
+ *
+ * @param {Object} obj object to check
+ * @param {any} prop property to check in object
+ * @return {boolean}
+ *
+ * @extends isNull
+ * @extends isIn
+ *
+ * @example
+ *
+ * hasIn({}, 'eh') //=> false
+ * hasIn(null, 'eh') //=> false
+ * hasIn({eh: true}, 'eh') //=> true
+ *
+ */
+ var hasIn = function hasIn(obj, prop) {
+ return !_null(obj) && _in(obj, prop)
+ };
+
+ /* ___filename___: dist/deps/fp/curry.js */
+
+ /* ___filename___: dist/deps/is/hasIn.js */
+
+ /* ___filename___: dist/deps/fp/invoke.js */
+ /* eslint consistent-return: "OFF" */
+
+
+
+
+ /**
+ * Creates a function that invokes the method at `path` of a given object.
+ * Any additional arguments are provided to the invoked method.
+ *
+ * @ignore
+ * @private
+ * @name method
+ * @NOTE basically this is `invoke` but not curried
+ *
+ * @since 5.0.0-beta.4
+ * @lodash 3.7.0
+ * @category Util
+ *
+ * @param {Array|string} path The path of the method to invoke.
+ * @param {Array} [args] The arguments to invoke the method with.
+ * @returns {Function} Returns the new invoker function.
+ *
+ * @see https://github.com/lodash/lodash/blob/master/method.js
+ *
+ * @example
+ *
+ * const objects = [
+ * { 'a': { 'b': () => 2 } },
+ * { 'a': { 'b': () => 1 } }
+ * ]
+ *
+ * map(objects, method('a.b'))
+ * // => [2, 1]
+ *
+ * map(objects, method(['a', 'b']))
+ * // => [2, 1]
+ */
+
+ /**
+ * @desc call a method when it exists
+ * @since 5.0.0-beta.4
+ * @memberOf fp
+ * @symb 📞
+ *
+ * @param {*} x object
+ * @param {*} key property with method
+ * @param {*} args arguments
+ * @return {*}
+ *
+ * @TODO add `path` calling, fallback to noop
+ * @see is/hasIn
+ *
+ * {@link http://underscorejs.org/docs/underscore.html#section-33 underscore-invoke}
+ * {@link https://github.com/lodash/lodash/blob/master/invoke.js lodash-invoke}
+ * @see {@link lodash-invoke}
+ * @see {@link underscore-invoke}
+ *
+ * @example
+ *
+ * var obj = {eh: console.log}
+ * invoke(obj, 'eh', 'eh!')
+ * //=> console.log('eh!')
+ *
+ * var getTag = invoke(Object.prototype.toString, 'call')
+ * getTag([])
+ * //=> '[object Array]'
+ *
+ */
+ function _invoke(x, key, args) {
+ if (hasIn(x, key)) { return x[key](args) }
+ // return void 0
+ }
+
+ var invoke = curry(3, _invoke);
+
+ /* ___filename___: dist/deps/native/objectToString.js */
+ var objectToString = Object.prototype.toString;
+
+ /* ___filename___: dist/deps/fp/invoke.js */
+
+ /* ___filename___: dist/deps/native/objectToString.js */
+
+ /* ___filename___: dist/deps/is/toS.js */
+
+
+
+ /**
+ * The base implementation of `getTag` without fallbacks for buggy environments.
+ *
+ * @memberOf is
+ * @since 3.0.0
+ * @alias getTag
+ *
+ * @param {*} obj The value to `Object.prototype.toString.call(obj)`.
+ * @return {string} Returns the `toStringTag`.
+ *
+ * @see https://github.com/lodash/lodash/blob/master/.internal/baseGetTag.js
+ * @see https://github.com/jonschlinkert/kind-of
+ * @see https://github.com/substack/js-traverse/blob/master/index.js#L285
+ * @see http://luxiyalu.com/object-prototype-tostring-call/
+ *
+ * @TODO obj[Symbol.toStringTag]
+ * @TODO run deopt check on this invoking see how many invocations... are needed to inline
+ *
+ * @example
+ *
+ * toS({})
+ * //=> '[object Object]'
+ *
+ * toS(function() {})
+ * //=> '[Object Function]'
+ *
+ * getTag([])
+ * //=> '[object Array]'
+ *
+ */
+ // module.exports = obj => objectToString.call(obj)
+ var toS = invoke(objectToString, 'call');
+
+ /* ___filename___: dist/deps/is/toS.js */
+
+ /* ___filename___: dist/deps/is/map.js */
+
+
+ /**
+ * @desc Checks if `value` is classified as a `Map` object.
+ * @param {*} x value
+ * @return {boolean} isMap
+ *
+ * @since 3.0.0
+ * @memberOf is
+ * @func isMap
+ * @see https://github.com/jonschlinkert/kind-of
+ *
+ * @example
+ *
+ * isMap(new Map())
+ * //=> true
+ * isMap(new Map.entries())
+ * //=> false
+ * isMap(new Set())
+ * //=> false
+ * isMap({})
+ * //=> false
+ * isMap('')
+ * //=> false
+ * isMap(1)
+ * //=> false
+ * isMap(new WeakMap)
+ * // => false
+ *
+ * @example
+ *
+ * const e = {}
+ * eh[Symbol.toStringTag] = '[object Map]'
+ * isMap(eh)
+ *
+ * @example
+ *
+ * class Eh extends Map()
+ * isMap(new Eh())
+ * //=> true
+ *
+ */
+ var map = function isMap(x) {
+ // return x instanceof Map ||
+ return toS(x) === '[object Map]'
+ };
+
+ /* ___filename___: dist/deps/is/set.js */
+
+
+ /**
+ * Checks if `value` is classified as a `Set` object.
+ *
+ * @since 4.3.0
+ * @category Lang
+ * @param {*} x The value to check.
+ * @return {boolean} Returns `true` if `value` is a set, else `false`.
+ *
+ * @example
+ *
+ * isSet(new Set)
+ * // => true
+ *
+ * isSet(new WeakSet)
+ * // => false
+ *
+ */
+ var set = function isSet(x) {
+ return x instanceof Set || toS(x) === '[object Set]'
+ // return toS(x) === '[object Set]'
+ };
+ // x instanceof Set ||
+
+ /* ___filename___: dist/deps/is/function.js */
+ /**
+ * Checks if `value` is classified as a `Function` object.
+ * @category Lang
+ * @memberOf is
+ * @since 3.0.0
+ *
+ * @param {*} x The value to check.
+ * @return {boolean} x isFunction
+ *
+ * @func isFunction
+ *
+ * @NOTE || x instanceof Function
+ *
+ * @polyfill safari=9
+ * The use of `Object#toString` avoids issues with the `typeof` operator
+ * in Safari 9 which returns 'object' for typed arrays and other constructors.
+ * there is no polyfill for this
+ * https://github.com/krambuhl/custom-event-polyfill/issues/2
+ * browser usage is < 0.3%, very edge case
+ *
+ * {@link http://underscorejs.org/docs/underscore.html#section-141 underscore-is-function}
+ * @see {@link underscore-is-function}
+ *
+ * @example
+ *
+ * isFunction(function() {})
+ * //=> true
+ * isFunction(() => {})
+ * //=> true
+ * isFunction(new Function())
+ * //=> true
+ *
+ * isFunction(1)
+ * //=> false
+ * isFunction('')
+ * //=> false
+ * isFunction(/abc/)
+ * // => false
+ *
+ */
+ var _function = function isFunction(x) {
+ return typeof x === 'function'
+ };
+
+ /* ___filename___: dist/deps/is/stringPrimitive.js */
+
+
+ /**
+ * Checks if `value` is classified as a `String` **primitive**.
+ *
+ * @since 3.0.0
+ * @category Lang
+ * @memberOf is
+ * @param {*} x The value to check.
+ * @returns {boolean} Returns `true` if `value` is a string, else `false`.
+ *
+ * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String
+ * @see https://github.com/lodash/lodash/blob/master/isString.js
+ * @see is/string
+ *
+ * @example
+ *
+ * isString('abc')
+ * // => true
+ *
+ * isString(new String('abc'))
+ * // => false
+ *
+ * isString(1)
+ * // => false
+ */
+ var stringPrimitive = function (x) { return typeof x === 'string'; };
+
+ /* ___filename___: dist/deps/is/stringPrimitive.js */
+
+ /* ___filename___: dist/deps/is/string.js */
+
+
+
+ /**
+ * Checks if `value` is classified as a `String` primitive or object.
+ *
+ * @since 3.0.0
+ * @category Lang
+ *
+ * @memberOf is
+ * @extends isStringPrimitive
+ * @variation also allows String objects
+ *
+ * @param {*} x The value to check.
+ * @return {boolean} Returns `true` if `value` is a string, else `false`.
+ *
+ * @see https://github.com/lodash/lodash/blob/master/isString.js
+ * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String
+ * @see isStringPrimitive
+ *
+ * @example
+ *
+ * isString('abc')
+ * // => true
+ *
+ * isString(new String('abc'))
+ * // => true
+ *
+ * isString(1)
+ * // => false
+ */
+ var string = function (x) { return stringPrimitive(x) || toS(x) === '[object String]'; };
+
+ /* ___filename___: dist/deps/is/false.js */
+ /**
+ * @param {*} x value
+ * @return {boolean} isFalse
+ *
+ * @since 4.0.0-alpha.1
+ * @memberOf is
+ * @func isFalse
+ *
+ * @example
+ *
+ * isFalse(false)
+ * //=> true
+ * isFalse(true)
+ * //=> false
+ * isFalse(0)
+ * //=> false
+ * isFalse('')
+ * //=> false
+ *
+ */
+ var _false = function isFalse(x) {
+ return x === false
+ };
+
+ /* ___filename___: dist/deps/util/noop.js */
+ /**
+ * @name noop
+ *
+ * @func
+ * @since 5.0.0
+ * @return {void}
+ *
+ * {@link https://github.com/sindresorhus/noop3 noop3}
+ * @see {@link noop3}
+ *
+ * @example
+ *
+ * noop
+ *
+ * @example
+ *
+ * noop()
+ *
+ */
+ var noop = function noop() { /* noop */ };
+
+ /* ___filename___: dist/deps/util/keys.js */
+ var keys = Object.keys;
+ // function keys(obj) {
+ // var res = []
+ // for (var key in obj)
+ // { res.push(key) }
+ // return res
+
+ /* ___filename___: dist/deps/util/assign.js */
+
+ /* ___filename___: dist/deps/define.js */
+
+
+ /**
+ * @desc default to configurable and enumerable, unless configured otherwise
+ * @since 4.0.0
+ *
+ * @param {Object} obj object to define on
+ * @param {Primitive} name property name to define
+ * @param {Object} descriptor object descriptor
+ * @return {void}
+ *
+ * @tutorial https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty
+ *
+ * @example
+ *
+ * var desc = Object.getOwnPropertyDescriptor(obj, 'eh', {get: () => console.log('eh')})
+ *
+ */
+ var define = function(obj, name, descriptor) {
+ Object.defineProperty(
+ obj,
+ name,
+ assign(
+ {
+ configurable: true,
+ enumerable: true,
+ },
+ descriptor
+ )
+ );
+ };
+
+ /* ___filename___: dist/deps/meta/ignored.js */
+ var ignored = function (key) { return key === 'parent' || key === 'store' || key === 'meta' || key === 'className'; };
+
+ // key === 'decorated' ||
+ // key === 'transformers' ||
+ // key === 'inspect' ||
+
+ /* ___filename___: dist/deps/env/dev.js */
+ /* istanbul ignore next: wip build */
+ var dev = process.env.NODE_ENV !== 'production';
+
+ /* ___filename___: dist/deps/symbols/iterator.js */
+
+ /* ___filename___: dist/deps/symbols/instance.js */
+
+ /* ___filename___: dist/deps/symbols/primitive.js */
+
+ /* ___filename___: dist/deps/is/prototypeOf.js */
+
+ /* ___filename___: dist/deps/is/map.js */
+
+ /* ___filename___: dist/deps/is/set.js */
+
+ /* ___filename___: dist/deps/is/function.js */
+
+ /* ___filename___: dist/deps/is/string.js */
+
+ /* ___filename___: dist/deps/is/false.js */
+
+ /* ___filename___: dist/deps/util/noop.js */
+
+ /* ___filename___: dist/deps/util/keys.js */
+
+ /* ___filename___: dist/deps/define.js */
+
+ /* ___filename___: dist/deps/meta/ignored.js */
+
+ /* ___filename___: dist/deps/env/dev.js */
+
+ /* ___filename___: dist/Chainable.js */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ // @TODO change from `||` to if else
+ var shouldClear = function (key, property) { return !ignored(key) &&
+ (map(property) || set(property) || (property && property.store)); };
+
+ var ComposeChainable = function (Target) {
+ /* istanbul ignore next: dev */
+ if (dev) {
+ if (!Target || !Target.prototype) {
+ console.log({Target: Target});
+ throw new TypeError('did not have a super class / target base')
+ }
+ }
+
+ /**
+ * @desc Trait class that can inherit any class passed into compose, extended by ChainedMap & ChainedSet
+ *
+ * @member Chainable
+ * @class Chainable
+ * @category Chainable
+ * @type {Chainable}
+ *
+ * @prop {Chainable | any} parent
+ * @prop {string} className
+ *
+ * {@link https://github.com/iluwatar/java-design-patterns/tree/master/chain chain-pattern}
+ * @see {@link chain-pattern}
+ *
+ * @see ChainedMap
+ * @see ChainedSet
+ *
+ * @tests Chainable
+ * @types Chainable
+ *
+ */
+ var Chainable = (function (Target) {
+ function Chainable(parent) {
+ Target.call(this);
+ if (parent) { this.parent = parent; }
+ this.className = this.constructor.name;
+ }
+
+ if ( Target ) Chainable.__proto__ = Target;
+ Chainable.prototype = Object.create( Target && Target.prototype );
+ Chainable.prototype.constructor = Chainable;
+
+ /**
+ * @desc Iterator for looping values in the store
+ *
+ * @memberOf Chainable
+ * @since 0.5.0
+ *
+ * @type {generator}
+ * @return {Object} {value: undefined | any, done: true | false}
+ *
+ * @NOTE assigned to a variable so buble ignores it
+ *
+ *
+ * @see https://github.com/sindresorhus/quick-lru/blob/master/index.js
+ * @see https://stackoverflow.com/questions/36976832/what-is-the-meaning-of-symbol-iterator-in-this-context
+ * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/iterator
+ * @see this.store
+ * @tests iteration
+ *
+ * @example
+ *
+ * const chain = new Chain().set('eh', 1)
+ * for (var [key, val] of chain) console.log({[key]: val})
+ * //=> {eh: 1}
+ *
+ * @example
+ *
+ * *[Symbol.iterator](): void { for (const item of this.store) yield item }
+ *
+ * @example
+ *
+ * const {ChainedSet} = require('chain-able')
+ * const set = new ChainedSet()
+ * set.add('eh')
+ *
+ * for (const arr of set) {
+ * const [key, val] = arr
+ *
+ * key
+ * //=> 0
+ *
+ * val
+ * //=> 'eh'
+ *
+ * arr.length
+ * //=> 2
+ * }
+ *
+ */
+ Chainable.prototype[iterator] = function () {
+ var values = this.values();
+ var size = this.store.size;
+ var entries = this.entries ? this.entries() : 0;
+ var keys$$1 = entries === 0 ? new Array(size) : keys(entries);
+
+ return {
+ i: 0,
+ next: function next() {
+ var i = this.i;
+ var key = i;
+ var val = values[i];
+ if (entries) { key = keys$$1[i]; }
+
+ // done - no more values, or iteration reached size
+ if ((_undefined(key) && _undefined(val)) || size <= i) {
+ return {value: undefined, done: true}
+ }
+
+ this.i++;
+
+ // return
+ return {value: [key, val], done: false}
+ },
+ }
+ };
+
+ /**
+ * @desc for ending nested chains
+ * @since 0.4.0
+ * @memberOf Chainable
+ *
+ * @return {Chainable | any}
+ *
+ * @see Chainable.parent
+ * @see FactoryChain
+ *
+ * @example
+ *
+ * const parent = 'eh'
+ * const child = newChain(parent)
+ * child.end()
+ * //=> 'eh'
+ *
+ */
+ Chainable.prototype.end = function end () {
+ return this.parent
+ };
+
+ /**
+ * @desc when the condition is true,
+ * trueBrancher is called,
+ * else, falseBrancher is called
+ *
+ * @memberOf Chainable
+ * @since 4.0.0 <- added string-as-has(condition)
+ * @since 2.0.0
+ *
+ * @param {boolean | string} condition when string, checks this.get
+ * @param {Function} [trueBrancher=Function] called when true
+ * @param {Function} [falseBrancher=Function] called when false
+ * @return {Chainable} @chainable
+ *
+ * @example
+ *
+ *
+ * const prod = process.env.NODE_ENV === 'production'
+ * chains.when(prod, c => c.set('prod', true), c => c.set('prod', false))
+ *
+ *
+ */
+ Chainable.prototype.when = function when (condition, trueBrancher, falseBrancher) {
+ if (condition) {
+ if (_function(trueBrancher)) {
+ if (string(condition)) {
+ if (this.get(condition)) {
+ trueBrancher(this);
+ }
+ }
+ else {
+ trueBrancher(this);
+ }
+ }
+ }
+ else if (_function(falseBrancher)) {
+ falseBrancher(this);
+ }
+
+ return this
+ };
+
+ /**
+ * @desc clears the map,
+ * goes through this properties,
+ * calls .clear if they are instanceof Chainable or Map
+ *
+ * @memberOf Chainable
+ * @since 4.0.0 (moved only to Chainable, added option to clear this keys)
+ * @since 0.4.0 (in ChainedMap)
+ * @since 0.3.0 (in Chainable)
+ *
+ * @param {boolean | undefined} [clearPropertiesThatAreChainLike=true] checks properties on the object, if they are `chain-like`, clears them as well
+ * @return {Chainable} @chainable
+ *
+ * @see https://github.com/fliphub/flipchain/issues/2
+ * @see ChainedSet
+ * @see ChainedMap
+ *
+ * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/clear map-clear}
+ * @see {@link map-clear}
+ *
+ * @example
+ *
+ * const chain = new Chain()
+ * chain.set('eh', 1)
+ * chain.entries()
+ * //=> {eh: 1}
+ * chain.clear()
+ * chain.entries()
+ * //=> {}
+ *
+ */
+ Chainable.prototype.clear = function clear (clearPropertiesThatAreChainLike) {
+ var this$1 = this;
+
+ this.store.clear();
+
+ if (_false(clearPropertiesThatAreChainLike)) { return this }
+
+ var keys$$1 = keys(this);
+ for (var k = 0; k < keys$$1.length; k++) {
+ var key = keys$$1[k];
+ var property = this$1[key];
+ if (shouldClear(key, property)) { this$1[key].clear(); }
+ }
+
+ return this
+ };
+
+ /**
+ * @desc calls .delete on this.store.map
+ * @since 0.3.0
+ * @memberOf Chainable
+ *
+ * @param {Primitive} key on a Map: key referencing the value. on a Set: the index
+ * @return {Chainable}
+ *
+ * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/has
+ * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/has
+ * @see ChainedSet
+ * @see ChainedMap
+ *
+ * @example
+ *
+ * const chain = new Chain()
+ * chain.set('eh', 1)
+ * chain.get('eh')
+ * // => 1
+ * chain.delete('eh', 1)
+ * chain.get('eh')
+ * // => undefined
+ *
+ */
+ Chainable.prototype.delete = function delete$1 (key) {
+ this.store.delete(key);
+ return this
+ };
+
+ /**
+ * @desc checks whether the store has a value for a given key
+ * @memberOf Chainable
+ * @since 0.3.0
+ *
+ * @param {any} keyOrValue key when Map, value when Set
+ * @return {boolean}
+ *
+ * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/has map-has}
+ * @see {@link map-has}
+ *
+ * @example
+ *
+ * const chain = new Chain()
+ * chain.set('eh', 1).has('eh')
+ * //=> true
+ * chain.has('canada')
+ * //=> false
+ *
+ */
+ Chainable.prototype.has = function has (keyOrValue) {
+ return this.store.has(keyOrValue)
+ };
+
+ /**
+ * @desc spreads the entries from ChainedMap.store.values
+ * allocates a new array, adds the values from the iterator
+ *
+ * @memberOf Chainable
+ * @since 0.4.0
+ *
+ * @return {Array} toArr(this.store.values())
+ *
+ * @NOTE look at Chainable.constructor to ensure not to use `new Array...`
+ * @NOTE moved from ChainedMap and ChainedSet to Chainable @2.0.2
+ * @NOTE this was [...] & Array.from(this.store.values())
+ *
+ * {@link https://kangax.github.io/compat-table/es6/#test-Array_static_methods compat-array-static-methods}
+ * {@link https://stackoverflow.com/questions/20069828/how-to-convert-set-to-array set-to-array}
+ * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/values mozilla-map-values}
+ * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/values mozilla-set-values}
+ *
+ * @see {@link mozilla-map-values}
+ * @see {@link mozilla-set-values}
+ * @see {@link compat-array-static-methods}
+ * @see {@link set-to-array}
+ *
+ *
+ * @example
+ *
+ * const chain = new Chain()
+ * chain.set('eh', 1)
+ * chain.values()
+ * //=> [1]
+ *
+ */
+ Chainable.prototype.values = function values () {
+ var allocated = new Array(this.store.size);
+ var i = 0;
+ this.store.forEach(function (v) { return (allocated[i++] = v); });
+ return allocated
+ };
+
+ /**
+ * @desc symbol method for toString, toJSON, toNumber
+ * @memberOf Chainable
+ * @since 1.0.2
+ * @version 2
+ *
+ * @param {string} hint enum[default, string, number]
+ * @return {Primitive}
+ *
+ * {@link http://2ality.com/2015/09/well-known-symbols-es6.html#default-tostring-tags well-known-symbols-es6}
+ * @see {@link well-known-symbols-es6}
+ *
+ * @example
+ *
+ * const chain = new Chain()
+ * chain.toNumber = () => 1
+ * +chain;
+ * //=> 1
+ * chain + 1
+ * //=>
+ *
+ * @example
+ *
+ * const chain = new Chain()
+ * chain.toString = () => 'eh'
+ * chain + ''
+ * //=> 'eh'
+ *
+ */
+ Chainable.prototype[primitive] = function (hint) {
+ /* prettier-ignore */
+ /**
+ * hint === 'number'
+ * `s`tring is 115
+ * `n`umber is 110
+ * 110 & 4 = 1
+ * 115 & 4 = 0
+ *
+ * if (hint === 'string' && this.toJSON) return this.toJSON()
+ * else if (hint === 'number' && this.toNumber) return this.toNumber()
+ */
+ if (hint === 'number' && this.toNumber) { return this.toNumber() }
+
+ // hint === 'string'
+ if (this.toJSON) { return this.toJSON() }
+
+ // hint === 'default'
+ return this.toString()
+ };
+
+ return Chainable;
+ }(Target));
+
+ var ChainPrototype = Chainable.prototype;
+
+ /**
+ * @memberOf Chainable
+ * @name length
+ * @method length
+ * @readonly
+ * @since 0.5.0
+ * @see ChainedMap.store
+ * @return {number}
+ * @example for (var i = 0; i < chain.length; i++)
+ */
+ define(ChainPrototype, 'length', {
+ enumerable: false,
+ get: function get() {
+ return this.store.size
+ },
+ });
+ define(ChainPrototype, instance, {
+ enumerable: false,
+ value: function (instance$$1) { return instance$$1 && (prototypeOf(ChainPrototype, instance$$1) || instance$$1.store); },
+ });
+
+ return Chainable
+ };
+
+ // class {}
+ var c = ComposeChainable(noop);
+
+ /**
+ * @since 3.0.0
+ * @func
+ * @example
+ *
+ * class Target {}
+ * const TargetChain = Chainable.compose(Target)
+ * const chain = new TargetChain()
+ * chain instanceof Target
+ * //=> true
+ *
+ */
+ c.compose = ComposeChainable;
+
+ var Chainable = c;
+
+ /* ___filename___: dist/deps/is/objTypeof.js */
+ /**
+ * @param {*} x value
+ * @return {boolean} isObjLoose
+ *
+ * @since 3.0.0
+ * @memberOf is
+ * @func isObjLoose
+ * @see is/obj
+ * @see is/objWithKeys
+ * @see is/objStrict
+ * @see is/null
+ *
+ * @example
+ *
+ * isObjLoose(new Object())
+ * //=> true
+ * isObjLoose({})
+ * //=> true
+ * isObjLoose(Object.create(null))
+ * //=> true
+ * isObjLoose(null)
+ * //=> true
+ *
+ * isObjLoose(new Set())
+ * //=> false
+ * isObjLoose(function() {})
+ * //=> false
+ * isObjLoose('')
+ * //=> false
+ * isObjLoose(1)
+ * //=> false
+ *
+ */
+ var objTypeof = function (x) { return typeof x === 'object'; };
+
+ /* ___filename___: dist/deps/is/objTypeof.js */
+
+ /* ___filename___: dist/deps/is/objNotNull.js */
+
+
+
+ /**
+ * @param {*} x value
+ * @return {boolean} isObjNotNull
+ *
+ * @since 3.0.0
+ * @memberOf is
+ * @func isObjNotNull
+ * @alias isObjectLike
+ *
+ * {@link https://github.com/lodash/lodash/blob/master/isObjectLike.js lodash-is-object-like}
+ * {@link https://github.com/sindresorhus/is-obj/blob/master/index.js is-obj}
+ * @see is/obj
+ * @see is/objWithKeys
+ * @see is/objTypeof
+ * @see is/null
+ * @see {@link is-obj}
+ * @see {@link lodash-is-object-like}
+ *
+ * @TODO !Array.isArray
+ *
+ * @extends isObjTypeof
+ * @variation null will not count as an object
+ *
+ * @example
+ *
+ * isObjNotNull(new Object())
+ * //=> true
+ * isObjNotNull({})
+ * //=> true
+ * isObjNotNull(Object.create(null))
+ * //=> true
+ * isObjNotNull(null)
+ * //=> false
+ *
+ * isObjNotNull(new Set())
+ * //=> false
+ * isObjNotNull(function() {})
+ * //=> false
+ * isObjNotNull('')
+ * //=> false
+ * isObjNotNull(1)
+ * //=> false
+ *
+ */
+ var objNotNull = function (x) { return !nullOrUndefined(x) && objTypeof(x); };
+
+ /* ___filename___: dist/deps/is/array.js */
+ /**
+ * @name isArray
+ * @func
+ * @memberOf is
+ *
+ * {@link https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray mozilla-isarray}
+ * {@link https://github.com/facebook/immutable-js/blob/master/src/utils/isArrayLike.js immutables-is-array-like}
+ * @todo is-arraylike https://github.com/facebook/immutable-js/blob/master/src/utils/isArrayLike.js
+ *
+ * @param {*} arg
+ * @return {boolean} isArray(arg)
+ *
+ * @see {@link mozilla-isarray}
+ * @type {Function}
+ * @since 3.0.0
+ */
+ var array = Array.isArray;
+
+ // function isArray(xs) {
+ // return Object.prototype.toString.call(xs) === '[object Array]'
+ // }
+
+ /* ___filename___: dist/deps/is/true.js */
+ /**
+ * @param {*} x value
+ * @return {boolean} isTrue
+ *
+ * @since 4.0.0-alpha.1
+ * @memberOf is
+ * @func isTrue
+ *
+ * @example
+ *
+ * isTrue(true)
+ * //=> true
+ * isTrue(false)
+ * //=> false
+ * isTrue(1)
+ * //=> false
+ * isTrue('')
+ * //=> false
+ *
+ */
+ var _true = function (x) { return x === true; };
+
+ /* ___filename___: dist/deps/is/regexp.js */
+
+
+ /**
+ * Checks if `value` is classified as a `RegExp` object.
+ *
+ * @since 0.1.0
+ * @category Lang
+ * @param {*} x The value to check.
+ * @return {boolean} Returns `true` if `value` is a regexp, else `false`.
+ * @see https://github.com/lodash/lodash/blob/master/isRegExp.js
+ *
+ * @example
+ *
+ * isRegExp(/abc/)
+ * // => true
+ *
+ * isRegExp('/abc/')
+ * // => false
+ *
+ */
+ var regexp = function (x) { return toS(x) === '[object RegExp]'; };
+ // obj instanceof RegExp ||
+
+ /* ___filename___: dist/deps/is/date.js */
+
+
+ /**
+ * @param {*} x value
+ * @return {boolean} isDate
+ *
+ * @since 3.0.0
+ * @memberOf is
+ * @func isDate
+ * @extends toS
+ *
+ * @example
+ *
+ * isDate(new Date())
+ * //=> true
+ * isDate(Date.now())
+ * //=> false
+ * isDate(1)
+ * //=> false
+ * isDate('')
+ * //=> false
+ *
+ * @example
+ *
+ * const e = {}
+ * eh[Symbol.toStringTag] = '[Object Date]'
+ * isDate(eh)
+ * //=> true
+ *
+ * @example
+ *
+ * class Eh extends Date()
+ * isDate(new Eh())
+ * //=> true
+ */
+ var date = function isDate(x) {
+ return toS(x) === '[object Date]'
+ // x instanceof Date ||
+ };
+
+ /* ___filename___: dist/deps/is/true.js */
+
+ /* ___filename___: dist/deps/is/booleanPrimitive.js */
+
+
+
+ /**
+ * @desc Checks if `value` is classified as a boolean primitive NOT object.
+ * @category Lang
+ * @since 5.0.0-beta.4
+ *
+ * @param {*} x value
+ * @return {boolean} isBooleanPrimitive
+ *
+ * @extends isTrue
+ * @extends isFalse
+ * @see is/toS
+ * @memberOf is
+ * @func isBooleanPrimitive
+ *
+ * @NOTE could also have typeof x === 'boolean' || (/true|false/).test(x)
+ *
+ * @example
+ *
+ * isBooleanPrimitive(false)
+ * //=> true
+ * isBooleanPrimitive(new Boolean(1))
+ * //=> false
+ *
+ * isBooleanPrimitive(1)
+ * //=> false
+ * isBooleanPrimitive('')
+ * //=> false
+ *
+ */
+ var booleanPrimitive = function isBooleanPrimitive(x) {
+ return _true(x) || _false(x)
+ };
+
+ /* ___filename___: dist/deps/is/booleanPrimitive.js */
+
+ /* ___filename___: dist/deps/is/boolean.js */
+
+
+
+ /**
+ * @desc Checks if `value` is classified as a boolean primitive OR object.
+ * @since 3.0.0
+ * @category Lang
+ * @memberOf is
+ *
+ * @param {*} x value
+ * @return {boolean} isBoolean
+ *
+ * @extends isTrue
+ * @extends isFalse
+ * @extends isBooleanPrimitive
+ *
+ * @see is/toS
+ * @func isBoolean
+ *
+ * @example
+ *
+ * isBoolean(false)
+ * //=> true
+ * isBoolean(new Boolean(1))
+ * //=> true
+ * isBoolean(1)
+ * //=> false
+ * isBoolean('')
+ * //=> false
+ *
+ */
+ var boolean_1 = function isBoolean(x) {
+ return booleanPrimitive(x) || toS(x) === '[object Boolean]'
+ };
+
+ /* ___filename___: dist/deps/is/array.js */
+
+ /* ___filename___: dist/deps/util/simpleKindOf.js */
+
+
+
+ /* prettier-ignore */
+ /**
+ * @desc when Array -> 'array'
+ * when null -> 'null'
+ * else `typeof x`
+ *
+ * @since 4.0.0
+ * @param {any} x value for type
+ * @return {string} type
+ *
+ * split at space, replace brackets and space, lowercase
+ * @TODO `type.split(' ').pop().replace(/\s\[\]/g, '').toLowerCase()`
+ *
+ * @example
+ *
+ * simpleKindOf([]) //=> 'array'
+ * simpleKindOf(null) //=> 'null'
+ * simpleKindOf({}) //=> 'object'
+ *
+ */
+ var simpleKindOf = function (x) {
+ return array(x)
+ ? 'array'
+ : _null(x)
+ ? 'null'
+ : typeof x
+ };
+
+ /* ___filename___: dist/deps/conditional/includes/haystackNeedle.js */
+
+
+ /**
+ * @desc haystack includes needle
+ * @memberOf includes
+ * @version 1.0.0
+ * @since 4.0.0
+ *
+ * @param {Array | string} haystack haystack includes needle
+ * @param {string | *} needle needle in haystack
+ * @return {boolean} needle in haystack
+ *
+ * @name includes
+ * @alias haystackNeedle
+ * @func
+ *
+ * @TODO `~haystack.indexOf(needle)`
+ *
+ * {@link https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#Bitwise_NOT mozilla-bitwise-not}
+ * @see {@link mozilla-bitwise-not}
+ * @see conditional/includes/flipped
+ *
+ * @example
+ *
+ * includes('eh', 'e') //=> true
+ * includes('eh', 'nope') //=> false
+ * includes(['eh'], 'eh') //=> true
+ * includes(['eh'], 'nope') //=> false
+ *
+ */
+ var includes = function (haystack, needle) { return haystack.includes(needle); };
+
+ var haystackNeedle = curry(2, includes);
+
+ /* ___filename___: dist/deps/dopemerge/emptyTarget.js */
+
+
+ /**
+ * @desc make a new empty Array or Object for cloning
+ * @memberOf dopemerge
+ * @name emptyTarget
+ * @since 2.0.0
+ * @func
+ *
+ * @param {*} val array or object to return an empty one of
+ * @return {Object | Array} depending on the data type of val
+ *
+ * @example
+ *
+ * emptyTarget({eh: true})
+ * //=> {}
+ *
+ * emptyTarget([1])
+ * //=> []
+ *
+ */
+ var emptyTarget = function emptyTarget(val) {
+ return array(val) ? [] : {}
+ };
+
+ /* ___filename___: dist/deps/is/objNotNull.js */
+
+ /* ___filename___: dist/deps/is/regexp.js */
+
+ /* ___filename___: dist/deps/is/date.js */
+
+ /* ___filename___: dist/deps/is/boolean.js */
+
+ /* ___filename___: dist/deps/util/simpleKindOf.js */
+
+ /* ___filename___: dist/deps/conditional/includes/haystackNeedle.js */
+
+ /* ___filename___: dist/deps/dopemerge/emptyTarget.js */
+
+ /* ___filename___: dist/deps/dopemerge/dopemerge.js */
+ /* eslint complexity: "OFF" */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ /**
+ * @desc 1: not null object
+ * 2: object toString is not a date or regex
+ *
+ * @category merge
+ * @memberOf dopemerge
+ *
+ * @since 2.0.0
+ * @param {*} x value to check
+ * @return {boolean}
+ *
+ * @example
+ *
+ * isMergeableObj({})
+ * //=> true
+ *
+ * isMergeableObj(Object.create(null))
+ * // => true
+ *
+ * isMergeableObj(new Date())
+ * //=> false
+ *
+ * isMergeableObj(/eh/)
+ * //=> false
+ *
+ */
+ function isMergeableObj(x) {
+ return objNotNull(x) && !regexp(x) && !date(x)
+ }
+
+ /**
+ * Defaults to `false`.
+ * If `clone` is `true` then both `x` and `y` are recursively cloned as part of the merge.
+ *
+ * @memberOf dopemerge
+ * @since 2.0.0
+ *
+ * @param {*} value value to clone if needed
+ * @param {DopeMergeOptions} optsArg dopemerge options, could contain .clone
+ * @return {Object | Array | any} cloned or original value
+ *
+ * @see emptyTarget
+ * @see isMergeableObj
+ *
+ * @example
+ *
+ * var obj = {eh: true}
+ *
+ * cloneIfNeeded(obj, {clone: true}) === obj
+ * //=> false
+ *
+ * cloneIfNeeded(obj, {clone: false}) === obj
+ * //=> true
+ *
+ */
+ function cloneIfNeeded(value, optsArg) {
+ return _true(optsArg.clone) && isMergeableObj(value)
+ ? deepmerge(emptyTarget(value), value, optsArg)
+ : value
+ }
+
+ /* prettier-ignore */
+ /**
+ * The merge will also merge arrays and array values by default.
+ * However, there are nigh-infinite valid ways to merge arrays,
+ * and you may want to supply your own.
+ * You can do this by passing an `arrayMerge` function as an option.
+ *
+ * @memberOf dopemerge
+ * @since 2.0.0
+ *
+ * @param {*} target array merged onto, could be emptyTarget if cloning
+ * @param {*} source original source array
+ * @param {*} optsArg dopemerge options
+ * @return {Array | *} merged array
+ *
+ * @example
+ *
+ * function concatMerge(destinationArray, sourceArray, options) {
+ * destinationArray
+ * //=> [1, 2, 3]
+ *
+ * sourceArray
+ * //=> [3, 2, 1]
+ *
+ * options
+ * //=> { arrayMerge: concatMerge }
+ *
+ * return destinationArray.concat(sourceArray)
+ * }
+ * merge([1, 2, 3], [3, 2, 1], { arrayMerge: concatMerge })
+ * //=> [1, 2, 3, 3, 2, 1]
+ *
+ */
+ function defaultArrayMerge(target, source, optsArg) {
+ var destination = target.slice();
+
+ for (var i = 0; i < source.length; i++) {
+ var v = source[i];
+
+ if (_undefined(destination[i])) {
+ destination[i] = cloneIfNeeded(v, optsArg);
+ }
+ else if (isMergeableObj(v)) {
+ destination[i] = deepmerge(target[i], v, optsArg);
+ }
+ // @see https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#Bitwise_NOT
+ // === -1
+ // eslint-disable-next-line prefer-includes/prefer-includes
+ else if (!~target.indexOf(v)) {
+ destination.push(cloneIfNeeded(v, optsArg));
+ }
+ }
+
+ return destination
+ }
+
+ function mergeObj(target, source, optsArg) {
+ var destination = {};
+ if (isMergeableObj(target)) {
+ var targetKeys = keys(target);
+ for (var k = 0; k < targetKeys.length; k++) {
+ destination[targetKeys[k]] = cloneIfNeeded(target[targetKeys[k]], optsArg);
+ }
+ }
+
+ var sourceKeys = keys(source);
+ for (var s = 0; s < sourceKeys.length; s++) {
+ var key = sourceKeys[s];
+ if (!isMergeableObj(source[key]) || !target[key]) {
+ destination[key] = cloneIfNeeded(source[key], optsArg);
+ }
+ else {
+ destination[key] = deepmerge(target[key], source[key], optsArg);
+ }
+ }
+
+ return destination
+ }
+
+ function deepmerge(target, source, optsArg) {
+ if (array(source)) {
+ var arrayMerge = optsArg.arrayMerge;
+ return array(target)
+ ? arrayMerge(target, source, optsArg)
+ : cloneIfNeeded(source, optsArg)
+ }
+
+ // else
+ return mergeObj(target, source, optsArg)
+ }
+
+ /* prettier-ignore */
+ /**
+ * Merge the enumerable attributes of two objects deeply.
+ * Merge two objects `x` and `y` deeply, returning a new merged object with the
+ * elements from both `x` and `y`.
+ * If an element at the same key is present for both `x` and `y`, the value from
+ * `y` will appear in the result.
+ * Merging creates a new object, so that neither `x` or `y` are be modified.
+ * However, child objects on `x` or `y` are copied over -
+ * if you want to copy all values, you must pass `true` to the clone option.
+ *
+ *
+ * @member dopemerge
+ * @category merge
+ *
+ * @param {*} obj1 left
+ * @param {*} obj2 right
+ * @param {*} opts dopemerge options
+ * @return {Object | Array | any} merged
+ *
+ * {@link https://github.com/facebook/immutable-js/blob/master/src/Map.js#L145 immutable-js-merge}
+ * {@link https://github.com/ramda/ramda/blob/master/src/merge.js ramda-merge}
+ * {@link https://github.com/lodash/lodash/blob/master/merge.js lodash-merge}
+ * {@link https://github.com/KyleAMathews/deepmerge deepmerge}
+ * @see {@link deepmerge}
+ *
+ * @types dopemerge
+ * @tests deepmerge
+ *
+ * @example
+ *
+ * var x = {
+ * foo: {bar: 3},
+ * array: [{
+ * does: 'work',
+ * too: [1, 2, 3],
+ * }],
+ * }
+ *
+ * var y = {
+ * foo: {baz: 4},
+ * quux: 5,
+ * array: [
+ * {
+ * does: 'work',
+ * too: [4, 5, 6],
+ * },
+ * {
+ * really: 'yes',
+ * },
+ * ],
+ * }
+ *
+ * var expected = {
+ * foo: {
+ * bar: 3,
+ * baz: 4,
+ * },
+ * array: [
+ * {
+ * does: 'work',
+ * too: [1, 2, 3, 4, 5, 6],
+ * },
+ * {
+ * really: 'yes',
+ * },
+ * ],
+ * quux: 5,
+ * }
+ *
+ * merge(x, y)
+ * //=> expected
+ *
+ */
+ function dopemerge(obj1, obj2, opts) {
+ // if they are identical, fastest === check
+ if (obj1 === obj2) {
+ return obj1
+ }
+
+ // setup options
+ var options = assign(
+ {
+ arrayMerge: defaultArrayMerge,
+ stringToArray: true,
+ boolToArray: false,
+ ignoreTypes: ['null', 'undefined'],
+ // debug: true,
+ },
+ opts
+ // || {}
+ );
+ var ignoreTypes = options.ignoreTypes;
+ var stringToArray = options.stringToArray;
+ var boolToArray = options.boolToArray;
+ var clone = options.clone;
+
+ // @NOTE: much better size but oh well
+ // const ignoreTypes = ['null', 'undefined']
+ // const stringToArray = true
+ // const boolToArray = false
+ // const clone = true
+
+ // @NOTE uglifier optimizes into a wicked ternary
+ // check one then check the other
+ if (_true(haystackNeedle(ignoreTypes, simpleKindOf(obj1)))) {
+ return obj2
+ }
+ else if (_true(haystackNeedle(ignoreTypes, simpleKindOf(obj2)))) {
+ return obj1
+ }
+ else if (boolean_1(obj1) && boolean_1(obj2)) {
+ return boolToArray ? [obj1, obj2] : obj2
+ }
+ else if (string(obj1) && string(obj2)) {
+ return stringToArray ? [obj1, obj2] : obj1 + obj2
+ }
+ else if (array(obj1) && string(obj2)) {
+ return (clone ? obj1.slice(0) : obj1).concat([obj2])
+ }
+ else if (string(obj1) && array(obj2)) {
+ return (clone ? obj2.slice(0) : obj2).concat([obj1])
+ }
+ else {
+ return deepmerge(obj1, obj2, options)
+ }
+ }
+
+ var dopemerge_1 = dopemerge;
+
+ /* ___filename___: dist/deps/dopemerge/dopemerge.js */
+
+ var index$2 = dopemerge_1;
+
+ /* ___filename___: dist/deps/util/from.js */
+ /**
+ * @tutorial https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/from
+ * @see https://github.com/lodash/lodash/blob/master/.internal/setToArray.js
+ * ^ could use if needed
+ */
+ var from = Array.from;
+
+ /* ___filename___: dist/deps/util/from.js */
+
+ /* ___filename___: dist/deps/reduce/reduce.js */
+
+
+ /**
+ * @desc Map -> Object
+ * @since 4.0.0
+ *
+ * @param {Map} map map to reduce, calls entries, turns into an array, then object
+ * @return {Object} reduced object
+ *
+ * @see ArrayFrom
+ *
+ * @example
+ *
+ * var emptyMap = new Map()
+ * reduce(emptyMap)
+ * // => {}
+ *
+ * @example
+ *
+ * var map = new Map()
+ * map.set('eh', 1)
+ * reduce(map)
+ * // => {eh: 1}
+ *
+ */
+ var reduce = function (map) {
+ var reduced = {};
+
+ // only need to do this if we actually have values in our Map
+ if (map.size !== 0) {
+ reduced = from(map.entries()).reduce(function (acc, ref) {
+ var key = ref[0];
+ var value = ref[1];
+
+ acc[key] = value;
+ return acc
+ }, reduced);
+ }
+
+ return reduced
+ };
+
+ /* ___filename___: dist/deps/reduce/reduce.js */
+
+ var index$4 = reduce;
+
+ /* ___filename___: dist/deps/is/obj.js */
+
+
+
+
+ /**
+ * @func isObj
+ *
+ * Checks if `value` is the
+ * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
+ * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
+ *
+ * @since 3.0.0
+ * @category Lang
+ *
+ * @param {*} value The value to check.
+ * @return {boolean} Returns `true` if `value` is an object, else `false`.
+ *
+ * @memberOf is
+ * @see http://stackoverflow.com/questions/34111902/why-do-lodashs-isobject-isplainobject-behave-differently-than-typeof-x
+ * @see https://github.com/lodash/lodash/blob/master/isObject.js
+ * @NOTE Object.prototype.toString.call(val) === '[object Object]'
+ *
+ * @example
+ *
+ * isObject({})
+ * // => true
+ *
+ * isObject([1, 2, 3])
+ * // => true
+ *
+ * isObject(Function)
+ * // => true
+ *
+ * isObject(null)
+ * // => false
+ *
+ */
+ var obj = function (x) { return !_null(x) && (objTypeof(x) || _function(x)); };
+
+ /* ___filename___: dist/deps/is/obj.js */
+
+ /* ___filename___: dist/deps/reduce/entries.js */
+
+
+
+
+
+
+ /**
+ * @desc recursively reduce maps and objects that include reducable data
+ * @since 4.0.0
+ *
+ * @sig reduced => object => isMap(object) -> reduced; merge(object, reduced)
+ *
+ * @param {Object | any} reduced merged object and reduced
+ * @return {Function} Function(values: Object)
+ *
+ * @see https://www.airpair.com/javascript/javascript-array-reduce
+ * @see ChainedMap
+ * @NOTE could curry, but this is super hot function
+ *
+ * @example
+ *
+ * const map = new Map()
+ * map.set('eh', true)
+ * const nested = new Map()
+ * nested.set('reduced', true)
+ *
+ * const chain = {
+ * entries() {
+ * return {
+ * nested: reduce(nested),
+ * key: true,
+ * }
+ * },
+ * }
+ * const reduced = reduce(map)
+ * reduceEntries(reduced)({chain})
+ * // => {
+ * eh: true,
+ * chain: {
+ * nested: {
+ * reduced: true,
+ * key: true,
+ * },
+ * },
+ * }
+ *
+ * @example
+ *
+ * const reducedIgnored = {
+ * canada: {
+ * store: chain,
+ * },
+ * }
+ * const ignored = reduceEntries(reduced)(reducedIgnored)
+ * //=> {
+ * eh: true,
+ * chain: {
+ * nested: {
+ * reduced: true,
+ * },
+ * key: true,
+ * },
+ * }
+ *
+ */
+ var entries = function (reduced) { return function (obj$$1) {
+ var keys$$2 = keys(obj$$1);
+
+ for (var k = 0; k < keys$$2.length; k++) {
+ var key = keys$$2[k];
+
+ if (ignored(key)) {
+ continue
+ }
+
+ var value = obj$$1[key];
+ // @NOTE could use hasInMatching here
+ if (obj(value) && _function(value.entries)) {
+ assign(reduced, {[key]: value.entries(true) || {}});
+ }
+ }
+
+ return reduced
+ }; };
+
+ /* ___filename___: dist/deps/is/iterator.js */
+
+
+ /**
+ * @param {*} x value
+ * @return {boolean} isIterator
+ *
+ * @since 3.0.0
+ * @memberOf is
+ * @func isIterator
+ * @see https://github.com/jonschlinkert/kind-of/pull/12
+ *
+ * @example
+ *
+ * isIterator(new Set().values())
+ * //=> true
+ * isIterator(new Map.entries())
+ * //=> true
+ * isIterator(new Map())
+ * //=> false
+ * isIterator('')
+ * //=> false
+ * isIterator(1)
+ * //=> false
+ *
+ * @example
+ *
+ * const e = {}
+ * eh[Symbol.toStringTag] = '[Map Iterator]'
+ * isIterator(eh)
+ * //=> true
+ * eh[Symbol.toStringTag] = '[Set Iterator]'
+ * isIterator(eh)
+ * //=> true
+ *
+ * @example
+ *
+ * class Eh extends Set()
+ * isIterator(new Eh().values())
+ * //=> true
+ *
+ */
+ // eslint-disable-next-line
+ var iterator$2 = function (x) { return ~toS(x).indexOf('Iterator'); };
+
+ /* ___filename___: dist/deps/is/iterator.js */
+
+ /* ___filename___: dist/deps/to-arr.js */
+
+
+
+
+
+
+
+ /**
+ * @desc anything into an array
+ * @sig * => Array
+ * @since 0.0.1
+ *
+ * @param {any} ar turn this into an array
+ * @return {Array} anything into an array
+ *
+ * @tests deps/to-arr
+ * @types deps
+ *
+ * @example
+ *
+ * toarr([])
+ * // => []
+ *
+ * toarr('')
+ * // => ['']
+ *
+ * toarr('1,2')
+ * // => ['1', '2']
+ *
+ * toarr('1,2')
+ * // => ['1', '2']
+ *
+ * const map = new Map()
+ * map.set('eh', true)
+ * const arr = toarr(map.entries())
+ * // => ['eh', true]
+ *
+ * const set = new Set()
+ * set.add('eh')
+ * set.add(true)
+ * const arr = toarr(map.entries())
+ * // => ['eh', true]
+ *
+ * toarr('').concat(toarr(false)).concat(toarr(null))
+ * // => ['', false, null]
+ *
+ */
+ var toArr = function(ar) {
+ // @NOTE: !'' === true
+ if (stringPrimitive(ar)) { return ar.includes(',') ? ar.split(',') : [ar] }
+ else if (!ar) { return [ar] }
+ else if (array(ar)) { return ar }
+ else if (set(ar) || map(ar) || ar.values) {
+ /**
+ * @desc when using `new Set().values`... no forEach o.o
+ * .values is also on `Object`...
+ */
+ return from(ar.values(ar))
+ }
+ else if (iterator$2(ar)) { return from(ar) }
+ else { return [ar] }
+ };
+
+ /* ___filename___: dist/deps/to-arr.js */
+
+ /* ___filename___: dist/deps/array/concat.js */
+
+
+ /**
+ * @desc concat two values, coerce to arrays
+ * @since 4.0.0
+ * @memberOf array
+ *
+ * @param {Array | *} one toArr1
+ * @param {Array | *} two toArr2
+ * @return {Array} [one, two]
+ *
+ * @see deps/to-arr
+ * @func
+ * @name concat
+ *
+ * @example
+ *
+ * concat([1], [2]) //=> [1, 2]
+ * concat([1], 2) //=> [1, 2]
+ * concat(1, 2) //=> [1, 2]
+ * concat(new Set([1]), 2) //=> [1, 2]
+ *
+ * // kind of weird...
+ * concat(null, 2) //=> [2]
+ * concat(undefined, 2) //=> [2]
+ * concat(1, null) //=> [1, null]
+ *
+ */
+ var concat = function (one, two) { return toArr(one || []).concat(toArr(two)); };
+
+ /* ___filename___: dist/deps/fp/always.js */
+ /**
+ * Returns a function that always returns the given value. Note that for
+ * non-primitives the value returned is a reference to the original value.
+ *
+ * This function is known as `const`, `constant`, or `K` (for K combinator) in
+ * other languages and libraries.
+ *
+ * @alias always
+ * @alias constant
+ * @func
+ * @memberOf fp
+ * @since v5.0.0
+ * @category Function
+ * @sig a -> (* -> a)
+ *
+ * @param {*} value The value to wrap in a function
+ * @return {Function} A Function :: * -> val.
+ *
+ * {@link http://underscorejs.org/#constant underscore-constant}
+ * {@link https://github.com/lodash/lodash/issues/1010 lodash-constant}
+ * {@link https://github.com/ramda/ramda/issues/1038 ramda-constant-docs-issue}
+ * {@link https://github.com/ramda/ramda/blob/master/src/always.js ramda-always}
+ * @see {@link ramda-constant-docs-issue}
+ * @see {@link ramda-always}
+ * @see {@link lodash-constant}
+ * @see {@link underscore-constant}
+ *
+ * @types fp
+ * @tests fp/always
+ *
+ * @example
+ *
+ * var t = always('Tee');
+ * t(); //=> 'Tee'
+ *
+ */
+
+ /* ___filename___: dist/deps/meta/transformers.js */
+ /* istanbul ignore next: wip build */
+ var transformers = process.env.NODE_ENV === 'production'
+ ? 'transformers'
+ : 'transformers';
+
+ /* ___filename___: dist/deps/meta/observers.js */
+ /* istanbul ignore next: wip build */
+ var observers = process.env.NODE_ENV === 'production'
+ ? 'observers'
+ : 'observers';
+
+ /* ___filename___: dist/deps/meta/shorthands.js */
+ /* istanbul ignore next: wip build */
+ var shorthands = process.env.NODE_ENV === 'production'
+ ? 'shorthands'
+ : 'shorthands';
+
+ /* ___filename___: dist/deps/meta/decorated.js */
+ /* istanbul ignore next: wip build */
+ var decorated = process.env.NODE_ENV === 'production'
+ ? 'decorated'
+ : 'decorated';
+
+ /* ___filename___: dist/deps/array/concat.js */
+
+ /* ___filename___: dist/deps/fp/always.js */
+
+ /* ___filename___: dist/deps/meta/transformers.js */
+
+ /* ___filename___: dist/deps/meta/observers.js */
+
+ /* ___filename___: dist/deps/meta/shorthands.js */
+
+ /* ___filename___: dist/deps/meta/decorated.js */
+
+ /* ___filename___: dist/deps/meta/meta.js */
+ // without it, the arguments & caller are uglier when drbugging
+
+
+
+
+
+
+
+
+
+
+
+
+
+ // will expand this later
+ var isInKeyMapAsSet = function (x) { return x === observers; };
+ var emptyArray = []; // always([])
+
+ // @NOTE: using `[]` deopts o.o
+ // eslint-disable-next-line
+ // this.shorthands = new Array()
+
+ /**
+ * @since 4.0.0
+ * @param {Chain} _this
+ * @return {Chain}
+ */
+ function getMeta(_this) {
+ // if we already have it, keep it
+ if (_this.meta) { return _this.meta }
+
+ // the store
+ // shorthands: key -> method
+ var store = {};
+
+ // --- uglifiable functions
+
+ /** @desc initialize the store maps when we need them */
+ /* prettier-ignore */
+ var ensureInitialized = function (name, value) {
+ if (!_undefined(store[name])) { return }
+
+ // if (
+ // name === TRANSFORMERS_KEY ||
+ // name === SHORTHANDS_KEY ||
+ // name === DECORATED_KEY
+ // ) {
+ // store[name] = new Map()
+ // }
+ // else
+ if (isInKeyMapAsSet(name)) {
+ store[name] = new Set();
+ }
+ else {
+ store[name] = new Map();
+ }
+ };
+
+ /**
+ * @since 4.0.0
+ * @param {Primitive} key
+ * @param {Primitive | undefined} [prop=undefined]
+ * @return {boolean}
+ */
+ var has = function (key, prop) {
+ if (_undefined(prop)) { return !!store[key].size }
+ else { return store[key].has(prop) }
+ };
+ /**
+ * @since 4.0.0
+ * @param {Primitive} key
+ * @param {Primitive | undefined} [prop=undefined]
+ * @return {any}
+ */
+ var get = function (key, prop) { return (has(key, prop) ? store[key].get(prop) : emptyArray); };
+
+ /**
+ * @since 4.0.0
+ * @param {Primitive} key
+ * @param {Primitive | undefined} [prop=undefined]
+ * @param {Primitive | undefined} [value=undefined]
+ * @return {void}
+ */
+ var set$$2 = function (key, prop, value) {
+ var storage = store[key];
+ // when it's a set, we have no `prop`, we just have .add
+ // so `prop = value` && `value = undefined`
+ if (set(storage)) {
+ storage.add(prop);
+ }
+ else {
+ // if (!has(key, prop)) return
+ var existing = storage.get(prop);
+ var val = concat(existing, value);
+ storage.set(prop, val);
+ }
+ };
+
+ /**
+ * @since 4.0.0
+ *
+ * @desc a single easily minifiable function,
+ * dynamically setting & getting depending on arguments
+ * to avoid nested property accessing
+ * only instantiating when values are **addded**
+ *
+ * @param {Primitive} key
+ * @param {Primitive | undefined} [prop=undefined]
+ * @param {undefined | any} [value=undefined] (when no value, it's a getter)
+ * @return {Array | Chain} depending on args
+ */
+ function meta(key, prop, value) {
+ if (process.env.NODE_ENV === 'DEBUG') {
+ console.log('USING META', {key: key, prop: prop, value: value});
+ }
+
+ /* prettier-ignore */
+ if (_undefined(value)) {
+ // when we want to just access the property, return an array
+ // @example `.meta('transformers')`
+ if (_undefined(prop)) {
+ if (_undefined(store[key])) { return emptyArray }
+ else { return store[key].size === 0 ? emptyArray : from(store[key].values()) }
+ }
+ // we have `key, prop`
+ //
+ // 1: should `prop` be a value, (isSet?)
+ else if (isInKeyMapAsSet(key)) {
+ ensureInitialized(key);
+ set$$2(key, prop);
+ }
+ // 2: prop is a key, we want to return the [..] for that specific property
+ // @example `.meta('transformers', 'eh')`
+ else if (_undefined(store[key])) { return emptyArray }
+ else { return toArr(get(key, prop)) }
+ }
+ // we have `key, prop, value`
+ else {
+ ensureInitialized(key);
+ // we have a value, let's add it
+ set$$2(key, prop, value);
+ }
+ return _this
+ }
+
+ // for debugging
+ meta.store = store;
+ // meta.debug = false
+
+ return meta
+ }
+
+ var meta = getMeta;
+
+ /* ___filename___: dist/deps/meta/meta.js */
+
+ var index$6 = meta;
+
+ /* ___filename___: dist/Chainable.js */
+
+ /* ___filename___: dist/deps/reduce/entries.js */
+
+ /* ___filename___: dist/ChainedMapBase.js */
+
+
+
+
+
+
+
+
+
+
+ /**
+ * this is to avoid circular requires
+ * because MergeChain & MethodChain extend this
+ * yet .method & .merge use those chains
+ * ...also, it serves as a non-references creator for extending new instances
+ * of Chainable, where it splits into (Map | Set) -> composed prototype decorators
+ *
+ *
+ * @file
+ * @since 4.0.0-alpha.1
+ * @inheritdoc
+ * @class ChainedMapBase
+ * @member ChainedMapBase
+ * @category Chainable
+ * @extends {Chainable}
+ * @type {Chainable}
+ *
+ * @types ChainedMapBase
+ * @tests ChainedMap
+ *
+ * @prop {Meta} meta meta fn
+ * @prop {Map} store main store
+ *
+ * {@link https://tc39.github.io/ecma262/#sec-map-objects emca-map}
+ * {@link https://ponyfoo.com/articles/es6-maps-in-depth pony-map}
+ * {@link https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Map mozilla-map}
+ * @see {@link pony-map}
+ * @see {@link mozilla-map}
+ * @see {@link emca-map}
+ *
+ * @see ChainedMap
+ * @see Chainable
+ * @see MergeChain
+ * @see MethodChain
+ * @see ChainedMap
+ *
+ */
+
+ var ComposeChainedMapBase = function (Target) {
+ return (function (Target) {
+ function ChainedMapBase(parent) {
+ Target.call(this, parent);
+
+ this.store = new Map();
+ this.meta = index$6(this);
+ }
+
+ if ( Target ) ChainedMapBase.__proto__ = Target;
+ ChainedMapBase.prototype = Object.create( Target && Target.prototype );
+ ChainedMapBase.prototype.constructor = ChainedMapBase;
+
+ /**
+ * @desc tap a value with a function
+ * @modifies this.store.get(name)
+ * @memberOf ChainedMapBase
+ * @version 0.7.0
+ * @since 4.0.0-alpha.1 <- moved from transform & shorthands
+ *
+ * @param {string | any} name key to `.get`
+ * @param {Function} fn function to tap with
+ * @return {Chain} @chainable
+ *
+ * {@link https://github.com/sindresorhus/awesome-tap awesome-tap}
+ * {@link https://github.com/midknight41/map-factory map-factory}
+ * {@link https://github.com/webpack/tapable tapable}
+ * @see {@link tapable}
+ *
+ * @see ChainedMapBase.set
+ * @see ChainedMapBase.get
+ *
+ * @example
+ *
+ * chain
+ * .set('moose', {eh: true})
+ * .tap('moose', moose => {moose.eh = false; return moose})
+ * .get('moose')
+ *
+ * // => {eh: false}
+ *
+ * @example
+ *
+ * const entries = new Chain()
+ * .set('str', 'emptyish')
+ * .tap('str', str => str + '+')
+ * .set('arr', [1])
+ * .tap('arr', arr => arr.concat([2]))
+ * .entries()
+ *
+ * //=> {str: 'emptyish+', arr: [1, 2]}
+ *
+ */
+ ChainedMapBase.prototype.tap = function tap (name, fn) {
+ return this.set(name, fn(this.get(name), index$2))
+ };
+
+ /**
+ * @desc checks each property of the object
+ * calls the chains accordingly
+ *
+ * @memberOf ChainedMapBase
+ * @since 0.5.0
+ *
+ * @param {Object} obj object with functions to hydrate from
+ * @return {Chainable} @chainable
+ *
+ * @TODO could also add parsing stringified
+ *
+ * @example
+ *
+ * const from = new Chain().from({eh: true})
+ * const eh = new Chain().set('eh', true)
+ * eq(from, eh)
+ * // => true
+ *
+ */
+ ChainedMapBase.prototype.from = function from (obj) {
+ var this$1 = this;
+
+ var keys$$1 = keys(obj);
+
+ for (var k = 0; k < keys$$1.length; k++) {
+ var key = keys$$1[k];
+ var value = obj[key];
+ var fn = this$1[key];
+
+ if (fn && fn.merge) {
+ fn.merge(value);
+ }
+ else if (_function(fn)) {
+ fn.call(this$1, value);
+ }
+ else {
+ this$1.set(key, value);
+ }
+ }
+
+ return this
+ };
+
+ /**
+ * @desc shorthand methods, from strings to functions that call .set
+ * @since 0.4.0
+ * @memberOf ChainedMapBase
+ *
+ * @param {Array} methods decorates/extends an object with new shorthand functions to get/set
+ * @return {ChainedMapBase} @chainable
+ *
+ * @example
+ *
+ * const chain1 = new Chain()
+ * chain1.extend(['eh'])
+ *
+ * const chain2 = new Chain()
+ * chain2.eh = val => this.set('eh', val)
+ *
+ * eq(chain2.eh, chain1.eh)
+ * //=> true
+ *
+ */
+ ChainedMapBase.prototype.extend = function extend (methods) {
+ var this$1 = this;
+
+ methods.forEach(function (method) {
+ this$1.meta(shorthands, method);
+ this$1[method] = function (value) { return this$1.set(method, value); };
+ });
+ return this
+ };
+
+ /**
+ * @desc spreads the entries from ChainedMapBase.store (Map)
+ * return store.entries, plus all chain properties if they exist
+ *
+ * @memberOf ChainedMapBase
+ * @version 4.0.0 <- improved reducing
+ * @since 0.4.0
+ *
+ * @param {boolean} [chains=false] if true, returns all properties that are chains
+ * @return {Object} reduced object containing all properties from the store, and when `chains` is true, all instance properties, and recursive chains
+ *
+ * //
+ *
+ * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/entries mozilla-map-entries}
+ * @see {@link mozilla-map-entries}
+ *
+ * @example
+ *
+ * map.set('a', 'alpha').set('b', 'beta').entries()
+ * //=> {a: 'alpha', b: 'beta'}
+ *
+ */
+ ChainedMapBase.prototype.entries = function entries$$1 (chains) {
+ var reduced = index$4(this.store);
+ if (_undefined(chains)) { return reduced }
+
+ var reducer = entries(reduced);
+ reducer(this);
+ reducer(reduced);
+ return reduced
+ };
+
+ /**
+ * @desc get value for key path in the Map store
+ * ❗ `debug` is a special key and is *not* included into .store
+ * it goes onto .meta
+ *
+ * @memberOf ChainedMapBase
+ * @version 4.0.0 <- moved debug here
+ * @since 0.4.0
+ *
+ * @param {Primitive} key Primitive data key used as map property to reference the value
+ * @return {any} value in .store at key
+ *
+ * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/get mozilla-map-get}
+ * @see {@link mozilla-map-get}
+ *
+ * @example
+ *
+ * const chain = new Chain()
+ * chain.set('eh', true)
+ * chain.get('eh')
+ * //=> true
+ *
+ * chain.get('nope')
+ * //=> undefined
+ *
+ */
+ ChainedMapBase.prototype.get = function get (key) {
+ if (key === 'debug') { return this.meta.debug }
+ return this.store.get(key)
+ };
+
+ /**
+ * @desc sets the value using the key on store
+ * adds or updates an element with a specified key and value
+ *
+ * @memberOf ChainedMapBase
+ * @since 0.4.0
+ *
+ * @param {Primitive} key Primitive to reference the value
+ * @param {any} value any data to store
+ * @return {ChainedMapBase} @chainable
+ *
+ * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/set mozilla-map-set}
+ *
+ * @see {@link mozilla-map-set}
+ * @see ChainedMapBase.store
+ *
+ * @example
+ *
+ * const chain = new Chain()
+ * chain.set('eh', true)
+ * chain.get('eh')
+ * //=> true
+ *
+ */
+ ChainedMapBase.prototype.set = function set (key, value) {
+ this.store.set(key, value);
+ return this
+ };
+
+ return ChainedMapBase;
+ }(Target))
+ };
+
+ /**
+ * @desc ChainedMapBase composer
+ * @alias ComposeMap
+ * @type {Composer}
+ * @method compose
+ * @memberOf ChainedMapBase
+ *
+ * @param {Class | Object | Composable} [Target=Chainable] class to extend
+ * @return {Class} ChainedMapBase
+ *
+ * @example
+ *
+ * const heh = class {}
+ * const composed = ChainedMapBase.compose(heh)
+ * const hehchain = new Composed()
+ * hehchain instanceof heh
+ * //=> true
+ *
+ */
+ var cmc = ComposeChainedMapBase(Chainable);
+ cmc.compose = ComposeChainedMapBase;
+
+ var ChainedMapBase = cmc;
+
+ /* ___filename___: dist/deps/env/debug.js */
+ var debug = process.env.NODE_ENV === 'debug'; // || process.env.DEBUG = true
+
+ /* ___filename___: dist/deps/util/lengthFromZero.js */
+ /**
+ * when length > 1, use length-1
+ * otherwise, when length == 1, use 0
+ * default, use length
+ *
+ * @memberOf util
+ * @since 5.0.0-beta.2
+ * @name lengthFromZero
+ *
+ * @TODO lense to use an object, or transform it to one with .length?
+ * const len = prop('length')
+ * // when isObj, use len, otherwise, value
+ * const coerceLength = lense([isObj, len])
+ *
+ * @param {Array | Object | number} obj with length
+ * @return {number} obj length from 0
+ *
+ * @see util/length
+ * @see util/lengthMinusOne
+ *
+ * @example
+ *
+ * lengthFromZero([1]) //=> 1
+ * lengthFromZero([]) //=> 0
+ * lengthFromZero([1, 2, 3]) //=> 2
+ *
+ */
+ var lengthFromZero = function (obj) { return (obj.length > 1 ? obj.length - 1 : obj.length === 1 ? 1 : 0); };
+
+ /* ___filename___: dist/deps/util/lengthFromZero.js */
+
+ /* ___filename___: dist/deps/argumentor.js */
+
+
+ /**
+ * @desc turns arguments into an array, used as a util, for opt
+ *
+ * @name argumentor
+ * @since 3.0.0
+ * @return {Array}
+ *
+ * @see https://github.com/aretecode/awesome-deopt
+ * @see https://github.com/petkaantonov/bluebird/wiki/Optimization-killers
+ * @see deps/util/lengthFromZero
+ *
+ * @example
+ *
+ * function eh() {
+ * const args = argumentor.apply(null, arguments).slice(1)
+ *
+ * console.log(args)
+ * //=> [1, 10, 100]
+ * }
+ * eh(0, 1, 10, 100)
+ *
+ */
+ var argumentor = function() {
+ var arguments$1 = arguments;
+
+ var len = arguments.length;
+ // len > 1 ? len - 1 : 0
+ var args = new Array(lengthFromZero(len));
+ for (var i = 0; i < len; ++i) { args[i] = arguments$1[i]; }
+ return args
+ };
+
+ /* ___filename___: dist/deps/argumentor.js */
+
+ /* ___filename___: dist/deps/fp/flip2.js */
+
+
+
+ /**
+ * Returns a new function much like the supplied one, except that the first two
+ * arguments' order is reversed.
+ *
+ * @memberOf fp
+ * @symb 🙃🙃
+ * @since 5.0.0-beta.4
+ *
+ * @param {Function} fn The function to invoke with its first two parameters reversed.
+ * @return {*} The result of invoking `fn` with its first two parameters' order reversed.
+ *
+ * @extends fp/flip
+ * @variation just flip, but flips arg 1-2 instead of reversing all arguments
+ * @see fp/flip
+ * @TODO flipN
+ *
+ * @types fp
+ * @tests fp/flip2
+ *
+ * @example
+ *
+ * var mergeThree = (a, b, c) => [].concat(a, b, c)
+ * mergeThree(1, 2, 3); //=> [1, 2, 3]
+ * flip(mergeThree)(1, 2, 3); //=> [2, 1, 3]
+ *
+ * const flipped = flip((...args) => args)
+ * flipped('a', 'b', 'c', 'd')
+ * // => ['b', 'a', 'c', 'd']
+ *
+ */
+ var flip2 = function flip2(fn) {
+ return curry(2, function(a, b) {
+ var args = argumentor.apply(null, arguments);
+ // .slice(n).reverse().splice()
+ args[0] = b;
+ args[1] = a;
+ return fn.apply(this, args)
+ })
+ };
+
+ /* ___filename___: dist/deps/fp/flip2.js */
+
+ /* ___filename___: dist/deps/conditional/includes/needleHaystack.js */
+
+
+
+ var needleHaystack = flip2(haystackNeedle);
+
+ /* ___filename___: dist/deps/conditional/includes/needleHaystack.js */
+
+ var index$8 = needleHaystack;
+
+ /* ___filename___: dist/deps/util/keysObjOrArray.js */
+
+
+
+
+
+ /**
+ * Creates an array of the own enumerable property names of `object`.
+ * **Note:** Non-object values are coerced to objects. See the
+ * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
+ * for more details.
+ *
+ * @since 0.1.0
+ * @category Object
+ * @name keysObjOrArray
+ *
+ * @param {Object} obj The object to query.
+ * @return {Array} Returns the array of property names.
+ *
+ * @see deps/util/lengthFromZero
+ * @see deps/util/props
+ * @see values, valuesIn
+ *
+ * {@link https://github.com/lodash/lodash/blob/master/keys.js lodash-keys}
+ * {@link https://github.com/lodash/lodash/blob/master/.internal/getAllKeys.js lodash-get-all-keys}
+ * @see {@link lodash-keys}
+ * @see {@link lodash-get-all-keys}
+ *
+ * @TODO https://github.com/lodash/lodash/blob/master/.internal/arrayLikeKeys.js
+ *
+ * @example
+ *
+ * function Foo() {
+ * this.a = 1
+ * this.b = 2
+ * }
+ *
+ * Foo.prototype.c = 3
+ *
+ * keys(new Foo)
+ * // => ['a', 'b'] (iteration order is not guaranteed)
+ *
+ * keys('hi')
+ * // => ['0', '1']
+ *
+ */
+ var keysObjOrArray = function keys$$2(obj$$2) {
+ return array(obj$$2)
+ ? new Array(lengthFromZero(obj$$2))
+ : obj(obj$$2) ? keys(obj$$2) : []
+
+ // for (var key in obj) gathered.push(key)
+ // return gathered
+ };
+
+ /* ___filename___: dist/deps/util/keysObjOrArray.js */
+
+ /* ___filename___: dist/deps/is/empty.js */
+
+
+
+
+
+ /* prettier-ignore */
+ /**
+ * Returns `true` if the given value is its type's empty value;
+ * `false` otherwise.
+ *
+ * @func
+ * @memberOf is
+ * @since v0.1.0
+ * @category Logic
+ * @sig a -> Boolean
+ *
+ * @param {*} x value to check if empty
+ * @return {boolean}
+ *
+ * @see empty
+ * @see https://github.com/ramda/ramda/issues/1228
+ *
+ * @example
+ *
+ * isEmpty([1, 2, 3]); //=> false
+ * isEmpty([]); //=> true
+ * isEmpty(''); //=> true
+ * isEmpty(null); //=> false
+ * isEmpty({}); //=> true
+ * isEmpty({length: 0}); //=> false
+ *
+ */
+ var empty = function isEmpty(x) {
+ if (x === '') { return true }
+ else if (nullOrUndefined(x)) { return false }
+ else if (obj(x) || array(x)) { return keysObjOrArray(x).length === 0 }
+ else { return false }
+
+ // else return (
+ // // null|undefined = empty
+ // // isNullOrUndefined(x) ||
+ // // '' = empty
+ // // [] | {} = empty
+ // keys(x).length === 0
+ // )
+ };
+
+ /* ___filename___: dist/deps/is/error.js */
+
+
+ /**
+ * @param {*} x value
+ * @return {boolean} isError
+ *
+ * @since 4.0.0
+ * @memberOf is
+ * @func isError
+ *
+ * @example
+ *
+ * isError(new Error())
+ * //=> true
+ * isError(new Error().stack)
+ * //=> false
+ * isError(1)
+ * //=> false
+ * isError('')
+ * //=> false
+ *
+ * @example
+ *
+ * const e = {}
+ * eh[Symbol.toStringTag] = '[Object Error]'
+ * isError(eh)
+ * //=> true
+ *
+ * @example
+ *
+ * class Eh extends Error()
+ * isError(new Eh())
+ * //=> true
+ *
+ */
+ var error$1 = function isError(x) {
+ // console.log('isError', toS(x), x)
+ return toS(x) === '[object Error]'
+ // x instanceof Error ||
+ };
+
+ /* ___filename___: dist/deps/is/symbol.js */
+
+
+ /**
+ * Checks if `value` is classified as a `Symbol` primitive or object.
+ *
+ * @since 4.0.0
+ * @category Lang
+ * @memberOf is
+ *
+ * @param {*} value The value to check.
+ * @return {boolean} Returns `true` if `value` is a symbol, else `false`.
+ *
+ * @example
+ *
+ * isSymbol(Symbol.iterator)
+ * // => true
+ *
+ * isSymbol('abc')
+ * // => false
+ *
+ */
+ var symbol = function (x) { return toS(x) === '[object Symbol]'; };
+
+ /* ___filename___: dist/deps/conditional/or.js */
+
+
+ /**
+ * @desc first fn || second fn, curried
+ * @memberOf conditional
+ * @since 4.0.1
+ *
+ * @param {Function} left first fn
+ * @param {Function} right second fn
+ * @param {*} x value to pass into left & right, @curried
+ * @return {boolean} one of the functions return truthy @curried
+ *
+ * @name or
+ * @func
+ *
+ * @example
+ *
+ * const {isTrue, isFalse} = require('chain-able')
+ *
+ * const either = or(isFalse, isTrue)
+ *
+ * either([true])
+ * //=> true
+ *
+ * either([new Boolean(true)])
+ * //=> false
+ *
+ * either([1])
+ * //=> false
+ *
+ * // because curried
+ * or(isTrue, isFalse, true) //=> true
+ *
+ */
+ var or = curry(3, function (left, right, x) { return left(x) || right(x); });
+
+ /* ___filename___: dist/deps/is/async.js */
+
+
+ /**
+ * @category Lang
+ *
+ * @param {*} x value
+ * @return {boolean} isAsync
+ * @since 4.0.0-beta.2
+ *
+ * @memberOf is
+ * @func isAsync
+ * @see is/toS
+ *
+ * @example
+ *
+ * isAsync(async function() {})
+ * //=> true
+ * isAsync(new Promise(r => r()))
+ * //=> false
+ * isAsync({})
+ * //=> false
+ * isAsync(function() {})
+ */
+ var async = function isAsync(x) {
+ return toS(x) === '[object AsyncFunction]'
+ };
+
+ /* ___filename___: dist/deps/is/promise.js */
+
+
+ /**
+ * @desc is a Promise
+ * @param {*} x value
+ * @return {boolean} x isPromise
+ *
+ * @since 4.0.0-beta.2
+ * @memberOf is
+ * @func isPromise
+ *
+ * @see https://github.com/jonschlinkert/kind-of/blob/master/index.js#L66
+ * @see https://github.com/sindresorhus/promise-fun
+ *
+ * @example
+ *
+ * isPromise(new Promise(r => r))
+ * //=> true
+ * isPromise(async function() {})
+ * //=> false // on some environments, true
+ *
+ * isPromise({})
+ * //=> false
+ * isPromise(Object.create(null))
+ * //=> false
+ * isPromise(null)
+ * //=> false
+ * isPromise(new Set())
+ * //=> false
+ * isPromise(function() {})
+ * //=> false
+ * isPromise('')
+ * //=> false
+ * isPromise(1)
+ * //=> false
+ *
+ */
+ var promise = function (x) { return toS(x) === '[object Promise]'; };
+
+ /* ___filename___: dist/deps/conditional/or.js */
+
+ /* ___filename___: dist/deps/is/async.js */
+
+ /* ___filename___: dist/deps/is/promise.js */
+
+ /* ___filename___: dist/deps/is/asyncish.js */
+
+
+
+
+ /**
+ * @desc async function or promise
+ * @since 4.0.0-beta.2
+ * @memberOf is
+ *
+ * @param {*} x value
+ * @return {boolean} x isAsyncish
+ *
+ * @category Lang
+ * @func
+ * @name isAsyncish
+ * @extends isAsyncish
+ * @extends isPromise
+ * @variation isAsyncish OR isPromise
+ *
+ * @example
+ *
+ * isAsyncish(async function() {}) //=> true
+ * isAsyncish(new Promise(r => r())) //=> true
+ *
+ * isAsyncish({}) //=> false
+ * isAsyncish(function() {}) //=> false
+ *
+ */
+ var asyncish = or(async, promise);
+
+ /* ___filename___: dist/deps/is/numberPrimitive.js */
+ /**
+ * @param {*} x value
+ * @return {boolean} isNumberPrimitive
+ *
+ * @since 3.0.0
+ * @memberOf is
+ * @func isNumberPrimitive
+ * @see is/real
+ *
+ * @example
+ *
+ * isNumberPrimitive(1)
+ * //=> true
+ * isNumberPrimitive(Number(1))
+ * //=> true
+ * isNumberPrimitive(NaN)
+ * //=> true
+ * isNumberPrimitive(new Number(1))
+ * //=> false
+ *
+ * isNumberPrimitive(null)
+ * //=> false
+ * isNumberPrimitive(undefined)
+ * //=> false
+ * isNumberPrimitive(void 0)
+ * //=> false
+ * isNumberPrimitive({})
+ * //=> false
+ * isNumberPrimitive('')
+ * //=> false
+ * isNumberPrimitive(false)
+ * //=> false
+ *
+ */
+ var numberPrimitive = function (x) { return typeof x === 'number'; };
+
+ /* ___filename___: dist/deps/is/numberPrimitive.js */
+
+ /* ___filename___: dist/deps/is/primitive.js */
+
+
+
+
+
+ /**
+ * Checks if `value` is classified as a **primitive**
+ * `(number|string|boolean|null|undefined)`
+ *
+ * @version 5.0.0 added booleanPrimitive, is in own file
+ * @since 4.0.0 was in another file
+ * @category Lang
+ * @memberOf is
+ * @param {*} x The value to check.
+ * @returns {boolean} x is number|string|boolean|null|undefined
+ *
+ * @see http://www.adequatelygood.com/Object-to-Primitive-Conversions-in-JavaScript.html
+ * @see https://developer.mozilla.org/en-US/docs/Glossary/Primitive
+ * @see http://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html
+ *
+ * @example
+ *
+ * isPrimitive('abc') // => true
+ * isPrimitive(1) // => true
+ * isPrimitive('') // => true
+ * isPrimitive(null) // => true
+ * isPrimitive(undefined) // => true
+ * isPrimitive(void 0) // => true
+ *
+ * isPrimitive(new String('abc')) // => false
+ * isPrimitive([]) // => false
+ * isPrimitive(() => {}) // => false
+ * isPrimitive({}) // => false
+ *
+ */
+ var primitive$2 = function isPrimitive(node) {
+ return (
+ nullOrUndefined(node) ||
+ stringPrimitive(node) ||
+ numberPrimitive(node) ||
+ booleanPrimitive(node)
+ )
+ };
+
+ /* ___filename___: dist/deps/is/error.js */
+
+ /* ___filename___: dist/deps/is/symbol.js */
+
+ /* ___filename___: dist/deps/is/asyncish.js */
+
+ /* ___filename___: dist/deps/is/primitive.js */
+
+ /* ___filename___: dist/deps/is/iteratable.js */
+
+
+
+
+
+
+
+
+
+ /**
+ * @desc is able to be iterated on
+ *
+ * @param {*} x node is iteratable
+ * @return {boolean} x isIteratable
+ *
+ * @extends isObj
+ * @extends isArray
+ * @extends isPrimitive
+ * @extends isRegExp
+ * @extends isDate
+ * @extends isSymbol
+ * @extends isAsync
+ * @extends isError
+ *
+ * @example
+ *
+ * isIteratable([]) //=> true
+ * isIteratable({}) //=> true
+ * isIteratable(new Date()) //=> false
+ * isIteratable(Symbol('eh')) //=> false
+ * isIteratable(new Promise(r => r())) //=> false
+ * isIteratable(new Error('eh')) //=> false
+ *
+ */
+ var iteratable = function isIteratable(x) {
+ // ez ones
+ if (objNotNull(x) || array(x)) { return true }
+
+ var notIteratable =
+ primitive$2(x) ||
+ regexp(x) ||
+ date(x) ||
+ symbol(x) ||
+ asyncish(x) ||
+ // isNative(x) ||
+ error$1(x);
+
+ // not-not is iteratable
+ return !notIteratable
+
+ // if (notIteratable) return false
+ // else return true
+ // if (isNullOrUndefined(node)) {
+ // }
+ // else if (isString(node)) {
+ // }
+ // else if (isNumber(node)) {
+ // }
+ // else if (isBoolean(node)) {
+ // }
+ // else if (isRegExp(node)) {
+ // }
+ // else if (isDate(node)) {
+ // }
+ // else if (isSymbol(node) || isAsyncish(node)) {
+ // }
+ // else if (isNative(node)) {
+ // }
+ // else {
+ // return true
+ // }
+ // return false
+ };
+
+ // function isSpecial(x) {
+ // // isPromise(x) ||
+ // return isSymbol(x) || isError(x) ||
+ // // || isGenerator(x)
+ // }
+
+ /* ___filename___: dist/deps/fp/prop.js */
+
+
+ /**
+ * Returns a function that when supplied an object returns the indicated
+ * property of that object, if it exists.
+ *
+ * @func
+ * @memberOf fp
+ * @since v5.0.0
+ * @category Object
+ * @sig s -> {s: a} -> a | Undefined
+ *
+ * @param {String} p The property name
+ * @param {Object} obj The object to query
+ * @return {*} The value at `obj.p`.
+ *
+ * @types fp
+ * @tests fp/prop
+ *
+ * @example
+ *
+ * R.prop('x', {x: 100}); //=> 100
+ * R.prop('x', {}); //=> undefined
+ *
+ */
+ var prop = curry(2, function (p, obj) { return obj[p]; });
+
+ /* ___filename___: dist/deps/fp/prop.js */
+
+ /* ___filename___: dist/deps/util/length.js */
+
+
+ // reduces size by hundreds of bytes gzipped...
+ var length = prop('length');
+
+ /* ___filename___: dist/deps/util/length.js */
+
+ /* ___filename___: dist/deps/util/lengthMinusOne.js */
+
+
+ // lengthMinusOne
+ var lengthMinusOne = function (x) { return length(x) - 1; };
+
+ /* ___filename___: dist/deps/util/lengthMinusOne.js */
+
+ /* ___filename___: dist/deps/dot/segments.js */
+
+
+
+
+ var cache;
+
+ /**
+ * @name dotPropSegments
+ * @since 4.0.0
+ * @memberOf dot
+ *
+ * @param {string | Array} path dot-prop-path
+ * @return {Array} array path
+ *
+ * @example
+ *
+ * dotPropSegments('eh.oh') //=> ['eh', 'oh']
+ * dotPropSegments(['eh', 'oh']) //=> ['eh', 'oh']
+ * dotPropSegments('ehoh') //=> ['ehoh']
+ *
+ */
+ var segments = function (path) {
+ if (!cache) { cache = new Map(); }
+ if (cache.has(path)) { return cache.get(path) }
+ if (array(path)) { return path }
+
+ var pathArr = path.split('.');
+ var parts = [];
+
+ for (var i = 0; i < pathArr.length; i++) {
+ var p = pathArr[i];
+
+ /**
+ * @example 1
+ * '\.eh' -1 === '\\' (true)
+ * +1 !== undefined (true, eh)
+ *
+ * @example 2
+ * '.eh' -1 === '\\' (false, undefined)
+ * +1 !== undefined (true, eh)
+ *
+ * @example 3
+ * '\.' -1 === '\\' (true)
+ * +1 !== undefined (false, eh)
+ */
+ while (p[lengthMinusOne(p)] === '\\' && !_undefined(pathArr[i + 1])) {
+ p = p.slice(0, -1) + '.' + pathArr[++i];
+ }
+
+ parts.push(p);
+ }
+
+ cache.set(path, parts);
+ return parts
+ };
+
+ /* ___filename___: dist/deps/dot/dottable.js */
+
+
+
+
+ // const isDot = require('./is/dot')
+ // const isDottable = (obj, path) => isObj(obj) && isDot(path)
+ var dottable = function (obj$$2, path) { return (obj(obj$$2) && string(path)) || array(path); };
+
+ /* ___filename___: dist/deps/dot/segments.js */
+
+ /* ___filename___: dist/deps/dot/dottable.js */
+
+ /* ___filename___: dist/deps/dot/set.js */
+
+
+
+
+
+ var set$2 = function dotset(obj$$2, path, value) {
+ if (!dottable(obj$$2, path)) {
+ return
+ }
+
+ var pathArr = segments(path);
+
+ for (var i = 0; i < pathArr.length; i++) {
+ var p = pathArr[i];
+
+ if (!obj(obj$$2[p])) {
+ obj$$2[p] = {};
+ }
+
+ // isLast
+ if (i === lengthMinusOne(pathArr)) {
+ obj$$2[p] = value;
+ }
+
+ obj$$2 = obj$$2[p];
+ }
+ };
+
+ /* ___filename___: dist/deps/fp/construct.js */
+ /* eslint max-len: "OFF" */
+ /* eslint consistent-return: "OFF" */
+
+
+
+ // const nAry = require('./arity')
+
+ /**
+ * Wraps a constructor function inside a curried function that can be called
+ * with the same arguments and returns the same type. The arity of the function
+ * returned is specified to allow using variadic constructor functions.
+ *
+ * @func
+ * @memberOf fp
+ * @symb 👷
+ * @since 5.0.0-beta.4
+ * @fork v0.4.0
+ * @category Function
+ * @sig Number -> (* -> {*}) -> (* -> {*})
+ *
+ * @param {number} n The arity of the constructor function. (aka, number of args)
+ * @param {Function} Klass The constructor function to wrap. (class to do `new Klass` on)
+ * @return {Function} A wrapped, curried constructor function.
+ *
+ * @extends R.construct
+ * @extends R.constructN
+ * @variation with a single *notNumber* arg, it acts as construct, rather than constructN
+ *
+ * {@link https://github.com/ramda/ramda/blob/master/src/constructN.js ramda-construct}
+ * @see {@link ramda-construct}
+ * @see isNumberPrimitive
+ *
+ * @example
+ *
+ * // Variadic Constructor function
+ * function Salad() {
+ * this.ingredients = arguments;
+ * }
+ *
+ * Salad.prototype.recipe = function() {
+ * var instructions = R.map(ingredient => 'Add a dollop of ' + ingredient, this.ingredients);
+ * return R.join('\n', instructions);
+ * };
+ *
+ * var ThreeLayerSalad = R.constructN(3, Salad);
+ *
+ * // Notice we no longer need the 'new' keyword, and the constructor is curried for 3 arguments.
+ * var salad = ThreeLayerSalad('Mayonnaise')('Potato Chips')('Ketchup');
+ *
+ * console.log(salad.recipe());
+ * // Add a dollop of Mayonnaise
+ * // Add a dollop of Potato Chips
+ * // Add a dollop of Ketchup
+ *
+ */
+ function constructN(n, Klass) {
+ if (!numberPrimitive(n)) {
+ return constructN(n.length, n)
+ }
+ else if (n === 0) {
+ return function () { return new Klass(); }
+ }
+ else {
+ /*, $5, $6, $7, $8, $9 */
+ // curry(nAry(n,
+ return curry(n, function($0, $1, $2, $3, $4) {
+ var len = arguments.length;
+ if (len === 1 || len > 5) { return new Klass($0, $1, $2) }
+ else if (len === 2) { return new Klass($0, $1) }
+ else if (len === 3) { return new Klass($0, $1, $2) }
+ else if (len === 4) { return new Klass($0, $1, $2, $3) }
+ else if (len === 5) { return new Klass($0, $1, $2, $3, $4) }
+ // else if (len=== 6) return new Klass($0, $1, $2, $3, $4, $5)
+ // else if (len=== 7) return new Klass($0, $1, $2, $3, $4, $5, $6)
+ // else if (len=== 8) return new Klass($0, $1, $2, $3, $4, $5, $6, $7)
+ // else if (len=== 9) return new Klass($0, $1, $2, $3, $4, $5, $6, $7, $8)
+ // else if (len === 10) return new Klass($0, $1, $2, $3, $4, $5, $6, $7, $8, $9)
+ })
+ // ))
+ }
+ }
+
+ // module.exports = curry(2, constructN)
+ var construct = constructN;
+
+ /* ___filename___: dist/deps/fp/construct.js */
+
+ /* ___filename___: dist/deps/construct/regexp.js */
+
+
+ var regexp$2 = construct(1, RegExp);
+
+ /* ___filename___: dist/deps/construct/regexp.js */
+
+ /* ___filename___: dist/deps/env/debug.js */
+
+ /* ___filename___: dist/deps/traversers/copy.js */
+
+
+
+
+
+
+
+
+ /* prettier-ignore */
+ /**
+ * @desc copy any primitive value, part of clone
+ * @version 5.0.0
+ * @since 3.0.0
+ * @name copy
+ * @see clone
+ * @memberOf Traverse
+ *
+ * @param {*} src value to copy
+ * @return {*} copied
+ *
+ * @example
+ *
+ * copy(/eh/gmi) //=> new RegExp('eh', 'gmi')
+ * copy(new Error('eh')) // => new Error with copied stack + msg
+ * copy([1]) // => [1]
+ * copy({}) // => {}
+ *
+ */
+ var copy = function copy(src) {
+ if (objNotNull(src)) {
+ var dst;
+
+ // if (isPrimitive(src)) {
+ // if (isNullOrUndefined(src)) {
+ // dst = src
+ // }
+
+ // @TODO @IMPORTANT @FIXME @!IMPORTANT - COVER THIS OR NOT?
+ // for string value number boolean objects...
+ // if (isString(src)) {
+ // dst = src + ''
+ // }
+ // else if (isNumber(src)) {
+ // dst = src + 0
+ // }
+ // else if (isBoolean(src)) {
+ // dst = !!src
+ // }
+ // else
+
+ // lists... <- needs to have dot-prop support on Map/Set
+ // if (isMap(src)) {
+ // dst = new Map()
+ // const obj = reduce(src)
+ // // src.clear()
+ // ObjectKeys(obj).forEach(key => dst.set(key, obj[key]))
+ // return dst
+ // }
+ // else if (isSet(src)) {
+ // dst = new Set()
+ // // could clone here too
+ // const obj = toarr(src)
+ // // src.clear()
+ // obj.forEach(value => dst.add(value))
+ // return dst
+ // }
+
+ // ------
+ if (array(src)) {
+ dst = [];
+ }
+ // @TODO also would just be isPrimitive
+ // was new date(src.getTime())
+ // || isBoolean(src) || isNumber(src) || isString(src)
+ else if (date(src)) {
+ dst = new src.constructor(src.valueOf());
+ }
+ else if (regexp(src)) {
+ // dst = new RegExp(src)
+ dst = regexp$2(src.src, src.toString().match(/[^/]*$/)[0]);
+ // dst = new RegExp(src.src, src.toString().match(/[^/]*$/)[0])
+ dst.lastIndex = src.lastIndex;
+ }
+ // @TODO this should just be handled by the next condition...
+ // else if (isError(src)) {
+ // dst = new Error(src.message)
+ // dst.stack = src.stack
+ // }
+ else {
+ dst = Object.create(Object.getPrototypeOf(src));
+ }
+
+ // @TODO: copy descriptor
+ // eslint-disable-next-line
+ for (var prop in src) {
+ dst[prop] = src;
+ // const desc = Object.getOwnPropertyDescriptor(src, prop)
+ // Object.defineProperty(dst, prop, desc)
+ }
+ return dst
+ }
+ else {
+ if (debug) {
+ console.log('is not obj', src);
+ }
+ return src
+ }
+ };
+
+ /* ___filename___: dist/deps/native/hasOwnProperty.js */
+ var hasOwnProperty_1$2 = Object.prototype.hasOwnProperty;
+
+ /* ___filename___: dist/deps/native/hasOwnProperty.js */
+
+ /* ___filename___: dist/deps/util/hasOwnProperty.js */
+
+
+
+
+ var hasOwnPropertyNotNill = function (haystack, needle) { return !nullOrUndefined(haystack) && hasOwnProperty_1$2.call(haystack, needle); };
+
+ var hasOwnProperty_1 = curry(2, hasOwnPropertyNotNill);
+ // function(obj, key) {
+ // return key in obj
+ // }
+
+ /* ___filename___: dist/deps/util/hasOwnProperty.js */
+
+ /* ___filename___: dist/deps/traversers/eqValue.js */
+ // conditionals
+ /* eslint complexity: "OFF" */
+ // debugging
+ /* eslint max-depth: "OFF" */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ // const ENV_DEBUG = true
+
+ var isNotRealOrNotEqToString = function (x, y) { return !x || !y || x.toString() !== y.toString(); };
+
+ /* prettier-ignore */
+ /**
+ * @desc checks value equality, used by eq which compares all types
+ * @since 4.1.0
+ * @memberOf Traverse
+ * @protected
+ *
+ * @TODO !!!!!! USE ENUM FLAGS ON LOOSE TO ALLOW MORE CONFIG FOR ==, COMPARATOR, VALUEOF, walk proto (check ownProps...)...
+ *
+ * @param {*} x compare to y
+ * @param {*} y compare to x
+ * @param {boolean | number} [loose=false] use == checks when typof !=
+ * @return {boolean}
+ *
+ * @example
+ *
+ * eqValue(1, 1) //=> true
+ * eqValue('1', 1) //=> false
+ * eqValue('1', 1, true) //=> true
+ * eqValue({}, {}) //=> true
+ *
+ */
+ var eqValue = function eqValue(x, y, loose) {
+ /* istanbul ignore next: dev */
+ if (debug) {
+ console.log('eqValue', {x: x, y: y, loose: loose});
+ }
+
+ // if (x === y) {
+ // if (ENV_DEBUG) {
+ // console.log('===', {x, y})
+ // }
+ // // noop
+ // }
+ // else
+
+ if (nullOrUndefined(x) || nullOrUndefined(y)) {
+ /* istanbul ignore next: dev */
+ if (debug) {
+ console.log('null or undef !=', {x: x, y: y});
+ }
+
+ if (x !== y) {
+ return false
+ }
+ }
+ else if (typeof x !== typeof y) {
+ // eslint-disable-next-line
+ if (_true(loose) && x == y) {
+ // ignore
+ }
+ else {
+ /* istanbul ignore next: dev */
+ if (debug) {
+ console.log('typeof !=', {x: x, y: y});
+ }
+
+ return false
+ }
+ }
+ // @TODO put this up first?
+ else if (toS(x) !== toS(y)) {
+ /* istanbul ignore next: dev */
+ if (debug) {
+ console.log('diff str types', {x: toS(x), y: toS(y)});
+ }
+
+ return false
+ }
+ else if (objNotNull(x)) {
+ // use .equals if the method exists
+ if (hasOwnProperty_1(x, 'equals')) {
+ return x.equals(y)
+ }
+
+ /* istanbul ignore next: dev */
+ if (debug) {
+ console.log('isObjNotNull', {x: x});
+ }
+
+ // if (isArray(x)) {
+ // if (x.length !== y.length) {
+ // return false
+ // }
+ // }
+
+ // @NOTE .toString will be covered for functions and regexes in objStrict
+ if (regexp(x) || regexp(y)) {
+ /* istanbul ignore next: dev */
+ if (debug) {
+ console.log('regexp', {x: x, y: y});
+ }
+
+ if (isNotRealOrNotEqToString(x, y)) {
+ /* istanbul ignore next: dev */
+ if (debug) {
+ console.log('regexp !=', {x: x, y: y});
+ }
+
+ return false
+ }
+ }
+ else if (date(x) || date(y)) {
+ /* istanbul ignore next: dev */
+ if (debug) {
+ console.log('dates', {x: x, y: y});
+ }
+
+ if (!date(x) || !date(y) || x.getTime() !== y.getTime()) {
+ /* istanbul ignore next: dev */
+ if (debug) {
+ console.log('!= dates', {x: x, y: y});
+ }
+
+ return false
+ }
+ }
+ else if (error$1(x) || error$1(y)) {
+ /* istanbul ignore next: dev */
+ if (debug) {
+ console.log('isError', {x: x, y: y});
+ }
+
+ if (!error$1(x) || !error$1(y) || x.stack !== y.stack) {
+ /* istanbul ignore next: dev */
+ if (debug) {
+ console.log('!= errors', {x: x, y: y});
+ }
+
+ return false
+ }
+ }
+
+ // @NOTE this is covered by toString != toString
+ // else if (isArray(x) && !isArray(y)) {
+ // /* istanbul ignore next: dev */
+ // if (ENV_DEBUG) {
+ // console.log('isArray(x) || isArray(y)!')
+ // }
+ //
+ // return false
+ // }
+ // else if (!isArray(x) && isArray(y)) {
+ // /* istanbul ignore next: dev */
+ // if (ENV_DEBUG) {
+ // console.log('!isArray(x) && isArray(y):')
+ // }
+ //
+ // return false
+ // }
+
+ // @TODO considering, we already know it is not null & undefined
+ // if (isPrimitive(x) || isPrimitive(y)) {
+ // return x.valueOf() === y.valueOf()
+ // }
+
+ else {
+ // @TODO ObjectOrArrayKeys, but have to have else where they are both array
+ //
+ // @NOTE it will traverse through values if they are == here
+ var xKeys = keys(x);
+ var yKeys = keys(y).length;
+
+ // diff length
+ if (xKeys.length !== yKeys) {
+ /* istanbul ignore next: dev */
+ if (debug) {
+ console.log('!= obj key length', {xKeys: xKeys, yKeys: yKeys});
+ }
+
+ return false
+ }
+
+ for (var k = 0; k < xKeys.length; k++) {
+ if (!hasOwnProperty_1(y, xKeys[k])) {
+ /* istanbul ignore next: dev */
+ if (debug) {
+ console.log('!= obj property', {y: y, val: xKeys[k]});
+ }
+
+ return false
+ }
+ }
+ }
+ }
+ else if (toS(x) === toS(y) && x !== y) {
+ // isString(x) || isBoolean(x) || isNumber(x) || isIterator(x)
+ /* istanbul ignore next: dev */
+ if (debug) {
+ console.log('same str types - diff values', {s: toS(x), x: x, y: y});
+ }
+
+ return false
+ }
+ // // @TODO put this up first?
+ // else if (toS(x) !== toS(y)) {
+ // /* istanbul ignore next: dev */
+ // if (ENV_DEBUG) {
+ // console.log('diff str types', {x: toS(x), y: toS(y)})
+ // }
+ //
+ // return false
+ // }
+
+ // go deeper
+ else if (_function(x) || _function(y)) {
+ /* istanbul ignore next: dev */
+ if (debug) {
+ console.log('isFunction(x) && isFunction(y):');
+ console.log(x.toString());
+ console.log(y.toString());
+ }
+
+ if (isNotRealOrNotEqToString(x, y)) {
+ /* istanbul ignore next: dev */
+ if (debug) {
+ console.log('x.toString() !== y.toString()', x.toString() !== y.toString());
+ }
+ return false
+ }
+ else {
+ return true
+ }
+ }
+ // @TODO why?
+ else if (obj(x) && obj(y)) {
+ /* istanbul ignore next: dev */
+ if (debug) {
+ console.log('isObj(x) && isObj(y):');
+ }
+
+ return false
+ }
+ // else {
+ /* istanbul ignore next: dev */
+ if (debug) {
+ console.log('eqeqeq:', {[toS(x) + 'X']: x, [toS(y) + 'Y']: y});
+ }
+ return true
+ // }
+ };
+
+ /* ___filename___: dist/deps/is/empty.js */
+
+ /* ___filename___: dist/deps/traversers/eqValue.js */
+
+ /* ___filename___: dist/deps/traversers/_eq.js */
+ // conditionals
+ /* eslint complexity: "OFF" */
+
+ // not iterating on empty root
+ /* eslint consistent-return: "OFF" */
+
+ // const traverse = require('../traverse')
+ // const get = require('../dot/get')
+
+
+
+
+
+
+ /* prettier-ignore */
+ /**
+ * @name eq
+ * @since 3.0.0
+ * @version 5.0.0
+ * @memberOf Traverse
+ *
+ * {@link http://dorey.github.io/JavaScript-Equality-Table/ js-equality-table}
+ * {@link https://github.com/facebook/react/blob/master/src/__mocks__/deepDiffer.js react-deep-differ}
+ * {@link https://github.com/substack/js-traverse/blob/master/test/lib/deep_equal.js traverse-deep-equal}
+ * {@link https://github.com/jashkenas/underscore/blob/master/underscore.js#L1183 underscore-equal}
+ * {@link https://github.com/angular/angular.js/blob/master/src/Angular.js angular-is-equal}
+ * {@link https://lodash.com/docs/4.17.4#isEqual lodash-is-equal}
+ * {@link http://ramdajs.com/docs/#equals ramda-equals}
+ * {@link https://github.com/substack/node-deep-equal node-deep-equal}
+ * {@link https://github.com/facebook/immutable-js/blob/master/src/utils/deepEqual.js immutable-js-deep-equal}
+ * @see {@link js-equality-table}
+ * @see {@link immutable-js-deep-equal}
+ * @see {@link node-deep-equal}
+ * @see {@link ramda-equals}
+ * @see {@link lodash-is-equal}
+ * @see {@link angular-is-equal}
+ * @see {@link underscore-equal}
+ * @see {@link traverse-deep-equal}
+ * @see {@link react-deep-differ}
+ *
+ * @param {Traverse} traverse traversejs (scoped, @FIXME @HACK)
+ * @param {*} a compare to b
+ * @param {*} b compare to a
+ * @param {boolean} [loose] compare loosely
+ * @return {boolean} isEqual: a === b
+ *
+ * @extends eqValue
+ *
+ * @example
+ *
+ * eq(1, 1) //=> true
+ * eq(1, '1') //=> false
+ * eq(1, '1', true) //=> true
+ * eq([1], [1]) //=> true
+ *
+ */
+ var _eq = function (traverse) { return function eq(a, b, loose) {
+ /* istanbul ignore next: dev */
+ if (debug) {
+ console.log('\n');
+ }
+
+ var equal = true;
+ var node = b;
+ var nodes = [node];
+
+ var instance = traverse(a);
+
+ var notEqual = function () {
+ equal = false;
+ instance.stop();
+ };
+
+ /* istanbul ignore next: dev */
+ if (debug) {
+ console.log('eq?');
+ }
+
+ instance.forEach(function(key, y, traverser) {
+ // @NOTE do base comparisons on values that are not actually iteratable
+ // aka, .isRoot
+ if (_null(key)) {
+ // always-valid state opionion vs always-invalid
+ // so it only returns false when it is !== fosho
+ if (eqValue(node, y, loose) === false) { return notEqual() }
+ else { return }
+ }
+
+ /* istanbul ignore next: dev */
+ if (debug) {
+ console.log('eq: iterating:');
+ }
+
+ // could use it as a fallback if undefined && y !== undefined
+ // const xyz = get(b, traverser.path.join('.'), b)
+
+ var x = node;
+
+ // isNotLeafAndIsObj
+ if (objNotNull(node) && !empty(node)) {
+ /* istanbul ignore next: dev */
+ if (debug) {
+ console.log('is leaf, is not empty node, going deeper');
+ }
+
+ // so x is our current one,
+ // if node is not empty, use the key, push the value
+ // and when it is empty, and it is not a leaf but has nodes, pop back up
+ x = node[key];
+ nodes.push(x);
+ }
+
+ // ENV_DEBUG
+ // console.log({[key]: {x, xyz, y, nodes, path: traverser.path.join('.')}})
+
+ // for next loop!!!
+ if (!traverser.isLeaf && !empty(nodes)) {
+ /* istanbul ignore next: dev */
+ if (debug) {
+ console.log('is not leaf, has nodes stack, pop');
+ }
+ node = nodes.pop();
+ }
+
+ /* istanbul ignore next: dev */
+ if (debug) {
+ console.log({key: key, y: y, x: x, a: a, b: b});
+ }
+
+ var eqv = eqValue(x, y, loose);
+
+ /* istanbul ignore next: dev */
+ if (debug) {
+ console.log({eqv: eqv});
+ }
+
+ if (eqv === false) {
+ // equal
+ notEqual();
+ }
+ });
+
+ // cleanup
+ nodes = undefined;
+ node = undefined;
+
+ return equal
+ }; };
+
+ /* ___filename___: dist/deps/cache/standardReleaser.js */
+ /* eslint consistent-this: ["error", "Klass"] */
+
+
+
+ /**
+ * @desc call destructor on a pooled instance, put it back in the pool
+ * @since 5.0.0
+ * @memberOf pooler
+ *
+ * @param {Object} instance call destructor
+ * @return {void}
+ *
+ * @prop {Array} instancePool
+ * @prop {number} poolSize
+ * @prop {Function} destructor
+ *
+ * @example
+ *
+ * class Eh {}
+ * addPoolingTo(Eh)
+ * const eh = Eh.getPooled()
+ * eh.release()
+ *
+ */
+ var standardReleaser = function standardReleaser(instance) {
+ var Klass = this;
+
+ if (debug) {
+ if (instance instanceof Klass) {
+ throw new Error(
+ "Trying to release an instance\n into a pool of a different type."
+ )
+ }
+ }
+
+ instance.destructor();
+ if (Klass.instancePool.length < Klass.poolSize) {
+ Klass.instancePool.push(instance);
+ }
+ };
+
+ /* ___filename___: dist/deps/cache/oneArgumentPooler.js */
+ /* eslint consistent-this: ["error", "Klass"] */
+
+
+
+ /**
+ * Static poolers. Several custom versions for each potential number of
+ * arguments. A completely generic pooler is easy to implement, but would
+ * require accessing the `arguments` object. In each of these, `this` refers to
+ * the Class itself, not an instance. If any others are needed, simply add them
+ * here, or in their own files.
+ *
+ * @since 5.0.0
+ * @memberOf pooler
+ *
+ * @param {Object} copyFieldsFrom obj with instance pool
+ * @return {Object} instance of Klass
+ *
+ * @example
+ *
+ * class Eh {}
+ * addPoolingTo(Eh)
+ * const eh = Eh.getPooled() //=> oneArgumentPooler(Eh)
+ * eh.release()
+ *
+ */
+ var oneArgumentPooler = function oneArgumentPooler(copyFieldsFrom) {
+ var Klass = this;
+ if (Klass.instancePool.length) {
+ var instance = Klass.instancePool.pop();
+ Klass.call(instance, copyFieldsFrom);
+ return instance
+ }
+ else {
+ return new Klass(copyFieldsFrom)
+ }
+ };
+
+ /* ___filename___: dist/deps/cache/standardReleaser.js */
+
+ /* ___filename___: dist/deps/cache/oneArgumentPooler.js */
+
+ /* ___filename___: dist/deps/cache/pooler.js */
+ /* eslint consistent-this: ["error", "Klass"] */
+
+
+
+
+
+ /**
+ * @symb 🎱
+ * @member pooler
+ * @type {Object}
+ *
+ * {@link https://github.com/facebook/react/blob/master/src/renderers/shared/utils/PooledClass.js react-pooler}
+ * @see {@link react-pooler}
+ *
+ * @tests deps/pooler
+ * @types deps.cache.pooler
+ */
+ var DEFAULT_POOLER = oneArgumentPooler;
+ var DEFAULT_POOL_SIZE = 10;
+
+ /**
+ * Augments `CopyConstructor` to be a poolable class, augmenting only the class
+ * itself (statically) not adding any prototypical fields. Any CopyConstructor
+ * you give this may have a `poolSize` property, and will look for a
+ * prototypical `destructor` on instances.
+ *
+ * @since 5.0.0
+ * @memberOf pooler
+ *
+ * @param {Function | Object} CopyConstructor Constructor that can be used to reset.
+ * @param {Function} pooler Customizable pooler.
+ * @return {Object} enhanced constructor, decorated with pooler
+ *
+ * @prop {Array} instancePool
+ * @prop {number} poolSize
+ * @prop {Function} release
+ * @prop {Function} getPooled
+ *
+ * @example
+ *
+ * class Eh {}
+ * addPoolingTo(Eh) // can optionally pass in pooler as second arg
+ * //=> Eh.instancePool = []
+ * //=> Eh.getPooled = pooler || singleArgumentPooler
+ * //=> Eh.poolSize = 10
+ * //=> Eh.release = standardReleaser
+ *
+ */
+ function addPoolingTo(CopyConstructor, pooler) {
+ // Casting as any so that flow ignores the actual implementation and trusts
+ // it to match the type we declared
+ var NewKlass = CopyConstructor;
+
+ NewKlass.instancePool = [];
+ NewKlass.getPooled = pooler || DEFAULT_POOLER;
+ if (!NewKlass.poolSize) { NewKlass.poolSize = DEFAULT_POOL_SIZE; }
+ NewKlass.release = standardReleaser;
+
+ return NewKlass
+ }
+
+ var pooler = addPoolingTo;
+
+ /* ___filename___: dist/deps/is/iteratable.js */
+
+ /* ___filename___: dist/deps/dot/set.js */
+
+ /* ___filename___: dist/deps/traversers/copy.js */
+
+ /* ___filename___: dist/deps/traversers/_eq.js */
+
+ /* ___filename___: dist/deps/cache/pooler.js */
+
+ /* ___filename___: dist/deps/traverse.js */
+ // conditionals
+ /* eslint complexity: "OFF" */
+
+ // inlined rollup
+ /* eslint import/max-dependencies: "OFF" */
+
+ // one file
+ /* eslint max-lines: "OFF" */
+
+ // debug conditionals
+ /* eslint max-depth: "OFF" */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ // const props = require('./util/props')
+
+ // const ENV_DEBUG = require('./env/debug')
+ // const ENV_DEBUG = true
+ // const TRUTH = true
+ var ENV_DEBUG = false;
+
+ /**
+ * {@link https://github.com/wmira/object-traverse/blob/master/index.js object-traverse}
+ * {@link https://www.npmjs.com/browse/keyword/traverse traverse-js}
+ * {@link https://www.npmjs.com/package/tree-walk tree-walk}
+ * {@link https://www.npmjs.com/package/1tree 1tree}
+ * {@link https://www.npmjs.com/package/pathway pathway}
+ * {@link https://www.npmjs.com/package/@mojule/tree tree}
+ * {@link http://web.archive.org/web/20160930054101/http://substack.net/tree_traversal tree-traversal-article}
+ * {@link https://medium.com/@alexanderv/tries-javascript-simple-implementation-e2a4e54e4330 js-trie-medium}
+ * --------------------
+ *
+ * if needed, clone
+ *
+ * first things to check are number/string/boolean/null/undefined
+ *
+ * then check non-iteratables
+ * symbol, promise,
+ *
+ * then check conversions
+ * - map, set
+ *
+ * then check empties
+ * - obj
+ * - fn
+ *
+ * -------
+ *
+ * numbers f-or first/last
+ * and as a sort of hash like
+ * 1 + 2 + 4 = ISLEAF & ISROOT ?
+ *
+ * Array
+ *
+ * Object Function Date Error Map Set
+ *
+ * String
+ * Number NaN Infinity
+ * Boolean
+ *
+ *
+ * null undefined
+ *
+ * Promise Symbol
+ *
+ * ----
+ *
+ * @emits before
+ * @emits pre
+ * @emits post
+ * @emits after
+ */
+
+ /**
+ * @desc Traverse class, pooled
+ * @modifies this.node
+ * @modifies this.parent
+ * @modifies this.root
+ * @since 5.0.0
+ *
+ * @member Traverse
+ * @class
+ * @constructor
+ * @alias IterAteOr
+ * @extends pooler
+ *
+ * @param {Traversable} iteratee value to iterate, clone, copy, check for eq
+ * @param {Object | undefined} [config] wip config for things such as events or configs
+ *
+ * @see {@link tree-traversal-article}
+ * @see traverse
+ * @TODO make this a trie OR a linked-list
+ *
+ * @tests traverse
+ * @types traverse
+ *
+ * @example
+ *
+ * new Traverse([1])
+ * new Traverse([], {})
+ *
+ */
+ function Traverse(iteratee, config) {
+ // always cleared when done anyway
+ if (_undefined(this.parents)) { this.parents = new Set(); }
+
+ this.node = iteratee;
+ this.parent = iteratee;
+ this.root = iteratee;
+ this.reset();
+
+ // to pass in the events (as commented below) without messing up scope?
+ // if (config.on) this.on = config.on
+ return this
+ }
+
+ /**
+ * @desc reset the properties when finished pooling or instantiating
+ * @since 5.0.0
+ * @method
+ *
+ * @memberOf Traverse
+ * @modifies Traverse.path
+ * @modifies Traverse.key
+ * @modifies Traverse.isAlive
+ * @modifies Traverse.isCircular
+ * @modifies Traverse.isLeaf
+ * @modifies Traverse.isRoot
+ * @modifies Traverse.depth
+ * @return {void}
+ *
+ * @example
+ * traverse([]).reset()
+ */
+ Traverse.prototype.reset = function() {
+ this.path = [];
+ this.key = undefined;
+ this.isAlive = true;
+ this.isCircular = false;
+ this.isLeaf = false;
+ this.isRoot = true;
+
+ // iterates +1 so start at 0
+ this.depth = -1;
+ };
+
+ /**
+ * @desc find parent,
+ * is there a parent
+ * above the current depth
+ * with the same value,
+ * making it circular?
+ *
+ * @memberOf Traverse
+ * @since 5.0.0
+ * @private
+ * @method
+ *
+ * @param {number} depth current depth, to find parent >=
+ * @param {parent} value parent value to find
+ * @return {boolean} hasParent
+ *
+ * @example
+ *
+ * var obj = {eh: ['eh']}
+ * traverse(obj).addParent(0, obj)
+ *
+ */
+ Traverse.prototype.hasParent = function(depth, value) {
+ // or array
+ return obj(value) ? this.parents.has(value) : false
+ };
+
+ /**
+ * @desc add parent, to prevent circular iterations
+ * @memberOf Traverse
+ * @since 5.0.0
+ * @private
+ * @method
+ *
+ * @param {number} depth current depth, to add parent to >=
+ * @param {parent} value parent value to add
+ * @return {void}
+ *
+ * @example
+ *
+ * var obj = {eh: ['eh']}
+ * traverse(obj).addParent(0, obj)
+ *
+ */
+ Traverse.prototype.addParent = function(depth, value) {
+ // && this.hasParent(value) === false
+ if (obj(value)) { this.parents.add(value); }
+ };
+
+ /**
+ * @desc remove all parents, reset the map
+ *
+ * @memberOf Traverse
+ * @since 5.0.0
+ * @private
+ * @method
+ *
+ * @return {void}
+ *
+ * @example
+ *
+ * var obj = {eh: ['eh']}
+ * traverse(obj).forEach((key, value, t) => {
+ * t.parents
+ * //=> Set([obj])
+ * t.clear()
+ * t.parents
+ * //=> Set[]
+ * })
+ *
+ */
+ Traverse.prototype.clear = function() {
+ // if (!isUndefined(this.parents))
+ this.parents.clear();
+ };
+
+ /**
+ * @memberOf Traverse
+ * @since 5.0.0
+ * @private
+ * @method
+ *
+ * @param {number} depth current depth, to find parents >=
+ * @param {parent} value parent value to remove
+ * @return {void}
+ *
+ * @example
+ *
+ * var obj = {eh: ['eh']}
+ * traverse(obj).removeParent(0, obj)
+ *
+ */
+ Traverse.prototype.removeParent = function(depth, value) {
+ this.parents.delete(value);
+ };
+
+ /**
+ * @desc this is the main usage of Traverse
+ * @memberOf Traverse
+ * @since 3.0.0
+ * @version 5.0.0
+ * @method
+ *
+ * @param {Function} cb callback for each iteration
+ * @return {*} mapped result or original value, depends how it is used
+ *
+ * @example
+ *
+ * traverse([1, 2, 3]).forEach((key, value) => console.log({[key]: value}))
+ * //=> {'0': 1}
+ * //=> {'1': 2}
+ * //=> {'2': 3}
+ *
+ */
+ Traverse.prototype.forEach = function iterateForEach(cb) {
+ /* istanbul ignore next: dev */
+ if (ENV_DEBUG) {
+ console.log('\n forEach \n');
+ }
+
+ var result = this.iterate(cb);
+
+ // TODO: HERE, WHEN THIS IS ADDED, CAN BREAK SOME TESTS? SCOPED PARENTS MAP?
+ Traverse.release(this);
+
+ return result
+ };
+
+ /**
+ * @desc stop the iteration
+ * @modifies this.isAlive = false
+ * @memberOf Traverse
+ * @method
+ *
+ * @return {void}
+ *
+ * @example
+ *
+ * traverse({eh: true, arr: []}).forEach((key, val, t) => {
+ * if (isArray(val)) this.stop()
+ * })
+ *
+ */
+ Traverse.prototype.stop = function stop() {
+ this.isAlive = false;
+ // this.release()
+ };
+
+ /**
+ * @TODO skip 1 branch
+ * @version 5.0.0
+ * @since 3.0.0
+ * @memberOf Traverse
+ * @method
+ *
+ * @return {void}
+ *
+ * @example
+ *
+ * traverse([1, 2, 3, [4]]).forEach((key, val, t) => {
+ * if (isArray(val)) t.skip()
+ * })
+ *
+ */
+ Traverse.prototype.skip = function skip() {
+ this.skipBranch = true;
+ };
+
+ /* prettier-ignore */
+ /**
+ * @desc checks whether a node is iteratable
+ * @modifies Traverse.isIteratable
+ * @modifies Traverse.isLeaf
+ * @modifies Traverse.isCircular
+ *
+ * @memberOf Traverse
+ * @protected
+ * @method
+ *
+ * @param {*} node value to check
+ * @return {void}
+ *
+ * @TODO move into the wrapper? if perf allows?
+ *
+ * @example
+ *
+ * .checkIteratable({eh: true})
+ * //=> this.isLeaf = false
+ * //=> this.isCircular = false
+ * //=> this.isIteratable = true
+ *
+ * .checkIteratable({} || [])
+ * //=> this.isLeaf = true
+ * //=> this.isCircular = false
+ * //=> this.isIteratable = false
+ *
+ * var circular = {}
+ * circular.circular = circular
+ * .checkIteratable(circular)
+ * //=> this.isLeaf = false
+ * //=> this.isCircular = true
+ * //=> this.isIteratable = true
+ *
+ */
+ Traverse.prototype.checkIteratable = function check(node) {
+ this.isIteratable = iteratable(node);
+ // just put these as an array?
+ if (_true(this.isIteratable)) {
+ // native = leaf if not root
+ this.isLeaf = false;
+ var path = this.path.join('.');
+
+ if (this.hasParent(path, node)) {
+ /* istanbul ignore next: dev */
+ if (ENV_DEBUG) {
+ console.log('circular___________', {node: node, path: this.path});
+ }
+ this.isCircular = true;
+ }
+ else {
+ this.addParent(path, node);
+ this.isCircular = false;
+ }
+
+ /* istanbul ignore next: dev */
+ if (ENV_DEBUG) {
+ // console.log('IS_CIRCULAR_JSON', isCircular(node), this.isCircular, node)
+ }
+ }
+ else {
+ this.isLeaf = true;
+ this.isCircular = false;
+ }
+ };
+
+ /* prettier-ignore */
+ /**
+ * Remove the current element from the output.
+ * If the node is in an Array it will be spliced off.
+ * Otherwise it will be deleted from its parent.
+ *
+ * @memberOf Traverse
+ * @version 5.0.0
+ * @since 2.0.0
+ * @method
+ *
+ * @param {undefined | Object} [arg] optional obj to use, defaults to this.node
+ * @return {void}
+ *
+ * @example
+ *
+ * traverse([0]).forEach((key, val, it) => it.remove())
+ * //=> []
+ *
+ * traverse({eh: true}).forEach((key, val, it) => it.remove())
+ * //=> {}
+ *
+ * traverse({eh: true, str: 'stringy'}).forEach((key, val, it) => {
+ * if (!isString(val)) it.remove()
+ * })
+ * //=> {str: 'stringy'}
+ *
+ */
+ Traverse.prototype.remove = function removes(arg) {
+ // ignore undefined & non-object/arrays
+ if (_undefined(this.key)) { return }
+ var obj$$2 = arg || this.node;
+ if (!obj(obj$$2)) { return }
+
+ /* istanbul ignore next: dev */
+ if (ENV_DEBUG) {
+ console.log('remove');
+ console.log({parent: this.parent, key: this.key, obj: obj$$2});
+ }
+
+ this.removeParent(obj$$2);
+ this.skip();
+
+ delete obj$$2[this.key];
+ delete this.parent[this.key];
+
+ /* istanbul ignore next: dev */
+ if (ENV_DEBUG) {
+ console.log('traverse:remove:', this.key, {obj: obj$$2, iteratee: this.node});
+ }
+ };
+
+ /**
+ * @desc update the value for the current key
+ * @version 5.0.0
+ * @since 2.0.0
+ * @memberOf Traverse
+ *
+ * @param {*} value this.node[this.key] = value
+ * @return {void}
+ *
+ * @example
+ *
+ * traverse({eh: true})
+ * .forEach((key, val, traverser) => {
+ * if (this.isRoot) return
+ * traverser.update(false)
+ * })
+ * //=> {eh: false}
+ *
+ */
+ Traverse.prototype.update = function update(value) {
+ set$2(this.root, this.path, value);
+ };
+
+ /**
+ * @desc mark the iteration as done, clear the map
+ * @NOTE this recycles the instance in the pooler to re-use allocated objects
+ * @memberOf Traverse
+ * @private
+ * @since 5.0.0
+ *
+ * @return {void}
+ *
+ * @see Traverse.iterate
+ *
+ * @example
+ *
+ * traverse([]).destructor()
+ *
+ */
+ Traverse.prototype.destructor = function destructor() {
+ this.node = undefined;
+ this.parent = undefined;
+ this.reset();
+
+ this.clear();
+ };
+
+ /* prettier-ignore */
+ /**
+ * @TODO handler for Set & Map so they can be skipped or traversed, for example when cloning...
+ * @TODO add hook to add custom checking if isIteratable
+ * @TODO deal with .isRoot if needed
+ * @TODO examples with clone and stop
+ *
+ * @memberOf Traverse
+ * @protected
+ * @sig on(key: null | Primitive, val: any, instance: Traverse): any
+ *
+ * @param {Function} on callback fn for each iteration
+ * @return {*} this.node
+ *
+ * @example
+ *
+ * iterate([])
+ * //=> []
+ * //=> on(null, [])
+ *
+ * @example
+ *
+ * iterate([1])
+ * //=> [1]
+ * //=> on(null, [1])
+ * //=> on('1', 1)
+ *
+ * @example
+ *
+ * //primitive - same for any number, string, symbol, null, undefined
+ * iterate(Symbol('eh'))
+ * //=> Symbol('eh')
+ * //=> on(Symbol('eh'))
+ *
+ * @example
+ *
+ * var deeper = {eh: 'canada', arr: [{moose: true}, 0]}
+ * iterate(deeper)
+ * //=> deeper // returns
+ * //=> on(null, deeper, this) // root
+ *
+ * //=> on('eh', 'canada', this) // 1st branch
+ *
+ * //=> on('arr', [{moose: true}, 0], this)
+ * //=> on('arr.0', [{moose: true}], this)
+ * //=> on('arr.0.moose', true, this)
+ * //=> on('arr.1', [0], this)
+ *
+ *
+ */
+ Traverse.prototype.iterate = function iterate(on) {
+ var this$1 = this;
+
+ /* istanbul ignore next : dev */
+ if (ENV_DEBUG) {
+ // require('fliplog')
+ // .bold(this.path.join('.'))
+ // .data(parents.keys())
+ // .echo()
+ console.log('\n...iterate...\n');
+ }
+
+ if (this.isAlive === false) {
+ /* istanbul ignore next : dev */
+ if (ENV_DEBUG) {
+ console.log('DEAD');
+ }
+
+ return Traverse.release(this)
+ }
+
+ var node = this.node;
+
+ // convert to iteratable
+ if (map(node)) {
+ node = index$4(node);
+ }
+ else if (set(node)) {
+ node = toArr(node);
+ }
+
+ // @TODO: maybe only right before sub-loop
+ this.addParent(this.depth, node);
+
+ var nodeIsArray = array(node);
+ var nodeIsObj = nodeIsArray || obj(node);
+
+ // ---
+
+ // @event
+ if (!_undefined(this.onBefore)) {
+ // eslint-disable-next-line no-useless-call
+ this.onBefore(this);
+ }
+
+ /* istanbul ignore next : dev */
+ if (ENV_DEBUG) {
+ // const str = require('pretty-format')({nodeIsObj, nodeIsArray, node})
+ // require('fliplog').verbose(1).data({nodeIsObj, nodeIsArray, node}).echo()
+ // console.log(node, parents)
+ // console.log(str)
+ console.log({nodeIsObj: nodeIsObj, nodeIsArray: nodeIsArray, node: node});
+ }
+
+ /**
+ * call as root, helpful when we
+ * - iterate something with no keys
+ * - iterate a non-iteratable (symbol, error, native, promise, etc)
+ */
+ if (_true(this.isRoot)) {
+ on.call(this, null, node, this);
+ this.isRoot = false;
+ }
+
+ var isObjOrArray = nodeIsArray || nodeIsObj;
+
+ // if (isObjOrArray) {
+ // // @event
+ // if (!isUndefined(this.onBefore)) {
+ // // eslint-disable-next-line no-useless-call
+ // this.onBefore(this)
+ // }
+ // }
+
+ // --------------------
+ // IF OBJWITHOUTKEYS, IF ARRAY WITHOUT LENGTH...
+ if (isObjOrArray && empty(node)) {
+ on.call(this, this.key, node, this);
+ this.node = node;
+ }
+
+ // --------------------
+
+ else if (isObjOrArray) {
+ this.depth = this.path.length;
+
+ // @TODO SAFETY WITH `props(node)` <- fixes Error
+ var keys$$2 = nodeIsArray ? node : keys(node);
+
+ /* istanbul ignore next : dev */
+ if (ENV_DEBUG) {
+ console.log({keys: keys$$2});
+ // require('fliplog').verbose(1).data(this).echo()
+ }
+
+ // @event
+ // if (!isUndefined(this.onBefore)) this.onBefore()
+
+ // @NOTE: safety here
+ // this.checkIteratable(node)
+
+ // const last = keys[keys.length - 1]
+
+ // @loop
+ for (var key = 0; key < keys$$2.length; key++) {
+ // if (ENV_DEBUG)
+ // console.log('iterating:', {key})
+
+ // --- safety ---
+ if (this$1.isAlive === false) {
+ /* istanbul ignore next : dev */
+ if (ENV_DEBUG) {
+ console.log('DEAD');
+ }
+
+ return Traverse.release(this$1)
+ }
+
+ // @NOTE: look above add prev add parent
+ // addParent(this.depth, node)
+
+
+ // ----- setup our data ----
+
+ // to make it deletable
+ if (node !== this$1.node) { this$1.parent = node; }
+
+ this$1.key = nodeIsArray ? key : keys$$2[key];
+ // this.isLast = key === last
+
+ /* istanbul ignore next: dev */
+ if (ENV_DEBUG) {
+ console.log('alive', this$1.key);
+ }
+
+ // @event
+ if (!_undefined(this$1.onPre)) {
+ // eslint-disable-next-line no-useless-call
+ this$1.onPre(this$1);
+ }
+
+
+ var value = node[this$1.key];
+
+ this$1.checkIteratable(value);
+ // addParent(value)
+ var pathBeforeNesting = this$1.path.slice(0);
+
+ // @NOTE: can go forward-backwards if this is after the nested iterating
+ this$1.path.push(this$1.key);
+ this$1.depth = this$1.path.length;
+
+ // ----- continue events, loop deeper when needed ----
+
+ // @NOTE since we check isAlive at the beginning of each loop
+ // could use .skip alongisde .stop
+ // @TODO @IMPORTANT @HACK @FIXME right here it should also handle the .stop
+ on.call(this$1, this$1.key, value, this$1);
+ if (_true(this$1.skipBranch)) {
+ this$1.skipBranch = false;
+ continue
+ }
+
+ /* istanbul ignore next: dev */
+ if (ENV_DEBUG) {
+ // require('fliplog').data(parents).echo()
+ // require('fliplog').data(this).echo()
+ }
+
+ // handle data
+ if (_true(this$1.isCircular)) {
+ /* istanbul ignore next: dev */
+ if (ENV_DEBUG) {
+ console.log('(((circular)))', this$1.key);
+ }
+
+ // on.call(this, this.key, value, this)
+ // this.path.pop()
+ this$1.path = pathBeforeNesting;
+
+ // this.isCircular = false
+ // break
+ continue
+ // return
+ }
+
+
+ // &&
+ if (_true(this$1.isIteratable)) {
+ /* istanbul ignore next: dev */
+ if (ENV_DEBUG) {
+ console.log('(((iteratable)))', this$1.key);
+ }
+
+ this$1.node = value;
+ this$1.iterate(on);
+ this$1.path = pathBeforeNesting;
+ }
+
+ /* istanbul ignore next: dev */
+ if (ENV_DEBUG) {
+ if (this$1.isIteratable === false) {
+ console.log('not iteratable', this$1.key);
+ }
+
+ console.log('----------------- post ----------', node);
+ }
+
+ // @event
+ if (!_undefined(this$1.onPost)) {
+ // eslint-disable-next-line no-useless-call
+ this$1.onPost(this$1);
+ }
+
+ // cleanup, backup 1 level
+ this$1.path.pop();
+
+ this$1.removeParent(node);
+ }
+
+ // this.path.pop()
+ this.depth = this.path.length;
+ }
+ else {
+ // this.isLast = false
+ on.call(this, this.depth, node, this);
+ }
+
+ // @NOTE: careful
+ // removeParent(node)
+
+ // @NOTE: just for .after ?
+ this.node = node;
+
+ // @event
+ if (!_undefined(this.onAfter)) {
+ // eslint-disable-next-line no-useless-call
+ this.onAfter(this);
+ }
+
+ this.path.pop();
+
+ return this.node
+ };
+
+ // is smaller, but probably slower
+ // function onEvent(property) {
+ // return function(fn) {
+ // this[property] = function
+ // }
+ // }
+
+ // when it's some sort of itertable object, loop it further
+ // @TODO: need to handle these better without totally messing with bad scope
+ Traverse.prototype.pre = function(fn) {
+ this.onPre = fn;
+ };
+ Traverse.prototype.post = function(fn) {
+ this.onPost = fn;
+ };
+ Traverse.prototype.before = function(fn) {
+ this.onBefore = fn;
+ };
+ Traverse.prototype.after = function(fn) {
+ this.onAfter = fn;
+ };
+
+ // -----------------------
+
+ /**
+ * @TODO merge with dopemerge?
+ * @TODO needs tests converted back for this (observe tests do cover somewhat)
+ *
+ * @param {*} arg defaults to this.node
+ * @return {*} cloned
+ *
+ * @example
+ *
+ * var obj = {}
+ * var cloned = traverse().clone(obj)
+ * obj.eh = true
+ * eq(obj, cloned)
+ * //=> false
+ *
+ */
+ Traverse.prototype.clone = clone;
+
+ /**
+ * @todo ugh, how to clone better with *recursive* objects?
+ * @param {any} src wip
+ * @return {any} wip
+ */
+ Traverse.prototype.copy = copy;
+
+ /**
+ * @desc clone any value
+ * @version 5.0.0
+ * @since 4.0.0
+ * @memberOf Traverse
+ * @extends copy
+ * @extends Traverse
+ *
+ * @param {*} arg argument to clone
+ * @return {*} cloned value
+ *
+ * @see dopemerge
+ *
+ * @example
+ *
+ * var obj = {eh: true}
+ * clone(obj) === obj //=> false
+ *
+ * var obj = {eh: true}
+ * var obj2 = clone(obj)
+ * obj.eh = false
+ * console.log(obj2.eh) //=> true
+ *
+ */
+ function clone(arg) {
+ var obj$$2 = _undefined(arg) ? this.node : arg;
+ if (primitive$2(obj$$2)) { return obj$$2 }
+ var cloned = emptyTarget(obj$$2);
+ var current = cloned;
+
+ traverse(obj$$2).forEach(function (key, value, traverser) {
+ // t.isRoot
+ if (_null(key)) { return }
+
+ var copied = copy(value);
+ if (traverser.isCircular && array(value)) { copied = value.slice(0); }
+ set$2(current, traverser.path, copied);
+ });
+
+ return cloned
+ }
+
+ // @TODO could just have traverse = Traverse.getPooled ?
+ pooler(Traverse);
+ function traverse(value) {
+ return Traverse.getPooled(value)
+ }
+
+ traverse.eq = _eq(traverse);
+ traverse.clone = clone;
+ traverse.copy = copy;
+ var traverse_1 = traverse;
+
+ var index$10 = new Map();
+
+ /* ___filename___: dist/deps/traverse.js */
+
+ /* ___filename___: dist/deps/dot/paths.js */
+
+
+
+
+
+
+ var run = 0;
+
+ /* prettier-ignore */
+ /**
+ * @desc gathers dot.prop from any value, with a prefixed/base key
+ * @since 4.0.0
+ *
+ * @param {Primitive} key prefixing key for the paths, root path/key
+ * @param {Traversable} value traversable value to extract paths from
+ * @param {boolean | undefined} [longest] optionally filter to keep only longest/deepest paths
+ * @return {Array} paths[]
+ *
+ * @see deps/traverse
+ * @TODO should build a trie if doing this
+ * @NOTE had `onlyLongest` & `asString` but can just .join(',') to match
+ *
+ * @example
+ *
+ * dotPropPaths('', {oh: {eh: true}})
+ * //=> ['oh.eh']
+ *
+ * dotPropPaths('moose', {oh: {eh: true}})
+ * //=> ['moose.oh.eh']
+ *
+ */
+ var paths = function(key, value, longest) {
+ // if (cache.has(value)) return cache.get(value)
+
+ var paths = [];
+
+ /* istanbul ignore next: debug */
+ if (debug) {
+ console.log({value: value});
+ }
+
+ // gather all paths in the object
+ // filter to ensure only the longest paths are kept
+ //
+ // .map the paths to `dot-prop`,
+ // `matcher` takes in an array so it will work for all
+ traverse_1(value).forEach(function(x) {
+ // const currentPath = this.paths
+ var currentPath = this.path;
+
+ /* istanbul ignore next: debug */
+ if (debug) {
+ console.log('paths', run++, this.path);
+ }
+
+ // ignore
+ if (!currentPath) { return }
+ else if (!currentPath.length) { return }
+
+ // dot-prop the array of paths
+ // if we have a key, prefix it
+ paths.push(
+ (key ? key + '.' : '') +
+ (currentPath.join ? currentPath.join('.') : currentPath)
+ );
+ });
+
+ if (_true(longest)) {
+ // concat a string of all paths so we can unique each branch
+ // @example `canada.arr.0` vs `canada.arr`
+ paths = paths.filter(function (path) { return !paths.some(function (otherPath) { return otherPath !== path && index$8(otherPath, path); }
+ ); });
+ }
+
+ // cache.set(value, paths)
+
+ return paths
+ };
+
+ /* ___filename___: dist/deps/native/propertyIsEnumerable.js */
+ var propertyIsEnumerable_1 = Object.prototype.propertyIsEnumerable;
+
+ /* ___filename___: dist/deps/native/propertyIsEnumerable.js */
+
+ /* ___filename___: dist/deps/is/enumerable.js */
+
+
+
+ /**
+ * @desc object at property is enumerable
+ * @memberOf is
+ * @since 3.0.0
+ *
+ * @param {Object | *} obj
+ * @param {string | *} prop
+ * @return {boolean} obj[prop] is enumerable
+ *
+ * @func
+ * @name isEnumerable
+ * @type {Function}
+ *
+ * {@link https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/propertyIsEnumerable mozilla-propertyisenumerable}
+ * @see {@link mozilla-propertyisenumerable}
+ *
+ * @TODO use fp/call
+ *
+ * @example
+ *
+ * const obj = {eh: true}
+ * isEnumerable(obj, 'eh')
+ * //=> true
+ *
+ * const objPropEnumerable = isEnumerable(obj)
+ * objPropEnumerable('eh')
+ * //=> true
+ *
+ * Object.defineProperty(obj, 'length', {
+ * enumerable: false,
+ * value: () => Object.keys(obj).length,
+ * })
+ * isEnumerable(obj, 'length')
+ * //=> false
+ *
+ */
+ var enumerable = curry(2, function (obj, prop) { return propertyIsEnumerable_1.call(obj, prop); });
+
+ /* ___filename___: dist/deps/is/enumerable.js */
+
+ /* ___filename___: dist/deps/dot/get.js */
+
+
+
+
+
+
+
+ /**
+ * @name dot.get
+ * @memberOf dot
+ * @func
+ * @since 3.0.0
+ * @extends dot/getPathSegments
+ *
+ * @param {Object} obj the object to retrieve the nested property from.
+ * @param {Dottable | string | Array} path dot-prop-path to use
+ * @param {*} fallback use when there is no value at specified path
+ * @return {*} value at path or fallback
+ *
+ * @example
+ *
+ * dot.get({a: {b: 2}}, 'a.b'); //=> 2
+ * dot.get({a: {b: 2}}, ['a', 'b']); //=> 2
+ * dot.get({c: {b: 2}}, ['a', 'b']); //=> undefined
+ *
+ */
+ var get = function(obj, path, fallback) {
+ if (!dottable(obj, path)) {
+ return _undefined(fallback) ? obj : fallback
+ }
+
+ var pathArr = segments(path);
+
+ for (var i = 0; i < pathArr.length; i++) {
+ if (!enumerable(obj, pathArr[i])) {
+ return fallback
+ }
+
+ obj = obj[pathArr[i]];
+
+ if (nullOrUndefined(obj)) {
+ /*
+ * `obj` is either `undefined` or `null` so we want to stop the loop, and
+ * if this is not the last bit of the path, and
+ * if it did't return `undefined`
+ * it would return `null` if `obj` is `null`
+ * but we want `get({foo: null}, 'foo.bar')` to equal `undefined`, or the supplied fallback, not `null`
+ */
+ if (i !== lengthMinusOne(pathArr)) {
+ return fallback
+ }
+
+ break
+ }
+ }
+
+ return obj
+ };
+
+ /* ___filename___: dist/deps/is/number.js */
+
+
+
+ /**
+ * @param {*} x value
+ * @return {boolean} isNumber
+ *
+ * @since 3.0.0
+ * @memberOf is
+ * @func isNumber
+ * @see is/real
+ * @extends numberPrimitive
+ * @variation also returns true for new Number object
+ *
+ * @see http://stackoverflow.com/questions/18082/validate-decimal-numbers-in-javascript-isnumeric
+ * @alternate !isNaN(parseFloat(n)) && isFinite(n)
+ *
+ * @example
+ *
+ * isNumber(1)
+ * //=> true
+ * isNumber(new Number(1))
+ * //=> true
+ * isNumber(Number(1))
+ * //=> true
+ * isNumber(NaN)
+ * //=> true
+ *
+ * isNumber(null)
+ * //=> false
+ * isNumber(undefined)
+ * //=> false
+ * isNumber(void 0)
+ * //=> false
+ * isNumber({})
+ * //=> false
+ * isNumber('')
+ * //=> false
+ * isNumber(false)
+ * //=> false
+ *
+ * @NOTE was not needed except for abstract ==
+ * const isObj = require('./obj')
+ * const isSymbol = require('./symbol')
+ * (isObj(x) || isSymbol(x)
+ * ? false
+ * : (/^0x[0-9a-f]+$/i).test(x) ||
+ * (/^[-+]?(?:\d+(?:\.\d*)?|\.\d+)(e[-+]?\d+)?$/).test(x))
+ *
+ */
+ var number = function (x) { return numberPrimitive(x) || toS(x) === '[object Number]'; };
+
+ /* ___filename___: dist/deps/is/number.js */
+
+ /* ___filename___: dist/deps/is/stringOrNumber.js */
+
+
+
+
+ /**
+ * Checks if `value` is classified as a `String` primitive or object.
+ *
+ * @since 3.0.0
+ * @category Lang
+ * @memberOf is
+ * @param {*} x The value to check.
+ * @return {boolean} Returns `true` if `value` is a string, else `false`.
+ *
+ * @see https://github.com/infernojs/inferno/blob/master/packages/inferno-shared/src/index.ts#L23
+ * @see https://github.com/lodash/lodash/blob/master/isString.js
+ *
+ * @example
+ *
+ * isString('abc')
+ * // => true
+ *
+ * isString(1)
+ * // => false
+ */
+ var stringOrNumber = or(string, number);
+
+ /* ___filename___: dist/deps/is/real.js */
+
+
+ /**
+ * @param {*} x value
+ * @return {boolean} isReal
+ *
+ * @since 3.0.0
+ * @memberOf is
+ * @func isReal
+ * @see is/null
+ * @see is/undefined
+ *
+ * @see http://2ality.com/2013/04/quirk-implicit-conversion.html
+ * @see https://javascriptrefined.io/nan-and-typeof-36cd6e2a4e43
+ * @see https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/isNaN
+ *
+ * @NOTE eslint-disable-next-line no-self-compare
+ * && x !== x
+ *
+ * @extends isNullOrUndefined
+ * @variation *not* isNullOrUndefined && false for NaN
+ *
+ * @example
+ *
+ * isReal(null)
+ * //=> false
+ * isReal(void 0)
+ * //=> false
+ * const nan = Number(undefined)
+ * isReal(nan)
+ * //=> false
+ *
+ * isReal({eh: true})
+ * //=> true
+ * isReal({})
+ * //=> true
+ * isReal(Object)
+ * //=> true
+ * isReal([])
+ * //=> true
+ * isReal(new Set())
+ * //=> true
+ * isReal(function() {})
+ * //=> true
+ * isReal('')
+ * //=> true
+ * isReal(1)
+ * //=> true
+ *
+ */
+ var real = function (x) { return !nullOrUndefined(x) && !Number.isNaN(x); };
+
+ /* ___filename___: dist/deps/is/stringOrNumber.js */
+
+ /* ___filename___: dist/deps/is/real.js */
+
+ /* ___filename___: dist/deps/is/notNested.js */
+
+
+
+
+
+
+ /**
+ * @since 5.0.0
+ * @param {*} x value to check
+ * @return {boolean} x isNotNested
+ *
+ * @example
+ *
+ * isNotNested('') //=> true
+ * isNotNested(true) //=> true
+ * isNotNested(new RegExp()) //=> true
+ * isNotNested(new Error('eh')) //=> false
+ * isNotNested(null) //=> false
+ *
+ */
+ var notNested = function isNotNested(x) {
+ return (
+ stringOrNumber(x) ||
+ boolean_1(x) ||
+ !real(x) ||
+ error$1(x) ||
+ regexp(x)
+ )
+ };
+
+ /* ___filename___: dist/deps/is/objPure.js */
+
+
+
+
+
+ /**
+ * @name isObjPure
+ * @memberOf is
+ * @alias isObjNotArrayOrFunction
+ * @since 3.0.0
+ *
+ *
+ * @param {*} x value to check
+ * @return {boolean} is obj & !null & !undefined & !array & !function
+ *
+ * @extends isArray
+ * @extends isObjTypeof
+ * @extends isNullOrUndefined
+ * @extends isFunction
+ *
+ * @example
+ *
+ * isObjPure(function() {})
+ * //=> false
+ * isObjPure(null)
+ * //=> false
+ * isObjPure([])
+ * //=> false
+ *
+ * isObjPure({})
+ * //=> true
+ *
+ */
+ var objPure = function (x) { return !nullOrUndefined(x) && !array(x) && !_function(x) && objTypeof(x); };
+
+ /* ___filename___: dist/deps/is/objWithKeys.js */
+
+
+
+ /**
+ * @TODO @NOTE need to be more careful, needs to check for vanilla objects, not native ones since e.g. Error has no keys
+ *
+ * @param {*} x value
+ * @return {boolean} isObjWithKeys
+ *
+ * @since 3.0.0
+ * @memberOf is
+ * @func isObjWithKeys
+ * @see is/obj
+ * @see is/objWithKeys
+ * @see is/objStrict
+ * @see is/null
+ *
+ * @extends isObj
+ * @variation Object.keys(obj).length !== 0
+ *
+ * @example
+ *
+ * isObjWithKeys({eh: true})
+ * //=> true
+ * isObjWithKeys({})
+ * //=> false
+ * isObjWithKeys(new Object())
+ * //=> false
+ * isObjWithKeys(Object.create(null))
+ * //=> false
+ * isObjWithKeys(null)
+ * //=> false
+ * isObjWithKeys(new Set())
+ * //=> false
+ * isObjWithKeys(function() {})
+ * //=> false
+ * isObjWithKeys('')
+ * //=> false
+ * isObjWithKeys(1)
+ * //=> false
+ *
+ */
+ var objWithKeys = function (val) { return obj(val) && keys(val).length !== 0; };
+
+ /* ___filename___: dist/deps/is/matcher.js */
+
+
+
+
+ /**
+ * @func isMatcher
+ * @memberOf is
+ * @since 3.0.0
+ *
+ * @param {*} x value to check
+ * @return {boolean} isFunction || isRegExp
+ *
+ * @see is/regexp
+ * @see is/function
+ * @see conditionals/or
+ *
+ * @example
+ *
+ * isMatcher(/(.*)/)
+ * //=> true
+ *
+ * isMatcher(x => true)
+ * //=> true
+ *
+ * isMatcher(1)
+ * //=> false
+ * isMatcher('.*')
+ * //=> false
+ *
+ */
+ var matcher = or(_function, regexp); // x => isFunction(x) || isRegExp(x)
+ // x instanceof RegExp
+
+ /* ___filename___: dist/deps/is/objPure.js */
+
+ /* ___filename___: dist/deps/is/objWithKeys.js */
+
+ /* ___filename___: dist/deps/is/matcher.js */
+
+ // dont need these yet
+
+
+ // const isClass = require('./class')
+ // const isEnumerable = require('./enumerable')
+ // const isMapish = require('./mapish')
+
+ /**
+ * @member is
+ * @types is
+ * @tests is/*
+ *
+ * @see https://github.com/lodash/lodash/issues/3237
+ * @type {Object}
+ */
+ var index$12 = {
+ isObjWithKeys: objWithKeys,
+ isObj: obj,
+ // isObject: isObj,
+ isObjPure: objPure,
+ isObjNotNull: objNotNull,
+ isFunction: _function,
+ isReal: real,
+ toS: toS,
+ isDate: date,
+ isRegExp: regexp,
+ isError: error$1,
+ isBoolean: boolean_1,
+ isNumber: number,
+ isString: string,
+ isMap: map,
+ isSet: set,
+ isSymbol: symbol,
+ isPrototypeOf: prototypeOf,
+ isArray: array,
+ // new
+ isIterator: iterator$2,
+ isUndefined: _undefined,
+ isNull: _null,
+ isNill: nullOrUndefined,
+ isTrue: _true,
+ isMatcher: matcher,
+ };
+
+ /* ___filename___: dist/deps/string/camelCase.js */
+ /* prettier-ignore */
+ /**
+ * @desc camelCase
+ * @since 0.2.0
+ * @symb 🐫
+ *
+ * @param {string} str string to turn into camelCase
+ * @return {string} camelCased string
+ *
+ * @tutorial https://github.com/substack/camelize/blob/master/test/camel.js
+ * @tutorial https://github.com/andrewplummer/Sugar/blob/9c018a257a38714b81f7df033b74d236dbf1e861/lib/string.js
+ * @tutorial http://stackoverflow.com/questions/2970525/converting-any-string-into-camel-case
+ * @tutorial https://github.com/sindresorhus/camelcase
+ * @see https://stackoverflow.com/questions/1533131/what-useful-bitwise-operator-code-tricks-should-a-developer-know-about
+ * @TODO s.charAt(0).toLowerCase() + string.slice(1)
+ *
+ * @types deps
+ * @tests deps/camelCase
+ *
+ * @example
+ *
+ * camelCase('snake_case')
+ * //=> 'snakeCase'
+ *
+ */
+ var camelCase = function (str) { return str
+ // spaces with underscore
+ .replace(/\s+/g, '_')
+ // < underscores & dashes until whitespace or end
+ // > .toUpperCase x & '_'
+ .replace(/[_.-](\w|$)/g, function (m, x) { return x.toUpperCase(); }); };
+
+ /* ___filename___: dist/deps/conditional/not.js */
+
+
+ /**
+ * return a negated function
+ * A function wrapping a call to the given function in a `!` operation.
+ * It will:
+ * - return `true` when the underlying function would return a false-y value,
+ * - and `false` when it would return a truth-y one.
+ *
+ * @name not
+ * @memberOf conditional
+ * @since 4.0.1
+ * @func
+ *
+ * @param {Function} fn any function
+ * @param {*} x value to pass to function
+ * @return {Function} !Function(x)
+ *
+ * @example
+ *
+ * const falsed = not(x => true)
+ * const trued = not(x => false)
+ *
+ * trued()
+ * //=> true
+ *
+ * falsed()
+ * //=> false
+ *
+ */
+ var not = function (fn, x) { return !fn(x); };
+ var not_1 = curry(2, not);
+
+ // curry(2,
+ // function not(predicate) {
+ // return function() {
+ // return !predicate.apply(this, arguments)
+ // }
+ // }
+
+ /* ___filename___: dist/deps/conditional/and.js */
+
+
+ /**
+ * @desc first fn & second fn
+ * @memberOf conditional
+ * @since 4.0.1
+ *
+ * @param {Function} left first fn
+ * @param {Function} right second fn
+ * @return {Function | boolean} both functions return truthy @curried
+ *
+ * @curried
+ * @name and
+ * @alias both
+ * @func
+ *
+ * @example
+ *
+ * const both = and(x => typeof x === 'boolean', x => x === true)
+ *
+ * both([true])
+ * //=> true
+ *
+ * both([false])
+ * //=> false
+ *
+ * both([1])
+ * //=> false
+ *
+ */
+ var and = function (left, right) { return function (x) { return left(x) && right(x); }; };
+ var and_1 = curry(2, and);
+
+ /* ___filename___: dist/deps/conditional/all.js */
+
+
+ /**
+ * map all values in an array to see if all match
+ * Returns `true` if all elements of the list match the predicate, `false` if there are any that don't.
+ *
+ * @name all
+ * @memberOf conditional
+ * @since 4.0.1
+ *
+ * @TODO `not(some)` ?
+ *
+ * @curried
+ * @param {Function} predicate match the value
+ * @param {Array} list to match against predicate
+ * @return {boolean} all match predicate
+ *
+ * {@link https://github.com/ramda/ramda/blob/master/src/all.js ramda-all}
+ * @see {@link ramda-all}
+ * @see fp/curry
+ *
+ * @sig (a -> Boolean) -> [a] -> Boolean
+ *
+ * @example
+ *
+ * const allBoolean = all(x => typeof x === 'boolean'q)
+ *
+ * allBoolean([true])
+ * //=> true
+ *
+ * allBoolean([1])
+ * //=> false
+ *
+ */
+ var all = curry(2, function (predicate, list) {
+ for (var i in list) {
+ if (!predicate(list[i])) { return false }
+ }
+ return true
+ });
+
+ var all_1 = all;
+
+ /* ___filename___: dist/deps/conditional/and.js */
+
+ /* ___filename___: dist/deps/conditional/all.js */
+
+ /* ___filename___: dist/deps/is/arrayOf.js */
+
+
+
+
+ /**
+ * @desc every item in an array matches predicate
+ * @since 4.0.0 was in validatorBuilder
+ * @version 5.0.0
+ *
+ * @memberOf is
+ * @param {Function} predicate test to pass on every item in an array
+ * @return {boolean} all match predicate
+ *
+ * @example
+ *
+ * isArrayOf(isTrue)([true, true]) //=> true
+ * isArrayOf(isEmpty)(['']) //=> true
+ *
+ * isArrayOf(isBoolean)([true, false, 1, 2, 0]) //=> false
+ * isArrayOf(isString)(['string', Number]) //=> false
+ *
+ */
+ var arrayOf = function isArrayOf(predicate) {
+ return and_1(array, all_1(predicate))
+ };
+
+ /* ___filename___: dist/deps/conditional/not.js */
+
+ /* ___filename___: dist/deps/is/notRealOrIsEmpty.js */
+
+
+
+
+
+ /**
+ * @SIZE: another 10bytes for these fns
+ * @name isNotRealOrIsEmpty
+ *
+ * @see is/isReal
+ * @see is/isEmpty
+ * @see conditional/and
+ * @see conditional/not
+ *
+ * @type {Function}
+ */
+ var notRealOrIsEmpty = and_1(not_1(real), empty);
+
+ /* ___filename___: dist/deps/fp/replace.js */
+
+
+ /**
+ * Replace a substring or regex match in a string with a replacement.
+ *
+ * @func
+ * @memberOf fp
+ * @since v5.0.0
+ * @category String
+ * @sig RegExp|String -> String -> String -> String
+ *
+ * @param {RegExp|String} pattern A regular expression or a substring to match.
+ * @param {String} replacement The string to replace the matches with.
+ * @param {String} str The String to do the search and replacement in.
+ * @return {String} The result.
+ *
+ * @types fp
+ * @tests fp/replace
+ *
+ * {@link https://github.com/ramda/ramda/blob/master/src/replace.js ramda-replace}
+ * {@link https://github.com/lodash/lodash/blob/master/replace.js lodash-replace}
+ * @see {@link ramda-replace}
+ * @see {@link lodash-replace}
+ *
+ * @example
+ *
+ * replace('foo', 'bar', 'foo foo foo'); //=> 'bar foo foo'
+ * replace(/foo/, 'bar', 'foo foo foo'); //=> 'bar foo foo'
+ *
+ * // Use the "g" (global) flag to replace all occurrences:
+ * replace(/foo/g, 'bar', 'foo foo foo'); //=> 'bar bar bar'
+ *
+ */
+ var replace = curry(3, function replace(pattern, replacement, str) {
+ return str.replace(pattern, replacement)
+ });
+
+ /* ___filename___: dist/ChainedMapBase.js */
+
+ /* ___filename___: dist/deps/string/camelCase.js */
+
+ /* ___filename___: dist/deps/is/arrayOf.js */
+
+ /* ___filename___: dist/deps/is/notRealOrIsEmpty.js */
+
+ /* ___filename___: dist/deps/fp/replace.js */
+
+ /* ___filename___: dist/deps/validators/validatorBuilder.js */
+ /**
+ * @since 4.0.0 <- moved out of the store, into scoped
+ * @since 1.0.0
+ * @desc library of validators to use by name
+ * @modifies this.validators
+ * @param {Object} validators
+ */
+
+
+
+
+
+
+
+
+
+
+
+
+
+ var validators = new ChainedMapBase();
+
+ // eslint-disable-next-line
+ var stripArithmeticSymbols = replace(/[?\[\]!\|]/g, '');
+ var escapedKey = function (x) { return camelCase('is-' + x); };
+ var enummy = function (enums) { return function (x) { return enums === x || enums.includes(x); }; };
+
+ // @TODO: .remap!!!
+ // @TODO: can use these to return noops with error logging on development
+ var get$2 = function (key) { return validators.get(key) || validators.get(escapedKey(key)) || enummy(key); };
+ var has = function (key) { return validators.has(key) || validators.get(escapedKey(key)); };
+ var set$4 = function (key, value) { return validators.set(key, value); };
+ var doesNotHave = not_1(has);
+
+ /**
+ * @desc add custom types for validation
+ * @category types
+ * @category schema
+ * @types schema
+ *
+ * @since 4.0.0 <- used with schema, used in method chain
+ * @since 3.0.0 <- took out
+ * @since 1.0.0
+ *
+ * @param {Object} types custom Types
+ *
+ * @see deps/validators/validatorFactory
+ *
+ * @example
+ *
+ * addTypes({yaya: x => typeof x === 'string'})
+ *
+ * const chain = new Chain().methods('eh').type('yaya').build()
+ *
+ * chain.eh('good')
+ * //=> chain
+ *
+ * chain.eh(!!'throws')
+ * //=> TypeError(false != {yaya: x => typeof x === 'string'})
+ *
+ * @example
+ *
+ * const custom = {}
+ * custom.enums = enums => x => enums.includes(x)
+ * custom['*'] = x => true
+ * addTypes(custom)
+ * //-> void
+ *
+ * new Chain().methods('eh').type('*').build().eh
+ * //=> validateType(custom['*'])
+ *
+ */
+ var addTypes = function (types) { return validators.from(index$2(validators.entries(), types)); };
+
+ addTypes(index$12);
+
+ var includesAndOr = function (x) { return x.includes('|') || x.includes('&'); };
+
+ /**
+ * @memberOf schema
+ * @category types
+ *
+ * @param {string} fullKey a key with `|` and/or '&'
+ * @return {Function} validator
+ *
+ * @example
+ *
+ * const isStringOrNumber = typeListFactory('string|number')
+ *
+ * isStringOrNumber(1)
+ * //=> true
+ * isStringOrNumber('one')
+ * //=> true
+ * isStringOrNumber(Object)
+ * //=> false
+ *
+ */
+ function typeListFactory(fullKey) {
+ // already have it
+ if (has(fullKey)) {
+ return get$2(fullKey)
+ }
+
+ // get all types
+ var orTypes = fullKey.split('|');
+ var andTypes = fullKey.split('&');
+
+ // ensure we have all validators - sets up conditionals
+ for (var v = 0; v < orTypes.length; v++) {
+ builder(orTypes[v]);
+ }
+
+ // go through all valid options, if any are true, good to go
+ set$4(fullKey, function (x) {
+ for (var v = 0; v < orTypes.length; v++) {
+ if (get$2(orTypes[v])(x)) {
+ return true
+ }
+ }
+ return false
+ });
+
+ return get$2(fullKey)
+ }
+
+ // @TODO how to iterate properly with the bitwise fn + AND
+ // add another param? ignore overly complex |& things? just allow 1?
+ // just show how to use these shorthand fn builders
+
+ /**
+ * @desc transform arithmetic strings into types
+ * @since 4.0.0-alpha.1
+ * @category types
+ *
+ * @param {Matchable} fullKey arithmetic type key
+ * @return {Matchable} function to match with, with .inspect for easy debugging
+ *
+ * @types schema
+ * @test typed
+ * @test schema
+ * @see is
+ * @todo coercing values to certain types: arithmeticTypeFactory('')
+ *
+ * @example
+ *
+ * arithmeticTypeFactory('?string')
+ * //=> x => !isReal(x) || isString(x)
+ *
+ * @example
+ *
+ * arithmeticTypeFactory('?string|string[]')
+ * //=> x => isString(x) || isArrayOf(isString)(x)
+ *
+ * @example
+ *
+ * arithmeticTypeFactory('!string')
+ * //=> x => not(isString)(x)
+ *
+ * @example
+ *
+ * types.addTypes({star: x => true})
+ * arithmeticTypeFactory('object|function|star')
+ * //=> x => isObj(x) || isFunction(x) || isStar(x)
+ *
+ * @example
+ *
+ * arithmeticTypeFactory('===')
+ * //=> x => (['===']).includes(x)
+ */
+ function arithmeticTypeFactory(fullKey) {
+ var key = stripArithmeticSymbols(fullKey);
+ var fn = get$2(key);
+ var optionalType = "?" + key;
+ var typeOrArrayOrType = key + "[]";
+ var notType = "!" + key;
+
+ var isValidOrNotRealOrEmptyStr = or(fn, notRealOrIsEmpty);
+ var isValidOrArrayOfValid = or(fn, arrayOf(fn));
+ if (doesNotHave(optionalType)) {
+ set$4(optionalType, isValidOrNotRealOrEmptyStr);
+ }
+ if (doesNotHave(typeOrArrayOrType)) {
+ set$4(typeOrArrayOrType, isValidOrArrayOfValid);
+ }
+ if (doesNotHave(notType)) {
+ set$4(notType, not_1(fn));
+ }
+
+ return get$2(fullKey)
+ }
+
+ // ----
+ // ; function split
+ // ----
+
+ // v- annoying on comments with ifs
+ /* prettier-ignore */
+ /**
+ * @desc @pattern @builder -> builds using multiple factories depending on conditons
+ * or abstractFactory whatever
+ * opinionated: if it's a function, it's a validator...
+ *
+ * @category types
+ * @since 4.0.0
+ * @param {string | Function | Primitive} fullKey arithmetic key to the validator
+ * @return {Function} validator
+ *
+ * @see https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/Default_parameters
+ * @NOTE if/else is for uglifying ternaries, even though else if is not needed
+ * @NOTE if key is number, iterating the array
+ *
+ * @example
+ *
+ * // functionType
+ * const isString = x => typeof x === 'string'
+ * builder(isString)
+ * // => isString
+ *
+ * @example
+ *
+ * // stringType (built in, or custom-keyed validator, or eqeqeq)
+ * builder('string')
+ * // => isString
+ *
+ * const enummy = builder('enum')
+ * // => x => ['enum'].includes(x)
+ *
+ * @example
+ *
+ * // arithmeticType
+ * builder('string|string[]')
+ * // => isString || isArrayOf(isString)
+ *
+ */
+ function builder(fullKey) {
+ if (_function(fullKey)) {
+ /* istanbul ignore next: dev */
+ if (debug) {
+ console.log('functionType', {fullKey: fullKey});
+ }
+ return fullKey
+ }
+ else if (string(fullKey) && includesAndOr(fullKey)) {
+ /* istanbul ignore next: dev */
+ if (debug) {
+ console.log('andOrType', {fullKey: fullKey});
+ }
+ return typeListFactory(fullKey)
+ }
+ else {
+ /* istanbul ignore next: dev */
+ if (debug) {
+ console.log('arithmeticType', {fullKey: fullKey}, arithmeticTypeFactory(fullKey));
+ }
+ return arithmeticTypeFactory(fullKey)
+ }
+ }
+
+ builder.has = has;
+ builder.get = get$2;
+ builder.set = set$4;
+ builder.addTypes = addTypes; // was merge
+ builder.map = validators;
+ var validatorBuilder = builder;
+
+ /* ___filename___: dist/deps/dot/paths.js */
+
+ /* ___filename___: dist/deps/dot/get.js */
+
+ /* ___filename___: dist/deps/is/notNested.js */
+
+ /* ___filename___: dist/deps/validators/validatorBuilder.js */
+
+ /* ___filename___: dist/deps/validators/schemaBuilder.js */
+
+
+
+
+
+
+ var validateType = function (type, value, nestedSchema) {
+ var validator = nestedSchema || validatorBuilder(type);
+ return validator(value)
+ };
+
+ /**
+ * @desc pass the property & schema in, get a nestable typeValidator out
+ * @since 4.0.0-alpha.1
+ * @category types
+ * @category schema
+ *
+ * @param {Primitive} property property name of the currently nested schema
+ * @param {Schema | Type} nestedSchema a nested schema with Type validators, or a Type validator
+ * @return {Function} typeValidator
+ *
+ * @example
+ *
+ * // property name here is `dates`, then `created`, then `at`
+ * nestedSchema = {
+ * dates: {
+ * created: {
+ * at: 'date'
+ * }
+ * }
+ * }
+ *
+ * input = {
+ * dates: {
+ * created: {
+ * at: new Date()
+ * }
+ * }
+ * }
+ *
+ * input = new Date()
+ * input = {
+ * dates: {
+ * mismatch: true
+ * }
+ * }
+ *
+ */
+ var schemaFactory = function (property, nestedSchema) {
+ /**
+ * @desc build a recursive schema for all around runtime type safety
+ * @category types
+ * @category schema
+ * @memberOf schema
+ * @symb 🛂
+ * @since 4.0.0-beta.1
+ *
+ * @param {any} input the input to validate
+ * @return {boolean} valid
+ *
+ * @see is
+ *
+ * @example
+ *
+ * const typeValidator = schemaFactory('eh', x => typeof x === 'string')
+ *
+ * var isValid = typeValidator('stringy')
+ * //=> true
+ *
+ * var isValid = typeValidator(Number)
+ * //=> false
+ *
+ * @example
+ *
+ * const isNumber = x => typeof x === 'number'
+ * const typeValidator = schemaFactory('eh', {canada: 'number'})
+ *
+ * var isValid = typeValidator({canada: 1})
+ * //=> true
+ *
+ * var isValid = typeValidator({})
+ * //=> false
+ *
+ * var isValid = typeValidator({canada: false})
+ * //=> false
+ *
+ * var isValid = typeValidator(1)
+ * //=> false
+ *
+ */
+ function typeValidator(input) {
+ if (notNested(input)) {
+ // @@DEBUGGER
+ return validateType(property, input, nestedSchema)
+ }
+ var longestPaths = paths(false, input, true);
+
+ // @@DEBUGGER
+
+ for (var l = 0; l < longestPaths.length; l++) {
+ var fullPath = longestPaths[l] || property;
+ var type = get(nestedSchema, fullPath);
+ var value = get(input, fullPath.split('.'));
+
+ // @@DEBUGGER
+
+ if (!validateType(type, value)) {
+ // @@DEBUGGER
+ return false
+ }
+
+ // @@DEBUGGER
+ }
+ return true
+ }
+
+ /* istanbul ignore next: devs */
+ if (dev) {
+ typeValidator.inspect = function () { return ({property: property, nestedSchema: nestedSchema}); };
+ typeValidator.toString = function () { return JSON.stringify(typeValidator.inspect(), null, 2); };
+ }
+ return typeValidator
+ };
+ var schemaBuilder = schemaFactory;
+
+ /* ___filename___: dist/deps/validators/schemaBuilder.js */
+
+ /* ___filename___: dist/plugins/schema.js */
+ /* eslint complexity: "OFF" */
+
+ // util
+
+
+
+
+
+ var isFunction$1 = _undefined;
+ // logic
+
+
+
+ var SCHEMA_KEY = 'schema';
+
+ var isObjOrArray = function (x) { return (obj(x) && !isFunction$1(x)) || array(x); };
+
+ // const meta = require('../deps/meta')
+ // const or = require('../deps/conditional/or')
+ // const and = require('../deps/conditional/and')
+ // const not = require('../deps/conditional/not')
+ // const condition = Condition(Condition.is(isFunction).and().not(isObj)).or(isArray)
+ // const isObjNotFn = and(not(isFunction), isObj)
+ // const isObjOrArray = or(isObjNotFn, isArray)
+
+ /**
+ * @desc handles:
+ * 1. recursively building nestable schemas,
+ * 2. creating MethodChains for all types
+ * 3. carrying over the inheritable properties
+ * 4. @modifies @injects @decorates .add(customValidators)
+ * @pattern decorator...builder...plugin...
+ *
+ * @param {Schema} obj
+ * @return {MethodFactory} @chainable
+ */
+ var schema = function schema(obj$$2) {
+ var this$1 = this;
+
+ var parent = this.parent;
+ var ref = this.entries();
+ var onValid = ref.onValid;
+ var onInvalid = ref.onInvalid;
+ var define = ref.define;
+ var getSet = ref.getSet;
+ var keys$$2 = keys(obj$$2);
+
+ for (var k = 0; k < keys$$2.length; k++) {
+ var key = keys$$2[k];
+ var value = obj$$2[key];
+
+ // parent.method ? parent.method(key) :
+ var builder = this$1.newThis().name(key); // MethodChain
+
+ // @TODO: PLUCK METHOD FOR USING VALID KEYS
+ // @TODO:
+ // const entryKeys = ObjectKeys(entries)
+ // const entries = this.entries()
+ // for (let e = 0; e < entryKeys.length; e++) {
+ // const entryKey = entryKeys[e]
+ // const entry = entries[entryKey]
+ // builder[entryKey](entry)
+ // }
+ if (onInvalid) { builder.onInvalid(onInvalid); }
+ if (onValid) { builder.onValid(onValid); }
+ if (define) { builder.define(); }
+ if (getSet) { builder.getSet(); }
+
+ var type = value;
+ if (isObjOrArray(value)) {
+ // @@DEBUGGER
+
+ // could just assign to type
+ var traversableValidator = schemaBuilder(key, value);
+
+ if (dev) {
+ traversableValidator.schema = value;
+ }
+
+ type = traversableValidator;
+ }
+
+ // @HACK @FIXME @TODO: this should not happen,
+ // just when using babel and decorating not calling constructor...
+ // likely needs to `return this` on each?
+ // parent.store = parent.store || new Map()
+ // parent.meta = meta(parent)
+ if (parent.meta) {
+ parent.meta(SCHEMA_KEY, key, value);
+ }
+
+ builder.type(type).build();
+ }
+
+ return parent
+ };
+
+ /* ___filename___: dist/deps/encase/withSpecification.js */
+
+
+ /**
+ * @desc a special encased wrapper with no try catch but same api
+ * @name withSpecification
+ * @func
+ * @memberOf encase
+ * @since 4.0.0
+ *
+ * @param {Function} specification match
+ * @param {Function} call cb to determine valid or invalid
+ * @param {Function} onInvalid cb when invalid
+ * @param {Function} onInvalid cb when valid
+ * @return {Function} a lot of functions...
+ *
+ * @see fp/curry
+ *
+ * @example
+ * const onInvalid = console.error
+ * const onValid = console.debug
+ * const onCall = console.log
+ * const encased = withSpecification(x => true)(onCall)(onValid, onInvalid)
+ *
+ * encased(1, 2, 3) //=> onCall (did not throw)
+ */
+ var withSpecification = curry(4, function (specification, call, onInvalid, onValid) { return function (a, b, c) {
+ var result = call(a, b, c);
+ if (specification(result)) { return onInvalid(result) }
+ else { return onValid(result) }
+ }; });
+
+ /* ___filename___: dist/deps/validators/error.js */
+
+
+
+
+ /* istanbul ignore next: dev */
+ var thrower = function (error) { return function () {
+ if (dev) {
+ console.log(error);
+ }
+
+ throw error
+ }; };
+
+ /**
+ * @desc enhance an Error, enable rethrowing & better inspection
+ * @memberOf encase
+ * @category types
+ * @category encase
+ *
+ * @since 4.0.0-alpha.1
+ * @param {Primitive} method method being decorated
+ * @param {Type} type type to validate with
+ * @return {Function} function that returns a decorated TypeError with .inspect & metadata (arg, thrown, meta)
+ *
+ * @TODO js stringify if development
+ *
+ * @see MethodChain
+ * @see validators/schemaBuilder
+ * @see validators/validatorBuilder
+ * @see plugins/encase
+ *
+ * @example
+ * const badValidator = x => {
+ * if (x === 'bad') {
+ * throw new Error('bad!')
+ * }
+ * }
+ * const enhancer = enhanceError('eh', badValidator)
+ *
+ * // called by plugins/encase when throws or invalid
+ * let error
+ * let arg = 'bad'
+ * try {
+ * error = badValidator(arg)
+ * }
+ * catch (e) {
+ * error = enhancer(arg, e, {metadata: true})
+ * }
+ *
+ * console.log(error)
+ * //=> {[eh]: { type: badValidator, arg: 'bad', json, str, rethrow }}
+ * //=> console.log on DEVELOPMENT
+ */
+ var error$3 = function (method, type) { return function (arg, thrown, meta) {
+ var argToString = toS(arg);
+ var data = {
+ [method]: {
+ type: type,
+ arg: {
+ val: arg,
+ str: argToString,
+ json: JSON.stringify(arg),
+ },
+ },
+ };
+
+ var error = assign(
+ new TypeError((argToString + " != " + type)),
+ data,
+ meta
+ );
+
+ // put it back in its place
+ if (thrown && thrown.message) { error.message += thrown.message; }
+ if (thrown && thrown.stack) { error.stack = thrown.stack; }
+
+ /* istanbul ignore next: dev */
+ if (dev) {
+ // since we are just inspecting the metadata on dev
+ error.inspect = function () {
+ var devMsg = 'inspecting on development';
+ var thrownMsg = "thrown: " + thrown;
+ var eMsg = "compare: " + (error.message);
+ var errorName = "name: " + (error.name);
+ var argMsg = "arg: " + arg + ";\nstr: " + (toS(
+ arg
+ )) + " " + (typeof arg) + ";\njson: " + (JSON.stringify(arg));
+ var typeMsg = "type: " + type;
+ var stackMsg = 'stack: ' + error.stack;
+ var dashMsg = "-----";
+ var msg = "\n" + dashMsg + " " + devMsg + " " + dashMsg + "\n";
+ if (meta) { msg += "meta: " + (JSON.stringify(meta)) + "\n"; }
+ msg += thrownMsg + "\n" + eMsg + "\n" + errorName + "\n\n";
+ msg += typeMsg + "\n" + argMsg;
+ msg += "\n\n" + stackMsg + "\n" + dashMsg + "\n";
+ return msg
+ };
+ }
+
+ error.reThrow = thrower(error);
+ return error
+ }; };
+
+ /* ___filename___: dist/deps/encase/tryCatch.js */
+
+
+ /**
+ * @TODO could curry
+ *
+ * @memberOf encase
+ * @see https://github.com/fluture-js/Fluture#encase
+ * @since 4.0.0 <- moved out into a dep
+ * @since 1.0.0
+ *
+ * @param {Function} call
+ * @return {boolean | any} validation/encased function call result
+ */
+ var tryCatch = curry(3, function (call, onValid, onInvalid) { return function (a, b, c) {
+ var result;
+ try {
+ result = call(a, b, c);
+ return onValid ? onValid(result) : result
+ }
+ catch (error) {
+ // error.caught = true
+ // @NOTE: defaults to rethrow... if (isTrue(rethrow)) throw error
+ if (onInvalid) { return onInvalid(error) }
+ else { return error }
+ }
+ }; });
+
+ /* ___filename___: dist/deps/encase/tryCatch.js */
+
+ /* ___filename___: dist/deps/encase/encase.js */
+
+
+ /**
+ * @version 5.0.0 wrapped tryCatch & withSpecification in curry
+ * @version 4.0.1 added custom encaser
+ * @since 4.0.0
+ * @member encase
+ * @symb 🛡
+ *
+ * @param {Function} call function to _encase_
+ * @param {Function | undefined} [encaser=tryCatch] function to encase _with_
+ * @return {Function} -> FunctionObject{onInvalid, onValid, rethrow, call}
+ *
+ * {@link https://github.com/fluture-js/Fluture#encase fluture-encase}
+ * {@link https://github.com/lodash/lodash/blob/master/attempt.js lodash-attempt}
+ * @see {@link lodash-attempt}
+ * @see {@link fluture-encase}
+ *
+ * @example
+ *
+ * const throws = x => {
+ * if (x === false) {
+ * throw new Error('invalid - cannot be false')
+ * }
+ * return true
+ * }
+ * const api = encase(throws)
+ *
+ *
+ * api.onValid(console.log)
+ * api.onInvalid(console.error)
+ *
+ * //--- invalid
+ * api.call(false)
+ * //=> 'invalid - cannot be false'
+ *
+ * //--- valid
+ * api.call(true)
+ * //=> 'true'
+ *
+ */
+ var encase = function (call, encaser) {
+ var encased = encaser ? encaser(call) : tryCatch(call);
+
+ // @TODO rethink this scoped approach
+ // left, right, rethrow
+ var onInvalid;
+ var onValid;
+
+ var config = function (a, b, c) { return encased(onValid, onInvalid)(a, b, c); };
+
+ config.then = config.onInvalid = function (fn) {
+ onInvalid = fn;
+ return config
+ };
+ config.catch = config.onValid = function (fn) {
+ onValid = fn;
+ return config
+ };
+
+ return config
+ };
+
+ /* ___filename___: dist/deps/encase/encase.js */
+
+ var index$14 = encase;
+
+ /* ___filename___: dist/deps/validators/error.js */
+
+ /* ___filename___: dist/plugins/encase.js */
+
+
+
+ var ERROR_META = {m: 1};
+
+ /**
+ * 3 steps
+ * 0. enhance error
+ * 1. encase function with a specification
+ * 2. build a function to call onInvalid or onInvalid depending
+ *
+ * @since 4.0.0
+ *
+ * @param {string} name name of the method
+ * @param {Object | Function} parent object being decorated by MethodChain
+ * @param {Object} built the current state of the decoration
+ * @return {Function} curried finisher, for specification
+ *
+ * @name methodEncasingFactory
+ * @func methodEncasingFactory
+ * @symb ⛑🏭
+ * @types encase
+ *
+ * @example
+ *
+ * methodEncasingFactory('eh', {}, {onSet: console.log})
+ * //=> Function
+ *
+ */
+ function methodEncasingFactory(name, parent, built) {
+ /**
+ * @name scopedEncase
+ * @func scopedEncase
+ * @category type
+ * @since 4.0.0-beta.1
+ *
+ * @param {Function} fnToEncase depending on the result of this, call
+ * @param {string | Function | undefined} [type=undefined] Type
+ * @param {Function | undefined} [specification=undefined] Specification
+ * @return {Function} the method...
+ *
+ * @example
+ *
+ * const fnToEncase = arg => arg === true
+ * const onInvalid = (error, key, arg, instance) => console.log(arguments)
+ * const onValid = (key, arg, instance) => console.log(arguments)
+ * const encased = scopedEncase(fnToEncase)
+ * .onValid(onValid)
+ * .onInvalid(onInvalid)
+ * //=> typedOnCall
+ *
+ */
+ return function scopedEncase(fnToEncase, type, specification) {
+ // @@debugger
+ var enhanceError = error$3(name, type, fnToEncase, parent);
+
+ // if specification is not passed in, undefined defaults to tryCatch
+ var encased = index$14(fnToEncase, specification);
+
+ // our configured functions, with fallback defaults
+ var onSet = built.onCall || built.onSet;
+ var onValid = built.onValid || onSet;
+
+ // default to re-throw
+ var onInvalid =
+ built.onInvalid ||
+ (function (arg, error) { return enhanceError(arg, error, ERROR_META).reThrow(); });
+
+ /**
+ * @desc this is the actual built function
+ * @name typedOnCall
+ * @func typedOnCall
+ * @category type
+ * @since 4.0.0-beta.1
+ *
+ * @param {any} arg arg to validate
+ * @return {Function} typedOnCall(argToValidate: any)
+ *
+ * @example
+ *
+ * const encased = encase(fnToEncase)
+ * .onValid()
+ * .onInvalid(function)
+ * .call()
+ *
+ */
+ return function typedOnCall(arg) {
+ var this$1 = this;
+
+ // nodejs way - error first, data second, instance last
+ var callInvalid = function (error) {
+ // @@debugger
+ onInvalid.call(this$1, enhanceError(arg, error), arg, name, this$1);
+ };
+
+ // @TODO: ensure it isn't a syntax error and is a type error
+ // if it is already an error, we should only enhance it
+ // @example `TypeError: Cannot read property 'call' of undefined`
+ encased
+ .onInvalid(callInvalid)
+ // @NOTE: onValid defaults to `this.set(name, arg)`
+ .onValid(function (result) {
+ // @@debugger
+ onValid.call(this$1, arg, name, this$1);
+ })
+ .call(this, arg);
+
+ return this
+ }
+ }
+ }
+
+ var encase_1 = methodEncasingFactory;
+
+ /* ___filename___: dist/deps/encase/withSpecification.js */
+
+ /* ___filename___: dist/plugins/encase.js */
+
+ /* ___filename___: dist/plugins/types.js */
+
+
+
+
+
+
+
+ // we'll be opinionated and say either `false` or `throw`
+ var spec = withSpecification(not_1(_false));
+
+ /**
+ * @pattern factory plugin
+ * @param {string} name
+ * @param {Object} parent
+ * @param {Object} built
+ * @return {void}
+ */
+ var types = function validatorPlugin(name, parent, built) {
+ // core domain of this fn, used by validators and configured fns
+ var type = built.type;
+
+ if (type) {
+ // if (ENV_DEVELOPMENT) {
+ // this.debugSteps('added built type')
+ // }
+
+ // create our validator in the factory,
+ var validator = validatorBuilder(type);
+
+ // then encase it, prepare a TypeError factory
+ var encase = encase_1(name, parent, built);
+ var validatorMethod = encase(validator, type, spec);
+
+ /* istanbul ignore next: dev */
+ if (dev) {
+ validatorMethod.type = type;
+ }
+
+ this.onCall(validatorMethod).onSet(validatorMethod);
+ }
+ };
+
+ /* ___filename___: dist/plugins/obj.js */
+
+
+ // @TODO optimize size here ez
+ var obj$2 = function(methods, name) {
+ var this$1 = this;
+
+ var obj = methods[name];
+
+ if (_function(obj)) {
+ return function () {
+ // @TODO: IS THIS THE BEST DEFAULT?!
+ this$1.define(false);
+ this$1.onCall(obj);
+ // .onSet(obj).onGet(obj)
+ }
+ }
+ else {
+ return function () {
+ this$1.from(obj);
+ // @NOTE: this is reserved
+ if (obj.set) { this$1.onSet(obj.set); }
+ if (obj.get) { this$1.onGet(obj.get); }
+ if (obj.call) { this$1.onCall(obj.call); }
+ if (obj.set && obj.get) {
+ this$1.define().getSet();
+ }
+ }
+ }
+ };
+
+ /* ___filename___: dist/plugins/decorate.js */
+
+
+
+ /**
+ * decorates a parent when the argument is provided
+ * BUT THE FUNCTIONS WILL STILL BE SCOPED TO CURRENT PARENT
+ * for easy factory chaining
+ *
+ * @since 4.0.0-alpha.1
+ * @memberOf MethodChain
+ * @param {Object} parentToDecorate object to put the method on instead
+ * @return {MethodChain} @chainable
+ *
+ * @see MethodChain
+ *
+ * @TODO this is more like a preset since it *adds* plugins?
+ * more of methodFactory now
+ *
+ * @example
+ *
+ * const chain = new Chain()
+ * const obj = {}
+ * chain.method('ehOh').decorate(obj).build()
+ * typeof obj.ehOh
+ * //=> 'function'
+ *
+ */
+ var decorate = function(parentToDecorate) {
+ // @TODO is objStrict?
+ // if (parentToDecorate) {
+ this.target(parentToDecorate);
+
+ // can use this to "undecorate"
+ // if (!parentToDecorate.meta) <- checks already inside of meta()
+ parentToDecorate.meta = index$6(parentToDecorate);
+
+ // default returns result of calling function,
+ // else .parentToDecorate
+ return this.plugin(function(name, parent) {
+ parentToDecorate.meta(decorated, name);
+
+ // @NOTE: so we can return...
+ /* prettier-ignore */
+ return this
+ .returns(function returnsFunction(result) {
+ return result || parentToDecorate
+ })
+ .callReturns(true)
+ })
+ };
+
+ /* ___filename___: dist/plugins/autoIncrement.js */
+ /**
+ * @plugin
+ * @param {Primitive} name method name
+ * @param {Object} parent Parent
+ * @return {MethodChain} @chainable
+ */
+ var autoIncrement = function(name, parent) {
+ return this.initial(0).onCall(function () { return parent.tap(name, function (num) { return num + 1; }); })
+ };
+
+ /* ___filename___: dist/plugins/autoGetSet.js */
+
+
+ /**
+ * @memberOf MethodChain
+ * @plugin
+ *
+ * @param {Primitive} name method name being built
+ * @param {Object} parent parent containing the method
+ * @return {MethodChain} @chainable
+ *
+ * @see MethodChain
+ *
+ * @example
+ *
+ * const chain = new Chain()
+ * chain.methods('eh').plugin(autoGetSet).build()
+ *
+ * chain.eh(1)
+ * //=> Chain
+ * chain.eh()
+ * //=> 1
+ *
+ */
+ function autoGetSet(name, parent) {
+ var auto = function (arg) { return (_undefined(arg) ? parent.get(name) : parent.set(name, arg)); };
+
+ // so we know if we defaulted them
+ auto.autoGetSet = true;
+ return this.onSet(auto).onGet(auto).onCall(auto)
+ }
+
+ var autoGetSet_1 = autoGetSet;
+
+ /* ___filename___: dist/deps/util/getDescriptor.js */
+ var getDescriptor = Object.getOwnPropertyDescriptor;
+
+ /* ___filename___: dist/deps/util/getPrototypeOf.js */
+
+ /* ___filename___: dist/deps/util/getPrototypeOf.js */
+
+ /* ___filename___: dist/deps/util/props.js */
+
+ /* ___filename___: dist/deps/gc.js */
+
+
+
+
+
+
+ // function gc() {
+ // if (typeof window !== 'undefined') window.global = window
+ // if (typeof global.gc === 'function') global.gc()
+ // }
+
+ /**
+ * @since 4.0.0
+ * @desc remove all methods, mark for garbage collection
+ *
+ * @param {Object} obj object to traverse and clear
+ * @return {void}
+ *
+ * @see https://stackoverflow.com/questions/1947995/when-should-i-use-delete-vs-setting-elements-to-null-in-javascript
+ * @see https://v8project.blogspot.ca/2015/08/getting-garbage-collection-for-free.html
+ * @see https://github.com/natewatson999/js-gc
+ * @see https://github.com/siddMahen/node-gc
+ * @see http://buildnewgames.com/garbage-collector-friendly-code/
+ * @see https://stackoverflow.com/questions/27597335/ensuring-object-can-be-garbage-collected
+ * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_Management
+ *
+ * @TODO blacklist = [] param
+ * @TODO put all GC events into a cached map and debounce the operation
+ *
+ * @example
+ *
+ * var scoped = {}
+ * var ref = () => scoped
+ * var obj = {scoped, ref, eh: true}
+ *
+ * markForGarbageCollection(obj)
+ * //=> void
+ *
+ * obj
+ * //=> undefined|{}
+ *
+ */
+ function markForGarbageCollection(obj$$2) {
+ // @TODO: ArrayOrObj loop... like tons of libs do...
+ // let props = isObj(obj) ? ObjectProperties(obj) : obj //isArray(obj) ? obj
+ var props$$1 = keysObjOrArray(obj$$2);
+
+ for (var p = 0; p < props$$1.length; p++) {
+ if (obj(obj$$2[p])) {
+ markForGarbageCollection(obj$$2[p]);
+ }
+ delete obj$$2[p];
+ }
+
+ // traverse(obj).forEach(function(x) {
+ // const {value} = this
+ //
+ // // @NOTE: just delete the main path first, later we can use cleaner
+ // // const shouldIgnore = path
+ // // .map(pathPart => ignore.includes(pathPart))
+ // // .includes(true)
+ // // !shouldIgnore &&
+ //
+ // /* istanbul ignore else: safety for bottom up */
+ // // ensure the longest paths in traverser are used...
+ // if (!isArray(value) && !isObj(value)) {
+ // this.remove()
+ // }
+ // })
+
+ // simple fast easy cleanup
+ // for (let p = 0; p < props.length; p++) {
+ // delete obj[p]
+ // }
+
+ props$$1 = undefined;
+ obj$$2 = undefined;
+ }
+
+ var gc = markForGarbageCollection;
+
+ /* ___filename___: dist/plugins/schema.js */
+
+ /* ___filename___: dist/plugins/types.js */
+
+ /* ___filename___: dist/plugins/obj.js */
+
+ /* ___filename___: dist/plugins/decorate.js */
+
+ /* ___filename___: dist/plugins/autoIncrement.js */
+
+ /* ___filename___: dist/plugins/autoGetSet.js */
+
+ /* ___filename___: dist/deps/util/getDescriptor.js */
+
+ /* ___filename___: dist/deps/gc.js */
+
+ /* ___filename___: dist/MethodChain.js */
+ /* eslint complexity: "OFF" */
+ /* eslint import/max-dependencies: "OFF" */
+
+ /**
+ * @TODO clarify .set vs .call
+ * {@link https://github.com/iluwatar/java-design-patterns/tree/master/property property-pattern}
+ * {@link https://github.com/iluwatar/java-design-patterns/tree/master/prototype prototype-pattern}
+ * {@link https://github.com/iluwatar/java-design-patterns/tree/master/step-builder step-builder-pattern}
+ * {@link https://github.com/iluwatar/java-design-patterns/tree/master/builder builder-pattern}
+ * {@link https://github.com/addyosmani/essential-js-design-patterns/blob/master/diagrams/mixins.png mixin-png}
+ * {@link https://sourcemaking.com/design_patterns/creational_patterns creational-patterns}
+ * {@link https://sourcemaking.com/design_patterns/factory_method factory-method}
+ * {@link https://medium.com/javascript-scene/javascript-factory-functions-vs-constructor-functions-vs-classes-2f22ceddf33e constructors}
+ * {@link https://www.sitepoint.com/factory-functions-javascript/ js-factory-functions}
+ */
+
+ // core
+
+
+
+
+ // plugins
+
+
+
+
+
+
+
+ // const validatorBuilder = require('./deps/validators/validatorBuilder')
+ // obj
+
+
+
+
+
+ // utils
+
+
+
+
+ // is
+
+
+
+
+
+
+
+ var DEFAULTED_KEY = 'defaulted';
+ var METHOD_KEYS = [
+ 'onInvalid',
+ 'onValid',
+ 'initial',
+ 'default',
+ 'type',
+ 'callReturns',
+ 'target',
+ 'onSet',
+ 'onCall',
+ 'onGet',
+ ];
+
+ // const SET_KEY = METHOD_KEYS[0]
+
+ function getSetFactory(_this, name, desc) {
+ _this[camelCase(("set-" + name))] = desc.set;
+ _this[camelCase(("get-" + name))] = desc.get;
+ }
+
+ function aliasFactory(name, parent, aliases) {
+ if (!_undefined(aliases)) {
+ for (var a = 0; a < aliases.length; a++) {
+ define(parent, aliases[a], getDescriptor(parent, name));
+ }
+ }
+ }
+
+ // @TODO to use as a function
+ // function _methods() {}
+ // _methods.use(obj) {
+ // this.obj = obj
+ // return _methods
+ // }
+ // _methods.extend = _methods.use
+ // _methods.methods = function(methods) {
+ // return new MethodChain(this.obj)
+ // }
+
+ var methodFactories = {};
+
+ /**
+ * ❗ using `+` will call `.build()` in a shorthand fashion
+ *
+ * @member MethodChain
+ * @inheritdoc
+ * @class
+ * @extends {ChainedMap}
+ * @type {Map}
+ *
+ * @since 4.0.0
+ *
+ * @types MethodChain
+ * @tests MethodChain
+ *
+ * @TODO maybe abstract the most re-usable core as a protected class
+ * so the shorthands could be used, and more functionality made external
+ * @TODO need to separate schema from here as external functionality & add .add
+ * @TODO .prop - for things on the instance, not in the store?
+ * !!! .sponge - absorn properties into the store
+ */
+ var MethodChain = (function (ChainedMap) {
+ function MethodChain(parent) {
+ var this$1 = this;
+
+ // timer.start('methodchain')
+
+ ChainedMap.call(this, parent);
+
+ // ----------------
+ var set = this.set.bind(this);
+
+ this.newThis = function () { return new MethodChain(parent); };
+ this.toNumber = function () { return this$1.build(0); };
+
+ /**
+ * @example
+ *
+ * chain
+ * .method('eh')
+ * .type(`?string`)
+ * .type(`string[]`)
+ * .type(`string|boolean`)
+ * .type(`boolean[]|string[]`)
+ * .type(`!date`)
+ *
+ */
+ this.extend(METHOD_KEYS);
+
+ // shorthand
+ this.method = this.methods = function (name) {
+ if (this$1.length) { return this$1.build().methods(name) }
+ else { return this$1.name(name) }
+ };
+
+ // default argument...
+ this.encase = function (x) {
+ return set('encase', parent[x] || x || true)
+ };
+
+ // alias
+ this.then = this.onValid.bind(this);
+ this.catch = this.onInvalid.bind(this);
+
+ this.returns = function (x, callReturns) { return set('returns', x || parent).callReturns(callReturns); };
+
+ // @NOTE replaces shorthands.chainWrap
+ this.chainable = this.returns;
+
+ /**
+ * @desc alias methods
+ * @since 2.0.0
+ *
+ * @param {string | Array} aliases aliases to remap to the current method being built
+ * @return {MethodChain} @chainable
+ *
+ * @NOTE these would be .transform
+ *
+ * @example
+ *
+ * const chain = new Chain()
+ * chain.methods(['canada']).alias(['eh']).build()
+ * chain.eh('actually...canada o.o')
+ * chain.get('canada')
+ * //=> 'actually...canada o.o')
+ *
+ */
+ this.alias = function (aliases) { return this$1.tap('alias', function (old, merge) { return merge(old, toArr(aliases)); }); };
+ this.plugin = function (plugin) { return this$1.tap('plugins', function (old, merge) { return merge(old, toArr(plugin)); }); };
+
+ this.camelCase = function () { return set('camel', true); };
+
+ // @NOTE: x = true is much prettier, but compiles badly
+ var defaultToTrue = function (x) { return (_undefined(x) ? true : x); };
+ this.define = function (x) { return set('define', defaultToTrue(x)); };
+ this.getSet = function (x) { return set('getSet', defaultToTrue(x)); };
+
+ // @TODO unless these use scoped vars, they should be on proto
+ // @NOTE shorthands.bindMethods
+ this.bind = function (target) { return set('bind', _undefined(target) ? parent : target); };
+ this.autoGetSet = function () { return this$1.plugin(autoGetSet_1); };
+
+ this.plugin(types);
+
+ if (objWithKeys(methodFactories)) {
+ keys(methodFactories).forEach(function (factoryName) {
+ this$1[factoryName] = function (arg) { return methodFactories[factoryName].call(this$1, arg); };
+ if (dev) {
+ this$1[factoryName].methodFactory = true;
+ }
+ });
+ }
+ }
+
+ if ( ChainedMap ) MethodChain.__proto__ = ChainedMap;
+ MethodChain.prototype = Object.create( ChainedMap && ChainedMap.prototype );
+ MethodChain.prototype.constructor = MethodChain;
+
+ /**
+ * @desc setup methods to build
+ * @category builder
+ * @memberOf MethodChain
+ *
+ * @since 4.0.0-beta.1 <- moved to plugin
+ * @since 4.0.0
+ *
+ * @param {string | Object | Array} methods method names to build
+ * @return {MethodChain} @chainable
+ *
+ * @example
+ *
+ * var obj = {}
+ * new MethodChain(obj).name('eh').build()
+ * typeof obj.eh
+ * //=> 'function'
+ *
+ */
+ MethodChain.prototype.name = function name (methods) {
+ var this$1 = this;
+
+ var names = methods;
+
+ /**
+ * @desc this is a plugin for building methods
+ * schema defaults value to `.type`
+ * this defaults values to `.onCall`
+ */
+ if (!array(methods) && obj(methods)) {
+ names = keys(methods);
+ for (var name = 0; name < names.length; name++) {
+ this$1.plugin(obj$2.call(this$1, methods, names[name]));
+ }
+ }
+ return this.set('names', names)
+ };
+
+ /**
+ * an object that contains nestable `.type`s
+ * they are recursively (using an optimized traversal cache) mapped to validators
+ * ❗ this method auto-calls .build, all other method config calls should be done before it
+ *
+ * @TODO link to `deps/is` docs
+ *
+ * @version 4.0.0-beta.1 <- moved to plugin
+ * @since 4.0.0
+ *
+ * @category types
+ * @memberOf MethodChain
+ *
+ * @param {Object} obj schema
+ * @return {MethodChain} @chainable
+ *
+ * @TODO move out into a plugin to show how easy it is to use a plugin
+ * and make it able to be split out for size when needed
+ *
+ * @TODO inherit properties (in plugin, for each key)
+ * from this for say, dotProp, getSet
+ *
+ * @TODO very @important
+ * that we setup schema validation at the highest root for validation
+ * and then have some demo for how to validate on set using say mobx
+ * observables for all the way down...
+ *
+ * @typedef `schema(schema: Obj): ChainAble`
+ *
+ * @example
+ *
+ * chain
+ * .methods()
+ * .define()
+ * .getSet()
+ * .onInvalid((error, arg, instance) => console.log(error))
+ * .schema({
+ * id: '?number',
+ * users: '?object|array',
+ * topic: '?string[]',
+ * roles: '?array',
+ * creator: {
+ * name: 'string',
+ * email: 'email',
+ * id: 'uuid',
+ * },
+ * created_at: 'date',
+ * updated_at: 'date|date[]',
+ * summary: 'string',
+ * })
+ *
+ * //--- valid
+ * chain.created_at = new Date()
+ * chain.setCreatedAt(new Date())
+ *
+ * isDate(chain.created_at) === true
+ *
+ * //--- nestable validation 👍
+ * chain.merge({creator: {name: 'string'}})
+ *
+ * //--- invalid
+ * chain.updated_at = false
+ *
+ */
+ MethodChain.prototype.schema = function schema$$1 (obj$$1) {
+ return schema.call(this, obj$$1)
+ };
+
+ /**
+ * @desc set the actual method, also need .context - use .parent
+ * @memberOf MethodChain
+ * @since 4.0.0
+ *
+ * @param {any} [returnValue=undefined] returned at the end of the function for ease of use
+ * @return {MethodChain} @chainable
+ *
+ * @TODO if passing in a name that already exists, operations are decorations... (partially done)
+ * @see https://github.com/iluwatar/java-design-patterns/tree/master/step-builder
+ *
+ * @example
+ *
+ * var obj = {}
+ * const one = new MethodChain(obj).methods('eh').getSet().build(1)
+ * //=> 1
+ *
+ * typeof obj.getEh
+ * //=> 'function'
+ *
+ */
+ MethodChain.prototype.build = function build (returnValue) {
+ var this$1 = this;
+
+ var parent = this.parent;
+ var names = toArr(this.get('names'));
+ var shouldTapName = this.get('camel');
+
+ for (var name = 0; name < names.length; name++) {
+ this$1._build(shouldTapName ? camelCase(names[name]) : names[name], parent);
+ }
+
+ // timer.stop('methodchain').log('methodchain').start('gc')
+
+ // remove refs to unused
+ this.clear();
+ delete this.parent;
+ gc(this);
+
+ // very fast - timer & ensuring props are cleaned
+ // timer.stop('gc').log('gc')
+ // require('fliplog').quick(this)
+
+ return _undefined(returnValue) ? parent : returnValue
+ };
+
+ /**
+ * @memberOf MethodChain
+ *
+ * @since 4.0.0
+ * @protected
+ * @param {Primitive} name method name
+ * @param {Object} parent being decorated
+ * @param {Object} built method being built
+ * @return {void}
+ *
+ * @TODO optimize the size of this
+ * with some bitwise operators
+ * hashing the things that have been defaulted
+ * also could be plugin
+ *
+ * @example
+ *
+ * ._defaults('', {}, {})
+ *
+ *
+ * @example
+ *
+ * let methodFactories
+ *
+ * ### `onSet`
+ *
+ * > defaults to `this.set(key, value)`
+ *
+ * ```ts
+ * public onSet(fn: Fn): MethodChain
+ * ```
+ *
+ * ### `onCall`
+ *
+ * > defaults to .onSet ^
+ *
+ * ```ts
+ * public onCall(fn: Fn): MethodChain
+ * ```
+ *
+ * ### `onGet`
+ *
+ * > defaults to `this.get(key)`
+ *
+ * ```ts
+ * public onGet(fn: Fn): MethodChain
+ * ```
+ *
+ */
+ MethodChain.prototype._defaults = function _defaults (name, parent, built) {
+ // defaults
+ var defaultOnSet = function (arg) { return parent.set(name, arg); };
+ var defaultOnGet = function () { return parent.get(name); };
+
+ // so we know if we defaulted them
+ defaultOnSet[DEFAULTED_KEY] = true;
+ defaultOnGet[DEFAULTED_KEY] = true;
+
+ // when we've[DEFAULTED_KEY] already for another method,
+ // we need a new function,
+ // else the name will be scoped incorrectly
+ var onCall = built.onCall;
+ var onSet = built.onSet;
+ var onGet = built.onGet;
+ if (!onGet || onGet[DEFAULTED_KEY]) {
+ this.onGet(defaultOnGet);
+ }
+ if (!onCall || onCall[DEFAULTED_KEY]) {
+ this.onCall(defaultOnSet);
+ }
+ if (!onSet || onSet[DEFAULTED_KEY]) {
+ this.onSet(defaultOnSet);
+ }
+ };
+
+ /**
+ * @protected
+ * @since 4.0.0-alpha.1
+ * @memberOf MethodChain
+ *
+ * @param {Primitive} name
+ * @param {Object} parent
+ * @return {void}
+ *
+ * @TODO allow config of method var in plugins since it is scoped...
+ * @TODO add to .meta(shorthands)
+ * @TODO reduce complexity if perf allows
+ * @NOTE scoping here adding default functions have to rescope arguments
+ */
+ MethodChain.prototype._build = function _build (name, parent) {
+ var this$1 = this;
+
+ var method;
+ var existing;
+ var entries = function () { return this$1.entries(); };
+
+ // could ternary `let method =` here
+ if (hasOwnProperty_1(parent, name)) {
+ existing = getDescriptor(parent, name);
+
+ // avoid `TypeError: Cannot redefine property:`
+ if (_false(existing.configurable)) {
+ return
+ }
+
+ // use existing property, when configurable
+ method = existing.value;
+
+ if (dev) {
+ method.decorated = true;
+ }
+
+ this.onCall(method).onSet(method);
+ }
+ else if (parent[name]) {
+ method = parent[name];
+
+ if (dev) {
+ method.decorated = true;
+ }
+
+ this.onCall(method).onSet(method);
+ }
+
+ // scope it once for plugins & type building, then get it again
+ var built = entries();
+
+ this._defaults(name, parent, built);
+
+ // plugins can add methods,
+ // useful as plugins/presets & decorators for multi-name building
+ var instancePlugins = built.plugins;
+ if (instancePlugins) {
+ for (var plugin = 0; plugin < instancePlugins.length; plugin++) {
+ built = entries();
+ instancePlugins[plugin].call(this$1, name, parent, built);
+ }
+ }
+
+ // after last plugin is finished, or defaults
+ built = entries();
+
+ // wrap in encasing when we have a validator or .encase
+ // @NOTE: validator plugin was here, moved into a plugin
+ if (built.encase) {
+ var encased = encase_1.call(this, name, parent, built)(method);
+
+ if (dev) {
+ encased.encased = method;
+ }
+
+ this.onCall(encased).onSet(encased);
+ method = encased;
+ built = entries();
+ }
+
+ // not destructured for better variable names
+ var shouldAddGetterSetter = built.getSet;
+ var shouldDefineGetSet = built.define;
+ var defaultValue = built.default;
+
+ // can only have `call` or `get/set`...
+ var onGet = built.onGet;
+ var onSet = built.onSet;
+ var onCall = built.onCall;
+ var initial = built.initial;
+ var bind = built.bind;
+ var returns = built.returns;
+ var callReturns = built.callReturns;
+ var alias = built.alias;
+
+ // default method, if we do not have one already
+ if (!method) {
+ method = function (arg) {
+ if ( arg === void 0 ) arg = defaultValue;
+
+ return onCall.call(parent, arg);
+ };
+
+ if (dev) {
+ method.created = true;
+ }
+ }
+
+ if (bind) {
+ // bind = bindArgument || parent
+ method = method.bind(bind);
+ }
+ if (returns) {
+ var ref = method;
+ method = function() {
+ var args = argumentor.apply(null, arguments);
+
+ // eslint-disable-next-line prefer-rest-params
+ var result = ref.apply(parent, args);
+
+ return _true(callReturns)
+ ? returns.apply(parent, [result].concat(args))
+ : returns
+ };
+ }
+
+ if (!_undefined(initial)) {
+ parent.set(name, initial);
+ }
+
+ // --------------- stripped -----------
+
+ /**
+ * !!!!! @TODO put in `plugins.post.call`
+ * !!!!! @TODO ensure unique name
+ *
+ * can add .meta on them though for re-decorating
+ * -> but this has issue with .getset so needs to be on .meta[name]
+ */
+
+ /* istanbul ignore next: dev */
+ if (dev) {
+ define(onGet, 'name', {
+ value: camelCase(((onGet.name) + "+get-" + name)),
+ });
+ define(onSet, 'name', {
+ value: camelCase(((onSet.name) + "+set-" + name)),
+ });
+ define(onCall, 'name', {
+ value: camelCase(((onCall.name) + "+call-" + name)),
+ });
+ define(method, 'name', {value: camelCase(("" + name))});
+
+ if (built.type) { method.type = built.type; }
+ if (initial) { method.initial = initial; }
+ if (bind) { method.bound = bind; }
+ if (returns) { method.returns = returns; }
+ if (alias) { method.alias = alias; }
+ if (callReturns) { method.callReturns = callReturns; }
+ if (onGet) { method._get = onGet; }
+ if (onSet) { method._set = onSet; }
+ // eslint-disable-next-line
+ if (onCall != onCall) { method._call = onCall; }
+ }
+
+ /* istanbul ignore next: dev */
+ if (debug) {
+ console.log({
+ name: name,
+ defaultValue: defaultValue,
+ initial: initial,
+ returns: returns,
+ onGet: onGet,
+ onSet: onSet,
+ method: method.toString(),
+ });
+ }
+
+ // ----------------- ;stripped ------------
+
+ // @TODO WOULD ALL BE METHOD.POST
+ // --- could be a method too ---
+ var getterSetter = {get: onGet, set: onSet};
+ var descriptor = shouldDefineGetSet ? getterSetter : {value: method};
+ if (existing) { descriptor = assign(existing, descriptor); }
+
+ // [TypeError: Invalid property descriptor.
+ // Cannot both specify accessors and a value or writable attribute, #]
+ if (descriptor.value && descriptor.get) {
+ delete descriptor.value;
+ }
+ if (!_undefined(descriptor.writable)) {
+ delete descriptor.writable;
+ }
+
+ var target = this.get('target') || parent;
+
+ define(target, name, descriptor);
+
+ if (shouldAddGetterSetter) {
+ if (target.meta) { target.meta(shorthands, name, onSet); }
+ getSetFactory(target, name, getterSetter);
+ }
+
+ aliasFactory(name, target, alias);
+
+ // if (built.metadata) {
+ // target.meta(SHORTHANDS_KEY, name, set)
+ // }
+ // require('fliplog')
+ // .bold('decorate')
+ // .data({
+ // // t: this,
+ // descriptor,
+ // shouldDefineGetSet,
+ // method,
+ // str: method.toString(),
+ // // target,
+ // name,
+ // })
+ // .echo()
+ };
+
+ // ---
+
+ /**
+ * @desc add methods to the parent for easier chaining
+ * @alias extendParent
+ * @memberOf MethodChain
+ *
+ * @since 4.0.0-beta.1 <- moved to plugin
+ * @since 4.0.0 <- moved from Extend
+ * @since 1.0.0
+ *
+ * @param {Object} [parentToDecorate=undefined] decorate a specific parent shorthand
+ * @return {ChainedMap} @chainable
+ *
+ * @see plugins/decorate
+ * @see ChainedMap.parent
+ *
+ * @example
+ *
+ * var obj = {}
+ * new MethodChain({}).name('eh').decorate(obj).build()
+ * typeof obj.eh
+ * //=> 'function'
+ *
+ * @example
+ *
+ * class Decorator extends Chain {
+ * constructor(parent) {
+ * super(parent)
+ * this.methods(['easy']).decorate(parent).build()
+ * this.methods('advanced')
+ * .onCall(this.advanced.bind(this))
+ * .decorate(parent)
+ * .build()
+ * }
+ * advanced(arg) {
+ * this.set('advanced', arg)
+ * return this.parent
+ * }
+ * easy(arg) {
+ * this.parent.set('easy-peasy', arg)
+ * }
+ * }
+ *
+ * class Master extends Chain {
+ * constructor(parent) {
+ * super(parent)
+ * this.eh = new Decorator(this)
+ * }
+ * }
+ *
+ * const master = new Master()
+ *
+ * master.get('easy-peasy')
+ * //=> true
+ *
+ * master.eh.get('advanced')
+ * //=> 'a+'
+ *
+ * @example
+ *
+ * +chain.method('ehOh').decorate(null)
+ * //=> @throws Error('must provide parent argument')
+ *
+ */
+ MethodChain.prototype.decorate = function decorate$$1 (parentToDecorate) {
+ /* istanbul ignore next: devs */
+ if (dev) {
+ if (!(parentToDecorate || this.parent.parent)) {
+ throw new Error('must provide parent argument')
+ }
+ }
+ return decorate.call(this, parentToDecorate || this.parent.parent)
+ };
+
+ /**
+ * @desc adds a plugin to increment the value on every call
+ * @modifies this.initial
+ * @modifies this.onCall
+ *
+ * @memberOf MethodChain
+ * @version 4.0.0-beta.1 <- moved to plugin
+ * @version 4.0.0 <- renamed from .extendIncrement
+ * @since 0.4.0
+ *
+ * @return {MethodChain} @chainable
+ *
+ * @see plugins/autoIncrement
+ *
+ * @example
+ *
+ * chain.methods(['index']).autoIncrement().build().index().index(+1).index()
+ * chain.get('index')
+ * //=> 3
+ *
+ */
+ MethodChain.prototype.autoIncrement = function autoIncrement$$1 () {
+ return this.plugin(autoIncrement)
+ };
+
+ return MethodChain;
+ }(ChainedMapBase));
+
+ /**
+ * @desc add methodFactories easily
+ * @static
+ * @since 4.0.0-beta.2
+ *
+ * @param {Object} methodFactory factories to add
+ * @return {void}
+ *
+ * @example
+ *
+ * function autoGetSet(name, parent) {
+ * const auto = arg =>
+ * (isUndefined(arg) ? parent.get(name) : parent.set(name, arg))
+ *
+ * //so we know if we defaulted them
+ * auto.autoGetSet = true
+ * return this.onSet(auto).onGet(auto).onCall(auto)
+ * }
+ * MethodChain.addPlugin({autoGetSet})
+ *
+ *
+ * const chain = new Chain()
+ * chain.methods('eh').autoGetSet().build()
+ *
+ * chain.eh(1)
+ * //=> chain
+ * chain.eh()
+ * //=> 1 *
+ *
+ */
+ MethodChain.add = function addMethodFactories(methodFactory) {
+ assign(methodFactories, methodFactory);
+ };
+ methodFactories = MethodChain.add;
+
+ var MethodChain_1 = MethodChain;
+
+ /* ___filename___: dist/deps/is/mapish.js */
+
+
+
+ /**
+ * @func isMapish
+ *
+ * @memberOf is
+ * @since 3.0.0
+ * @extends isMap
+ * @variation also checks `instanceof Chainable`
+ *
+ * @param {*} x value to check
+ * @return {boolean} isMapish
+ *
+ * @example
+ *
+ * isMapish(new Map)
+ * //=> true
+ *
+ * isMapish(new Chain)
+ * //=> true
+ *
+ * isMapish({})
+ * //=> false
+ *
+ * isMapish(1)
+ * //=> false
+ *
+ */
+ var mapish = function (x) { return map(x) || x instanceof Chainable; };
+
+ /* ___filename___: dist/MethodChain.js */
+
+ /* ___filename___: dist/deps/is/mapish.js */
+
+ /* ___filename___: dist/MergeChain.js */
+ /* eslint complexity: "OFF" */
+
+
+
+
+
+
+
+
+
+
+
+
+ var ON_EXISTING_KEY = 'onExisting';
+ var ON_VALUE_KEY = 'onValue';
+ var MERGER_KEY = 'merger';
+ var MERGER_OPTIONS_KEY = 'opts';
+ var OBJ_KEY = 'obj';
+
+ /**
+ * @since 1.0.0
+ * @type {Map}
+ * @extends {ChainedMapBase}
+ * @member MergeChain
+ * @memberOf Chainable
+ *
+ * @types MergeChain
+ * @tests MergeChain
+ * @see deps/dopemerge
+ *
+ * {@link https://sourcemaking.com/design_patterns/visitor visitor-pattern}
+ *
+ * @TODO consider just making this a function,
+ * because 80/20 onValue merger & onExisting
+ * are rarely used & are easily overridable with .merge
+ */
+ var MergeChain = (function (ChainedMapBase$$1) {
+ function MergeChain(parent) {
+ ChainedMapBase$$1.call(this, parent);
+
+ /* prettier-ignore */
+ this
+ .extend([ON_EXISTING_KEY, ON_VALUE_KEY, OBJ_KEY])
+ .set(ON_VALUE_KEY, function () { return true; })
+ .set(MERGER_KEY, index$2);
+ }
+
+ if ( ChainedMapBase$$1 ) MergeChain.__proto__ = ChainedMapBase$$1;
+ MergeChain.prototype = Object.create( ChainedMapBase$$1 && ChainedMapBase$$1.prototype );
+ MergeChain.prototype.constructor = MergeChain;
+
+ /**
+ * @desc options for merging with dopemerge
+ * @modifies this.merger | this.opts
+ *
+ * @memberOf MergeChain
+ * @since 1.0.2
+ * @param {Object | Function} opts when object: options for the merger. when function: is the merger
+ * @return {MergeChain} @chainable
+ * @see dopemerge
+ *
+ * @example
+ * {
+ * stringToArray: true,
+ * boolToArray: false,
+ * boolAsRight: true,
+ * ignoreTypes: ['null', 'undefined', 'NaN'],
+ * debug: false,
+ * }
+ *
+ * @example
+ * .merger(require('lodash.mergewith')())
+ */
+ MergeChain.init = function init (parent) {
+ return new MergeChain(parent)
+ };
+
+ MergeChain.prototype.merger = function merger (opts) {
+ if (_function(opts)) { return this.set(MERGER_KEY, opts) }
+ return this.set(MERGER_OPTIONS_KEY, opts)
+ };
+
+ // [v] messes comments on conditional brace style
+ /* prettier-ignore */
+ /**
+ * @desc merges object in, goes through all keys, checks cbs, dopemerges
+ *
+ * @since 1.0.0
+ *
+ * @param {Object} [obj2=undefined] object to merge in, defaults to this.get('obj')
+ * @return {MergeChain} @chainable
+ *
+ * @see ChainedMap
+ * @TODO issue here if we extend without shorthands &
+ * we want to merge existing values... :s
+ *
+ *
+ * @example
+ *
+ * const chain = new Chain()
+ * chain.merge({canada: {eh: true}})
+ * chain.merge({canada: {arr: [0, {'1': 2}], eh: {again: true}}})
+ * chain.entries()
+ * //=> {canada:{ eh: {again: true}, arr: [0, {'1': 2}] }}
+ *
+ */
+ MergeChain.prototype.merge = function merge (obj2) {
+ var this$1 = this;
+
+ // better uglifying
+ var parent = this.parent;
+ var get = function (key) { return this$1.get(key); };
+
+ var onExisting = get(ON_EXISTING_KEY);
+ var onValue = get(ON_VALUE_KEY);
+ var opts = get(MERGER_OPTIONS_KEY);
+ var obj = obj2 || get(OBJ_KEY);
+ var merger = get(MERGER_KEY);
+ var shorthands$$1 = parent.meta ? parent.meta(shorthands) : {};
+ var keys$$1 = keys(obj);
+
+ // @@debugger
+
+ /* istanbul ignore next: devs */
+ if (dev) {
+ if (!obj) {
+ console.log({onExisting: onExisting, opts: opts, obj: obj, merger: merger, shorthands: shorthands$$1, keys: keys$$1, parent: parent});
+ throw new Error('must provide an object to merge')
+ }
+ }
+
+ /**
+ * @private
+ *
+ * since this would be slower
+ * if I want to not have a speedy default when using .onExisting
+ * should @note to use .extend
+ * when using chains without a class & doing .merge (edge-case)
+ *
+ * @param {Primitive} key key (shorthands[key] or just key)
+ * @param {*} value obj[key]
+ * @return {void}
+ *
+ * @TODO could use .eq here
+ * @TODO if (isMapish(obj)) obj = obj.entries()
+ *
+ * @example
+ * var obj = {key: 1}
+ *
+ * MergeChain.init(obj).merge({key: ['value']})
+ *
+ * // goes to this internal scoped function
+ * handleExisting('key', ['value'])
+ * // if there is .onValue or .onExisting, use them, default deepmerge
+ *
+ * obj
+ * //=> {key: [1, 'value']}
+ *
+ */
+ var handleExisting = function (key, value) {
+ /**
+ * @desc when fn is a full method, not an extended shorthand
+ * @since 0.5.0
+ *
+ * @param {Primitive} keyToSet key we chose to set
+ * @param {*} valueToSet value we chose to set (merged, existing, new)
+ * @return {Parent | Chain | *} .set or [keyToSet] return
+ *
+ * @example
+ *
+ * MergeChain.init(new Chain().extend(['eh']))
+ *
+ * //isFunction: true => call parent[keyToSet](valueToSet)
+ * setChosen('eh', 1)
+ * //=> parent
+ * parent.get('eh')
+ * //=> 1
+ *
+ * //=>isFunction: false => parent.set(keyToSet, valueToSet)
+ * setChosen('oh', 1)
+ * //=> parent //<- unless .set is overriden
+ * parent.get('oh')
+ * //=> 1
+ *
+ */
+ var setChosen = function (keyToSet, valueToSet) { return (_function(parent[key])
+ ? parent[keyToSet](valueToSet)
+ : parent.set(keyToSet, valueToSet)); };
+
+ /**
+ * check if it's shorthanded
+ * -> check if it has a value already
+ */
+ if (_true(parent.has(key))) {
+ // get that value
+ var existing = parent.get(key);
+
+ /**
+ * if we have onExisting, call it
+ * else default to dopemerge
+ */
+ if (_undefined(onExisting)) {
+ /* istanbul ignore next: devs */
+ if (debug) {
+ console.log(
+ 'parent has: no onExisting',
+ {existing: existing, [key]: value}
+ );
+ }
+ setChosen(key, merger(existing, value, opts));
+ }
+ else {
+ /* istanbul ignore next: devs */
+ if (debug) {
+ console.log(
+ 'parent has: has onExisting',
+ {existing: existing, onExisting: onExisting, [key]: value}
+ );
+ }
+
+ /**
+ * maybe we should not even have `.onExisting`
+ * since we can just override merge method...
+ * and then client can just use a custom merger...
+ *
+ * could add and remove subscriber but that's overhead and
+ * tricky here, because if we set a value that was just set...
+ */
+ setChosen(key, onExisting(existing, value, opts));
+ }
+ }
+ else {
+ /* istanbul ignore next: devs */
+ if (debug) {
+ console.log('parent does not have', {[key]: value});
+ }
+ setChosen(key, value);
+ }
+ };
+
+ for (var k = 0, len = keys$$1.length; k < len; k++) {
+ // key to the current property in the data being merged
+ var key = keys$$1[k];
+
+ // we have our value, no we can change the key if needed for shorthands
+ var value = obj[key];
+
+ // @NOTE: when shorthands is an object, key is the method it should call
+ if (!_undefined(shorthands$$1[key]) && shorthands$$1[key] !== key) {
+ /* istanbul ignore next: devs */
+ if (debug) {
+ console.log(
+ 'had a shorthand with a diff key than the object (likely @alias)',
+ {shorthandMethod: shorthands$$1[key], key: key, value: value}
+ );
+ }
+ key = shorthands$$1[key];
+ }
+
+ // method for the key
+ var method = parent[key];
+
+ /* istanbul ignore next: sourcemaps trigger istanbul here incorrectly */
+ // use onValue when set
+ if (!onValue(value, key, this$1)) {
+ /* istanbul ignore next: devs */
+ if (debug) {
+ console.log('had onValue, was false, ignored', {onValue: onValue, key: key, value: value});
+ }
+ continue
+ }
+ // when property itself is a Chainable
+ else if (mapish(method)) {
+ /* istanbul ignore next: devs */
+ if (debug) {
+ console.log('has method or shorthand');
+ }
+ parent[key].merge(value);
+ }
+ // we have a method or shorthand
+ else if (method) {
+ /* istanbul ignore next: devs */
+ if (debug) {
+ console.log('has method or shorthand', {method: method, key: key, value: value});
+ }
+ handleExisting(key, value);
+ }
+ // default to .set on the store
+ else {
+ /* istanbul ignore next: devs */
+ if (debug) {
+ console.log('went to default', {method: method, key: key, value: value});
+ }
+ parent.set(key, value);
+ }
+ }
+
+ return parent
+ };
+
+ return MergeChain;
+ }(ChainedMapBase));
+
+ /**
+ * @memberOf MergeChain
+ * @method onExisting
+ * @since 0.9.0
+ * @example
+ *
+ * const {Chain, MergeChain} = require('chain-able')
+ *
+ * const chain = new Chain().set('str', 'stringy')
+ *
+ * MergeChain.init(chain)
+ * .onExisting((a, b) => a + b)
+ * .merge({str: '+'})
+ *
+ * chain.get('str')
+ * //=> 'stringy+'
+ *
+ */
+
+ var MergeChain_1 = MergeChain;
+
+ // @TODO re-enable this later
+ // module.exports = new MethodChain(MergeChain.prototype)
+ // .methods(['onExisting', 'onValue', 'obj'])
+ // .build(MergeChain)
+
+ /* ___filename___: dist/MergeChain.js */
+
+ /* ___filename___: dist/ChainedMap.js */
+
+
+
+
+
+ /**
+ * @desc ChainedMap composer
+ * @category Chainable
+ * @category Map
+ * @memberOf ChainedMapBase
+ * @class ChainedMap
+ * @since 0.0.1
+ * @alias ComposeMap
+ * @extends {ChainedMapBase}
+ *
+ * @param {Class | Object | Composable} [SuperClass=ChainedMapBase] class to extend
+ * @return {Class} ChainedMap
+ *
+ * @see ChainedMapBase
+ * @tests ChainedMap
+ * @types ChainedMap
+ *
+ * @example
+ *
+ * const heh = class {}
+ * const composed = ChainedMap.compose(heh)
+ * const hehchain = new Composed()
+ * hehchain instanceof heh
+ * //=> true
+ *
+ */
+
+ var ComposeChainedMap = function (SuperClass) {
+ var Composed =
+ SuperClass === ChainedMapBase
+ ? SuperClass
+ : ChainedMapBase.compose(SuperClass);
+
+ var ChainedMap = (function (Composed) {
+ function ChainedMap () {
+ Composed.apply(this, arguments);
+ }
+
+ if ( Composed ) ChainedMap.__proto__ = Composed;
+ ChainedMap.prototype = Object.create( Composed && Composed.prototype );
+ ChainedMap.prototype.constructor = ChainedMap;
+
+ ChainedMap.prototype.methods = function methods (names) { return this.method(names) };
+
+ /**
+ * @desc the way to easily start building methods when using chainable instances
+ *
+ * @since 4.0.0
+ * @category methods
+ * @alias methods
+ *
+ * @param {string | Array | Primitive} names method names to add to the object
+ * @return {MethodChain} @chainable
+ *
+ * @see MethodChain
+ *
+ * @example
+ *
+ * const chain = new Chain()
+ * chain.method('eh').build()
+ * chain.eh(true)
+ * chain.get('eh')
+ * // => true
+ *
+ */
+ ChainedMap.prototype.method = function method (names) {
+ return new MethodChain_1(this).name(names)
+ };
+
+ /**
+ * @desc merges an object with the current store
+ * @since 0.4.0
+ * @category merge
+ *
+ * @param {Object} obj object to merge
+ * @param {Function | null} [handleMergeFn=undefined] return the merger to the callback
+ * @return {ChainedMap} @chainable
+ *
+ * @TODO needs to pass in additional opts somehow...
+ * @see deps/dopemerge
+ * @see MergeChain
+ *
+ * @example
+ *
+ * const chain = new Chain()
+ * chain.set('eh', [1])
+ * chain.merge({eh: [2]})
+ * chain.get('eh')
+ * // => [1, 2]
+ *
+ * @example
+ *
+ * const chain = new Chain()
+ * chain.set('emptyArr', [])
+ * chain.merge({emptyArr: []}, mergeChain =>
+ * mergeChain.onExisting((a, b) => []).merger((a, b) => []).merge()
+ * )
+ * chain.get('emptyArr').length)
+ * //=> 0
+ *
+ */
+ ChainedMap.prototype.merge = function merge (obj, handleMergeFn) {
+ var merger = MergeChain_1.init(this);
+
+ if (_undefined(handleMergeFn)) {
+ merger.merge(obj);
+ }
+ else {
+ handleMergeFn(merger.obj(obj));
+ }
+
+ return this
+ };
+
+ return ChainedMap;
+ }(Composed));
+
+ return ChainedMap
+ };
+
+ var composed = ComposeChainedMap(ChainedMapBase);
+ composed.compose = ComposeChainedMap;
+
+ var ChainedMap = composed;
+
+ /* ___filename___: dist/ChainedSet.js */
+
+
+
+ /**
+ * @class
+ * @category Chainable
+ * @category Set
+ * @memberOf Chainable
+ * @member ChainedSet
+ *
+ * @TODO could add .first .last ?
+ * @NOTE had Symbol.isConcatSpreadable but it was not useful
+ *
+ * @tutorial https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set
+ * @see http://2ality.com/2015/09/well-known-symbols-es6.html
+ * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/isConcatSpreadable
+ * @see Chainable
+ * @tests ChainedSet
+ * @types ChainedSet
+ *
+ * @extends {Chainable}
+ * @prop {Set} store
+ * @type {Set}
+ */
+ var ChainedSet = (function (Chainable$$2) {
+ function ChainedSet(parent) {
+ Chainable$$2.call(this, parent);
+ this.store = new Set();
+ }
+
+ if ( Chainable$$2 ) ChainedSet.__proto__ = Chainable$$2;
+ ChainedSet.prototype = Object.create( Chainable$$2 && Chainable$$2.prototype );
+ ChainedSet.prototype.constructor = ChainedSet;
+
+ /**
+ * @desc appends a new element with a specified value to the end of the .store
+ * @memberOf ChainedSet
+ * @since 0.4.0
+ *
+ * @param {any} value any value to add to **end** of the store
+ * @return {ChainedSet} @chainable
+ *
+ * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/add mozilla-set-add}
+ * {@link https://github.com/lodash/lodash/blob/master/.internal/addSetEntry.js#L9 lodash-add-set-entry}
+ * @see {@link mozilla-set-add}
+ * @see {@link lodash-add-set-entry}
+ *
+ * @example
+ *
+ * const people = new ChainedSet()
+ * people
+ * .add('sam')
+ * .add('sue')
+ *
+ * for (let name of people) console.log(name)
+ * //=> sam, sue
+ *
+ */
+ ChainedSet.prototype.add = function add (value) {
+ this.store.add(value);
+ return this
+ };
+
+ /**
+ * @desc inserts the value at the **beginning** of the Set
+ * @memberOf ChainedSet
+ * @since 0.4.0
+ *
+ * @param {any} value any value to add to **beginning** the store
+ * @return {ChainedSet} @chainable
+ *
+ * @example
+ *
+ * const people = new ChainedSet()
+ * people
+ * .add('sue')
+ * .prepend('first')
+ *
+ * for (let name of people) console.log(name)
+ * //=> first, sue
+ *
+ */
+ ChainedSet.prototype.prepend = function prepend (value) {
+ this.store = new Set([value].concat(Chainable$$2.prototype.values.call(this)));
+ return this
+ };
+
+ /**
+ * @desc merge any Array/Set/Iteratable/Concatables into the array, at the end
+ * @since 0.4.0
+ * @memberOf ChainedSet
+ *
+ * @param {Array | Set | Concatable} arr values to merge in and append
+ * @return {ChainedSet} @chainable
+ *
+ * @example
+ *
+ * const people = new ChainedSet()
+ * people
+ * .add('sam')
+ * .add('sue')
+ * .prepend('first')
+ * .merge(['merged'])
+ *
+ * for (let name of people) console.log(name)
+ * //=> first, sam, sue, merged
+ *
+ */
+ ChainedSet.prototype.merge = function merge (arr) {
+ var this$1 = this;
+
+ var mergeable = toArr(arr);
+ for (var i = 0; i < mergeable.length; i++) {
+ this$1.store.add(mergeable[i]);
+ }
+ return this
+ };
+
+ return ChainedSet;
+ }(Chainable));
+
+ var ChainedSet_1 = ChainedSet;
+
+ /* ___filename___: dist/ChainedMap.js */
+
+ /* ___filename___: dist/FactoryChain.js */
+
+
+
+
+
+ var ON_CHAIN_UP_DOWN_KEY = 'onChainUpDown';
+ var ON_DONE_KEY = 'onDone';
+
+ /**
+ * @extends {ChainedMapBase}
+ * @inheritdoc
+ * @prop {Object} data
+ * @prop {Set} _calls
+ * @type {Map}
+ *
+ * {@link http://robdodson.me/javascript-design-patterns-factory/ abstract-factory-pattern}
+ *
+ * @member FactoryChain
+ * @category Chainable
+ * @tests FactoryChain
+ * @types FactoryChain
+ */
+ var FactoryChain = (function (ChainedMap$$1) {
+ function FactoryChain(parent) {
+ ChainedMap$$1.call(this, parent);
+
+ this.data = {};
+ this._calls = new Set();
+
+ this.factory()
+ .extend(['optional', 'required', ON_CHAIN_UP_DOWN_KEY, ON_DONE_KEY])
+ .set('len', 0);
+ }
+
+ if ( ChainedMap$$1 ) FactoryChain.__proto__ = ChainedMap$$1;
+ FactoryChain.prototype = Object.create( ChainedMap$$1 && ChainedMap$$1.prototype );
+ FactoryChain.prototype.constructor = FactoryChain;
+
+ /**
+ * @desc chain back up to parent for any of these
+ * @since 2.0.0
+ *
+ * @param {Array} methods methods to trigger `onChainUpDown` on
+ * @return {FactoryChain} @chainable
+ *
+ * @memberOf FactoryChain
+ * @emits onChainUpDown
+ * @TODO should have a debug log for this
+ *
+ * @example
+ *
+ * const {Chain, FactoryChain, ChainedSet} = require('chain-able')
+ *
+ * class Things extends Chain {
+ * constructor(parent) {
+ * super(parent)
+ * this.people = new ChainedSet(this)
+ * }
+ * person() {
+ * const person = new FactoryChain(this)
+ * person
+ * .props(['name', 'age', 'email'])
+ * .onChainUpDown(this.person)
+ * .chainUpDowns(['person'])
+ * .onDone(personChain => {
+ * this.people.add(personChain)
+ * return this
+ * })
+ *
+ * return person
+ * }
+ * }
+ *
+ * const things = new Things()
+ * const returned = things
+ * .person()
+ * .name('sue')
+ * .person()
+ * .age(100)
+ * .name('john')
+ * .email('@')
+ *
+ */
+ FactoryChain.prototype.chainUpDowns = function chainUpDowns (methods) {
+ var arguments$1 = arguments;
+ var this$1 = this;
+
+ methods.forEach(function (m) {
+ this$1[m] = function () {
+ // @@debugger
+ this$1.end();
+ return this$1.parent[m].apply(this$1.parent, arguments$1)
+ };
+ });
+ return this
+ };
+
+ /**
+ * @desc adds an *array* of properties, using FactoryChain.prop
+ * @since 2.0.0
+ *
+ * @memberOf FactoryChain
+ * @param {Array} names property names
+ * @return {FactoryChain} @chainable
+ *
+ * @see FactoryChain.prop
+ *
+ * @example
+ *
+ * person.props(['name', 'age', 'email'])
+ *
+ * typeof person.name
+ * //=> 'function'
+ *
+ * person.name().age()
+ * //=> FactoryChain
+ *
+ * person.name().age().email()
+ * //=> ParentChain
+ *
+ * // person.name().age().person()
+ * //=> FactoryChain
+ * //^ because .person is `chainUpDowns`
+ * //^ so it finishes the old chain, and begins a new one
+ *
+ */
+ FactoryChain.prototype.props = function props (names) {
+ var this$1 = this;
+
+ names.forEach(function (name) { return this$1.prop(name); });
+ return this
+ };
+
+ /* istanbul ignore next: sourcemaps trigger istanbul here incorrectly */
+ /**
+ * @desc add property that are counted towards the call count for easy auto-ending chaining
+ * @since 2.0.0
+ *
+ * @param {Primitive} name property name
+ * @param {Function | null | undefined} [onCall=undefined] callback for the property
+ * @return {FactoryChain} @chainable
+ *
+ * @memberOf FactoryChain
+ *
+ * @example
+ *
+ * person
+ * //.prop also accepts an optional callback,
+ * //for nestable nestable chains
+ * .prop('name')
+ * .prop('age')
+ * .prop('email')
+ *
+ */
+ FactoryChain.prototype.prop = function prop (name, onCall) {
+ var this$1 = this;
+
+ this.tap('len', function (len) { return len + 1; });
+
+ // so if we call a property twice,
+ // chain back up to parent,
+ // add a new chain
+ if (!_undefined(this[name]) && _true(this.has(ON_CHAIN_UP_DOWN_KEY))) {
+ this.end();
+ return this.get(ON_CHAIN_UP_DOWN_KEY)()[name](onCall)
+ }
+
+ // @TODO need to spread as needed
+ this[name] = function (args) {
+ // @@debugger
+ /* istanbul ignore next: devs */
+ if (debug) {
+ console.log(
+ ("called " + name + " with:"),
+ args,
+ "calls length is now:",
+ this$1._calls.size
+ );
+ }
+ if (_undefined(onCall)) { this$1.data[name] = args; }
+ else { onCall(args); }
+
+ this$1._calls.add(name);
+
+ // aka magicReturn
+ return this$1._calls.size === this$1.get('len') ? this$1.end() : this$1
+ };
+ return this
+ };
+
+ /**
+ * @desc access data being built when stepping through a factory
+ * @since 2.0.0
+ *
+ * @param {Primitive} [prop=undefined] key of the data, or returns all data
+ * @return {any} this.data
+ *
+ * @memberOf FactoryChain
+ *
+ * @example
+ *
+ * .data['prop'] = 'eh'
+ * .getData('prop')
+ * //=> 'eh'
+ * .getData()
+ * //=> {prop: 'eh'}
+ *
+ * @example
+ *
+ * const person = new FactoryChain(this)
+ * const age = person.props(['name', 'age']).age(10).getData('age')
+ * expect(age).toBe(10)
+ *
+ */
+ FactoryChain.prototype.getData = function getData (prop) {
+ /* istanbul ignore next: sourcemaps trigger istanbul here incorrectly */
+ return _undefined(prop) ? this.data : this.data[prop]
+ };
+
+ /* istanbul ignore next: sourcemaps trigger istanbul here incorrectly */
+ /**
+ * @desc creates/add the `.end` method,
+ * which checks how many methods have been called,
+ * and decides whether to return parent or not
+ * @modifies this.end
+ *
+ * @since 2.0.0
+ *
+ * @param {Object} [obj={}] optional object to use for creating .end
+ * @return {FactoryChain} @chainable
+ *
+ * @memberOf FactoryChain
+ */
+ FactoryChain.prototype.factory = function factory (obj) {
+ var this$1 = this;
+
+ this.end = function (arg) {
+ // @@debugger
+ var ended;
+
+ if (obj && !_undefined(obj.end)) { ended = obj.end; }
+ else if (this$1.has(ON_DONE_KEY)) { ended = this$1.get(ON_DONE_KEY); }
+
+ if (ended) { ended = ended.call(this$1, this$1.data, this$1.parent, this$1, arg); }
+
+ if (ended && ended !== this$1) { return ended }
+ else { return this$1.parent }
+ };
+
+ return this
+ };
+
+ return FactoryChain;
+ }(ChainedMap));
+
+ var FactoryChain_1 = FactoryChain;
+
+ /* ___filename___: dist/deps/fp/pipeTwo.js */
+ /**
+ * Performs left-to-right function composition. ONLY CAN PIPE 2 ARGUMENTS
+ *
+ * @NOTE The result of pipe is not automatically curried.
+ * @NOTE This is a variation, is the internal version with only 2 functions, for now
+ *
+ * @func
+ * @memberOf fp
+ * @since v5.0.0
+ * @category Function
+ *
+ * @param {...Function} f function first
+ * @param {...Function} g function next
+ * @return {Function}
+ *
+ * @see https://github.com/ramda/ramda/blob/master/src/pipe.js
+ * @see https://github.com/ramda/ramda/blob/master/test/pipe.js
+ *
+ * @types fp
+ * @tests fp/pipe
+ *
+ * @example
+ *
+ * var f = R.pipe(Math.pow, R.negate);
+ * f(3, 4); // -(3^4) + 1
+ *
+ */
+ var pipeTwo = function _pipe(f, g) {
+ return function() {
+ return g.call(this, f.apply(this, arguments))
+ }
+ };
+
+ /* ___filename___: dist/deps/matcher/escape-string-regex.js */
+
+
+ /**
+ * @func escapeStringRegExp
+ * @module escape-string-regexp
+ * @memberOf matcher
+ * @since 3.0.0
+ *
+ * @param {string} str string to escape
+ * @return {string} escaped string
+ *
+ * {@link https://github.com/sindresorhus/escape-string-regexp escape-string-regexp}
+ * @see {@link escape-string-regexp *} 🍴
+ * @see fp/replace
+ *
+ * @NOTE also as const escapeStringRegexp = require('escape-string-regexp');
+ *
+ * @example
+ *
+ * const escaped = escapeStringRegexp('how much $ for a unicorn?');
+ * //=> 'how much \$ for a unicorn\?'
+ * new RegExp(escaped);
+ *
+ */
+ var escapeStringRegex = replace(/[|\\{}()[\]^$+*?.]/g, '\\$&');
+
+ /* ___filename___: dist/deps/fp/pipeTwo.js */
+
+ /* ___filename___: dist/deps/matcher/escape-string-regex.js */
+
+ /* ___filename___: dist/deps/matcher/to-regexp.js */
+
+
+
+
+ /**
+ * @func toRegExp
+ * @memberOf matcher
+ * @module to-regexp
+ * @extends escapeStringRegExp
+ *
+ * @param {string} str string to escape
+ * @return {string} escaped str
+ *
+ * @example
+ *
+ * toRegExp('*')
+ * => '.*'
+ *
+ * toRegExp('eh')
+ * => 'eh'
+ *
+ */
+ var toRegexp = pipeTwo(escapeStringRegex, replace(/\\\*/g, '.*'));
+
+ /* ___filename___: dist/deps/matcher/to-regexp.js */
+
+ /* ___filename___: dist/deps/matcher/matcher.js */
+ /**
+ * @name matcher
+ * @member matcher
+ * @see https://github.com/sindresorhus/matcher/blob/master/index.js
+ * @symb 🎯
+ * @types matcher
+ * @tests deps/matcher
+ */
+
+
+
+
+
+
+
+ var m = {};
+
+ /**
+ * @desc turn any string[], function[], or RegExp[] into a matcher
+ * @memberOf matcher
+ * @since 3.0.0
+ * @func make
+ *
+ * @param {Array | string | Function | RegExp} pattern a matchable pattern
+ * @param {boolean | undefined} shouldNegate turn into a negated regex
+ * @param {boolean | undefined} alphaOmega should have regex start at the beginning and the end
+ * @return {Array | string | Function | RegExp} matchable
+ *
+ * @example
+ *
+ * matcher.make('*')
+ * //=> RegExp('.*', 'i')
+ *
+ * @example
+ *
+ * var any = new RgExp('.*', 'i')
+ * matcher.make(any)
+ * //=> any
+ *
+ * @example
+ *
+ * var strings = x => typeof x === 'string'
+ * matcher.make(strings)
+ * // {test: strings}
+ *
+ * @example
+ *
+ * var tester = {test: x => x === true}
+ * matcher.make(tester)
+ * // tester
+ *
+ * @example
+ *
+ * var noName = '!name'
+ * matcher.make(noName, true)
+ * // new RegExp('(?:name)', 'i')
+ *
+ * @example
+ *
+ * var noName = '!name'
+ * matcher.make(noName, true, true)
+ * // new RegExp('^(?:name)$', 'i')
+ *
+ */
+ m.make = function (pattern, shouldNegate, alphaOmega) {
+ if (index$10.has(pattern)) { return index$10.get(pattern) }
+
+ var matchable = pattern;
+ if (matcher(matchable) && !matchable.test) { matchable.test = matchable; }
+ if (matcher(matchable)) { return matchable }
+
+ // if (!matchable) {
+ // console.log({pattern, shouldNegate, alphaOmega})
+ // throw new Error('eh')
+ // }
+ var negated = matchable[0] === '!';
+ if (negated) { matchable = matchable.slice(1); }
+ matchable = toRegexp(matchable);
+
+ if (negated && shouldNegate) { matchable = "(?!" + matchable + ")"; }
+ if (alphaOmega) { matchable = "^" + matchable + "$"; }
+
+ matchable = regexp$2(("" + matchable), 'i');
+ matchable.negated = negated;
+
+ index$10.set(pattern, matchable);
+ return matchable
+ };
+
+ /**
+ * @desc same as .make but also accepts inputs, and returns an array
+ * @memberOf matcher
+ * @func match
+ * @since 3.0.0
+ *
+ * @param {Array | string} inputs input to use patterns as predicates on
+ * @param {Array | string | Function | RegExp} patterns predicates to match with, transformed to Matcher
+ * @param {boolean | undefined} shouldNegate should negate, passed to matcher.make
+ * @param {boolean | undefined} alphaOmega should enforce regex @beginning and end, passed to .matcher
+ * @return {Array}
+ *
+ * @see Matcher.make
+ * @see compose/Observe
+ *
+ * @example
+ *
+ *
+ * matcher(['foo', 'bar', 'moo'], ['*oo', '!foo']);
+ * //=> ['moo']
+ *
+ * matcher(['foo', 'bar', 'moo'], ['!*oo']);
+ *
+ *
+ * @example
+ *
+ *
+ * matcher('kinga', 'kinga')
+ * //=> ['kinga']
+ * matcher('k*nga', 'kinga')
+ * //=> ['kinga']
+ * matcher('kinga', 'nope')
+ * //=> []
+ *
+ * matcher(new RegExp(/kinga/), 'kinga')
+ * //=> ['kinga']
+ * matcher(new RegExp(/kinga/), 'nope')
+ * //=> ['nope']
+ *
+ * matcher(x => x === 'kinga', 'kinga')
+ * //=> ['kinga']
+ * matcher(x => x === 'kinga', 'nope')
+ * //=> []
+ *
+ * matcher({test: x => x === 'kinga'}, 'kinga')
+ * //=> ['kinga']
+ * matcher({test: x => x === 'kinga'}, 'nope')
+ * //=> []
+ *
+ *
+ */
+ m.matcher = function (inputs, patterns, shouldNegate, alphaOmega) {
+ patterns = toArr(patterns).map(function (p) { return m.make(p, shouldNegate, alphaOmega); });
+ inputs = toArr(inputs);
+
+ var firstNegated = patterns[0].negated;
+ var matchesToReturn = [];
+
+ for (var i = 0; i < inputs.length; i++) {
+ var input = inputs[i];
+ // If first pattern is negated we include everything to match user expectation
+ var matches = firstNegated;
+ for (var j = 0; j < patterns.length; j++) {
+ if (patterns[j].test(input)) {
+ matches = !patterns[j].negated;
+ }
+ }
+
+ if (matches) { matchesToReturn.push(input); }
+ }
+
+ return matchesToReturn
+ };
+
+ /**
+ * @TODO replace to-test
+ */
+ // m.test = (inputs, patterns) => m.matcher(inputs, patterns).length !== 0
+
+ var matcher$2 = assign(m.matcher, m);
+
+ /* ___filename___: dist/deps/matcher/matcher.js */
+
+ var index$18 = matcher$2;
+
+ /* ___filename___: dist/compose/Observe.js */
+
+
+ // const eq = require('../deps/traversers/eq')
+
+
+
+
+
+ var eq$1 = traverse_1.eq;
+ var clone$1 = traverse_1.clone;
+
+ /**
+ * scoped clones
+ * @private
+ * @type {Map}
+ */
+ var objs = new Map();
+
+ /**
+ * @desc > subscribe to changes
+ * ❗ called only on **change**
+ * observers are only called when data they subscribe to changes
+ *
+ * @since 3.0.1
+ * @class Observe
+ * @member Observe
+ * @extends {ChainedMap}
+ * @extends {DotProp}
+ * @memberOf compose
+ * @category Chainable
+ *
+ * @param {Class | Composable} Target composable class
+ * @return {Observe} class
+ *
+ * @tests Observe
+ * @types Observe
+ *
+ * @see ChainedMap
+ * @see DotProp
+ * @see deps/matcher
+ * @see deps/traversers/eq
+ * @see deps/traverse
+ * @see DotProp
+ *
+ * {@link https://github.com/iluwatar/java-design-patterns/tree/master/observer observer-pattern}
+ * {@link https://github.com/ReactiveX/rxjs/blob/master/src/Subscriber.ts reactivex}
+ * {@link https://github.com/sindresorhus/awesome-observables awesome-observables}
+ * {@link https://medium.com/@benlesh/learning-observable-by-building-observable-d5da57405d87 building-observables}
+ * {@link https://github.com/addyosmani/essential-js-design-patterns/blob/master/diagrams/observer.png js-observer-png}
+ * {@link https://github.com/addyosmani/essential-js-design-patterns/blob/master/diagrams/publishsubscribe.png pubsub-png}
+ * {@link https://github.com/tusharmath/observable-air observable-air}
+ *
+ * @see {@link reactivex}
+ * @see {@link awesome-observables}
+ * @see {@link building-observables}
+ * @see {@link observer-pattern}
+ * @see {@link observable-air}
+ *
+ * @example
+ *
+ * const {compose} = require('chain-able')
+ * const {DotProp} = compose
+ * new DotProp()
+ * //=> DotProp
+ *
+ */
+ var Observe = function (Target) {
+ // return class Observe extends Target {
+ /**
+ * @desc observe properties when they change
+ *
+ * @method
+ * @memberOf Observe
+ * @since 4.0.0 <- refactored with dot-prop
+ * @since 1.0.0
+ *
+ * @param {Matchable} properties Matchable properties to observe
+ * @param {Function} fn onChanged
+ * @return {Target} @chainable
+ *
+ * @see traversers/eq
+ * @see toarr
+ * @see matcher
+ *
+ * {@link https://jsfiddle.net/wqxuags2/28/ for a Demo Clock with observable}
+ *
+ * @see {@link for a Demo Clock with observable}
+ * @see examples/playground/TodoStore
+ *
+ * @TODO gotta update `data` if `deleting` too...
+ * @TODO un-observe
+ * @TODO should hash these callback properties
+ * @TODO just throttle the `.set` to allow easier version of .commit
+ *
+ * @example
+ *
+ * const Target = require('chain-able')
+ *
+ * const chain = new Target()
+ * const log = arg => console.log(arg)
+ *
+ * chain
+ * .extend(['eh'])
+ * .observe('eh', data => log(data))
+ * .eh(true)
+ * //=> {eh: true}
+ *
+ * @example
+ *
+ * chain
+ * .extend(['canada', 'timbuck'])
+ * .observe(['canad*'], data => console.log(data.canada))
+ * .canada(true)
+ * .canada(true)
+ * .timbuck(false)
+ *
+ * //=> true
+ * //=> false
+ *
+ * // only called when changed,
+ * // otherwise it would be 2 `true` & 1 `false`
+ *
+ */
+ Target.prototype.observe = function chainObserve(properties, fn) {
+ var this$1 = this;
+
+ var props = toArr(properties);
+ var hashKey = props.join('_');
+ var data = {};
+
+ /* prettier-ignore */
+ return this.meta(observers, function (changed) {
+ /**
+ * match the keys, make the data out of it
+ */
+ var m = index$18(changed.key, props);
+
+ // @@debugger
+
+ for (var i = 0; i < m.length; i++) {
+ var segments$$2 = segments(m[i]);
+ set$2(data, segments$$2, this$1.get(segments$$2));
+ }
+
+ /**
+ * if we have called it at least once...
+ * and it has not changed, leave it
+ * else
+ * clone it
+ * call the observer
+ */
+ if (objs.has(hashKey) && eq$1(objs.get(hashKey), data)) {
+ // @@debugger
+ return
+ }
+
+ // @@debugger
+
+ /**
+ * it did change - clone it for next deepEquals check
+ */
+ objs.set(hashKey, clone$1(data));
+
+ /**
+ * call the observer - it matched & data changed
+ */
+ fn.call(this$1, data, this$1);
+ })
+ };
+ return Target
+ };
+
+ /* ___filename___: dist/compose/Shorthands.js */
+ /**
+ * @since 2.0.0
+ */
+
+
+
+
+ /**
+ * @class Shorthands
+ * @member Shorthands
+ * @extends {ChainedMap}
+ * @extends {DotProp}
+ * @memberOf compose
+ * @category Chainable
+ *
+ * @param {Class | Composable} Target composable class
+ * @return {Shorthands} class
+ *
+ * @tests Shorthands
+ * @types Shorthands
+ *
+ * @see ChainedMap
+ * @see DotProp
+ * @see deps/matcher
+ * @see deps/traversers/eq
+ * @see deps/traverse
+ * @see DotProp
+ *
+ * {@link https://github.com/ReactiveX/rxjs/blob/master/src/Subscriber.ts reactivex}
+ * {@link https://github.com/sindresorhus/awesome-observables awesome-observables}
+ * {@link https://medium.com/@benlesh/learning-observable-by-building-observable-d5da57405d87 building-observables}
+ * @see {@link reactivex}
+ * @see {@link awesome-observables}
+ * @see {@link building-observables}
+ *
+ * @example
+ *
+ * const {compose} = require('chain-able')
+ * const {DotProp} = compose
+ * new DotProp()
+ * //=> DotProp
+ *
+ */
+ var Shorthands = function (Target) {
+ return (function (Target) {
+ function Shorthands(parent) {
+ Target.call(this, parent);
+
+ if (parent && parent.meta) {
+ this.meta.debug = parent.meta.debug;
+ }
+ else {
+ this.debug(false);
+ }
+ }
+
+ if ( Target ) Shorthands.__proto__ = Target;
+ Shorthands.prototype = Object.create( Target && Target.prototype );
+ Shorthands.prototype.constructor = Shorthands;
+
+ // https://github.com/fluents/chain-able/issues/32
+ // find(key, data = this.entries(true)) {
+ // let val = null
+ // const matcher = new RegExp(key.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&'))
+ // // console.debug(`key: ${key} `)
+ // const cb = (x, traverser) => {
+ // if (matcher.test(traverser.key) || traverser.path.includes(key)) {
+ // val = x
+ // traverser.stop()
+ // // console.error({x})
+ // }
+ // // console.debug(`path: ${traverser.path.join('.')} prop: ${traverser.key}`)
+ // // console.dir({x, path: traverser.path, key: traverser.key})
+ // }
+ //
+ // traverse(data).forEach(function(x) {
+ // cb(x, this)
+ // })
+ // return val
+ // }
+
+ /**
+ * @desc sets on store not this.set for easier extension
+ *
+ * @since 4.0.0 <- moved from Extend to Shorthands
+ * @since 0.2.0
+ *
+ * @param {boolean} [should=true] shouldDebug
+ * @return {Chainable} @chainable
+ *
+ * @NOTE is inherited by any chain with a parent with .meta.debug
+ *
+ * @example
+ *
+ * const Chain = require('chain-able')
+ * const chain = new Chain()
+ * chain.debug()
+ *
+ * chain.get('debug')
+ * //=> true
+ *
+ * // not in entries
+ * chain.entries()
+ * //=> {}
+ *
+ */
+ Shorthands.prototype.debug = function debug (should) {
+ this.meta.debug = _undefined(should) ? true : should;
+ return this
+ };
+
+ /**
+ * @desc sets a value **only** when .has is false
+ * aka set if the value has not been set
+ *
+ * @memberOf ShorthandChain
+ * @since 1.0.2
+ *
+ * @param {Primitive} name key to set if it has not been done so already
+ * @param {any} value value to set when key has not been already set
+ * @return {ShorthandChain} @chainable
+ *
+ * @see ChainedMapBase.set
+ *
+ * @example
+ *
+ * const chain = new Chain()
+ *
+ * chain.set('eh', true)
+ *
+ * // eh is already set ^, ignored
+ * chain.setIfEmpty('eh', false)
+ *
+ * chain.get('eh')
+ * //=> true
+ *
+ * @example
+ *
+ * new Chain().setIfEmpty('canada', true).entries()
+ * //=> {canada: true}
+ *
+ * @example
+ *
+ * // longhand way to do the same thing
+ * if (chain.has('eh') === false) {
+ * chain.set('eh', false)
+ * }
+ *
+ * // or using .when
+ * chain.when(!chain.has('eh'), instance => instance.set('eh', false))
+ *
+ */
+ Shorthands.prototype.setIfEmpty = function setIfEmpty (name, value) {
+ if (_false(this.has(name))) { return this.set(name, value) }
+ else { return this }
+ };
+
+ /**
+ * @desc returns any value passed in
+ * return a value at the end of a chain regardless
+ *
+ * @memberOf ShorthandChain
+ * @since 3.0.0
+ *
+ * @param {any} value value to return at the end of a chain
+ * @return {any} value
+ *
+ * @example
+ *
+ * const chain = new Chain()
+ *
+ * const saveAndDebug = env => chain
+ * .from({env: env.NODE_ENV})
+ * .return(JSON.stringify(env))
+ *
+ * console.log(saveAndDebug(process.env))
+ * //=> value of process.env
+ */
+ Shorthands.prototype.return = function return$1 (value) {
+ return value
+ };
+
+ /**
+ * @desc wrap a value, if it's a Function call it, return this
+ * aka execute something and return this
+ *
+ * @memberOf ShorthandChain
+ * @since 2.0.0
+ * @param {Function | any} fn function to call, or just any value
+ * @return {ShorthandChain} @chainable
+ *
+ * @example
+ *
+ * const {eh} = chain.wrap(chain => chain.eh = true)
+ * //=> true
+ *
+ * @example
+ *
+ * new Chain()
+ * .wrap(encased => encased.fn = arg => {
+ * throw new Error('encased yo')
+ * })
+ * .method('fn')
+ * .encase()
+ * .catch(error => {
+ * //=> Error('encasedYo')
+ * })
+ * .build()
+ * .fn(true)
+ *
+ */
+ Shorthands.prototype.wrap = function wrap (fn) {
+ if (_function(fn)) { fn.call(this, this); }
+ return this
+ };
+
+ return Shorthands;
+ }(Target))
+ };
+
+ /* ___filename___: dist/deps/to/boolean.js */
+ // http://people.mozilla.org/~jorendorff/es6-draft.html#sec-toboolean
+ var boolean_1$2 = function (x) { return !!x; };
+
+ /* ___filename___: dist/deps/fp/pipe.js */
+
+
+
+
+ /**
+ * Performs left-to-right function composition. The leftmost function may have
+ * any arity; the remaining functions must be unary.
+ * In some libraries this function is named `sequence`.
+ *
+ * @icon |
+ * @func
+ * @memberOf fp
+ * @since v5.0.0
+ * @category Function
+ * @sig (((a, b, ..., n) -> o), (o -> p), ..., (x -> y), (y -> z)) -> ((a, b, ..., n) -> z)
+ * @symb R.pipe(f, g, h)(a, b) = h(g(f(a, b)))
+ * @extends fp/pipeTwo
+ *
+ * @param {Function} first function first
+ * @param {...Function} rest function next
+ * @return {Function}
+ *
+ * @see R.compose
+ * @see https://github.com/ramda/ramda/blob/master/src/pipe.js
+ * @see https://github.com/ramda/ramda/blob/master/test/pipe.js
+ *
+ * @types fp
+ * @tests fp/pipe
+ *
+ * @example
+ *
+ * var f = R.pipe(Math.pow, R.negate, R.inc);
+ * f(3, 4); // -(3^4) + 1
+ *
+ * @example
+ *
+ * var x = v => v + 'x'
+ * var y = v => v + 'y'
+ * var z = v => v + 'z'
+ *
+ * const xyz = pipe(x, y, z)
+ * /// starts with w, adds x, then y, then z
+ * const wxyz = xyz('w')
+ * //=> 'wxyz'
+ */
+ var pipe = function pipe(first) {
+ // @TODO: could move into pipeArray
+ // could start from first, second? etc?
+ // (isArray(first) ? first : argumentor.apply(null, arguments))
+ var args = argumentor.apply(null, arguments)
+ .slice(1).reduce(function (previous, next) { return pipeTwo(previous, next); });
+
+ return pipeTwo(first, args)
+ };
+
+ /* ___filename___: dist/deps/to/boolean.js */
+
+ /* ___filename___: dist/deps/fp/pipe.js */
+
+ /* ___filename___: dist/deps/matcher/to-test.js */
+
+
+
+
+
+
+
+ // @TODO use in matcher
+ var constructEscRegExp = pipe(escapeStringRegex, regexp$2);
+
+ /**
+ * @desc like matcher, but .isMatch
+ * @since 3.0.0
+ *
+ * @param {Matchable} matchable any matchable
+ * @param {any} [arg1=undefined] arg to match with
+ * @param {any} [arg2=undefined] optional second arg to pass into tester
+ * @return {boolean} is a match, passes the test
+ *
+ * @NOTE as else-if for easier ternary uglification
+ *
+ * @example
+ *
+ * matcher('kinga', 'kinga')
+ * //=> true
+ * matcher('k*nga', 'kinga')
+ * //=> true
+ * matcher('kinga', 'nope')
+ * //=> false
+ *
+ * matcher(new RegExp(/kinga/), 'kinga')
+ * //=> true
+ * matcher(new RegExp(/kinga/), 'nope')
+ * //=> false
+ *
+ * matcher(x => x === 'kinga', 'kinga')
+ * //=> true
+ * matcher(x => x === 'kinga', 'nope')
+ * //=> false
+ *
+ * matcher({test: x => x === 'kinga'}, 'kinga')
+ * //=> true
+ * matcher({test: x => x === 'kinga'}, 'nope')
+ * //=> false
+ *
+ */
+ function toTest(matchable, arg1, arg2) {
+ if (stringPrimitive(matchable)) { return constructEscRegExp(matchable).test(arg1) }
+ else if (_function(matchable) && !matchable.test) { return matchable(arg1) }
+ else { return matchable.test(arg1, arg2) }
+ }
+
+ var toTest_1 = pipe(toTest, boolean_1$2);
+
+ /* ___filename___: dist/deps/matcher/to-test.js */
+
+ /* ___filename___: dist/deps/matcher/any-key-val.js */
+
+
+ /**
+ * the original simple to-test matcher for traversable,
+ * will be merged into, or simplified as simplified into matcher
+ *
+ * @since 2.0.0
+ *
+ * @TODO should use matcher,
+ * @TODO should inprove the callback data...
+ *
+ * @types matcher
+ *
+ * @param {Matchable[]} keys matchable keys
+ * @param {Matchable[]} vals matchable values
+ * @return {boolean} matched or not
+ *
+ * @example
+ *
+ * anyKeyVal([], [])(0, 0)
+ * //=> false
+ *
+ * anyKeyVal([() => true], [])(0, 0)
+ * //=> true
+ *
+ */
+ var anyKeyVal = function (keys, vals) { return function (prop, val) {
+ for (var i = 0; i < keys.length; i++) {
+ if (toTest_1(keys[i], prop, val)) { return true }
+ }
+ for (var i$1 = 0; i$1 < vals.length; i$1++) {
+ if (toTest_1(vals[i$1], val, prop)) { return true }
+ }
+ return false
+ }; };
+
+ /* ___filename___: dist/deps/matcher/any-key-val.js */
+
+ /* ___filename___: dist/TraverseChain.js */
+
+
+
+
+
+
+ var TRAVERSED_KEY = 1;
+ var EXTENSION_KEYS = ['obj', 'keys', 'vals', 'onNonMatch', 'onMatch', 'clone'];
+
+ /**
+ * @since 1.0.0
+ * @type {Map}
+ * @extends {ChainedMapBase}
+ *
+ * @memberOf Chainable
+ * @member Traverse
+ * @see deps/traverse
+ * @category traverse
+ * @types TraverseChain
+ * @tests TraverseChain
+ * @symb 👣
+ *
+ * @prop {Object} obj
+ * @prop {Array} [keys]
+ * @prop {Array} [vals]
+ * @prop {Function} [onMatch]
+ * @prop {Function} [onNonMatch]
+ * @prop {boolean} [clone]
+ */
+ var TraverseChain = (function (ChainedMapBase$$2) {
+ function Traverser(parent) {
+ ChainedMapBase$$2.call(this, parent);
+ this.call = this.traverse.bind(this);
+
+ /* prettier-ignore */
+ this
+ .extend(EXTENSION_KEYS)
+ .keys([])
+ .vals([])
+ // key,
+ .onMatch(function (arg, traverser) { return traverser.remove(); });
+ }
+
+ if ( ChainedMapBase$$2 ) Traverser.__proto__ = ChainedMapBase$$2;
+ Traverser.prototype = Object.create( ChainedMapBase$$2 && ChainedMapBase$$2.prototype );
+ Traverser.prototype.constructor = Traverser;
+
+ /**
+ * @desc runs traverser, checks the tests, calls the onMatch
+ * @modifies this.cleaned
+ *
+ * @alias call
+ * @since 1.0.0
+ * @param {boolean} [shouldReturn=false] returns traversed object
+ * @return {any} this.obj/data cleaned
+ *
+ * @memberOf TraverseChain
+ *
+ * @example
+ *
+ * const traversed = new Chain()
+ * .merge({flat: 0, one: {two: true}})
+ * .traverse(false)
+ * .vals([/true/])
+ * .onMatch((current, traverser) => {
+ * traverser.path.join('.')
+ * //=> 'one.two'
+ *
+ * current
+ * //=> true
+ *
+ * typeof traverser.update === typeof traverser.remove
+ * typeof traverser.update === 'function'
+ * //=> true
+ *
+ * traverser.remove()
+ * //=> void
+ * })
+ * .onNonMatch(val => {
+ * // ignore
+ * })
+ * .call(true)
+ *
+ * traversed
+ * //=> {flat: 0}
+ *
+ */
+ Traverser.prototype.traverse = function traverse$1 (shouldReturn) {
+ var ref = this.entries();
+ var obj = ref.obj;
+ var keys = ref.keys;
+ var vals = ref.vals;
+ var onMatch = ref.onMatch;
+ var onNonMatch = ref.onNonMatch;
+ var clone = ref.clone;
+ var result = clone ? traverse_1(obj).clone() : obj;
+
+ // diff between keys and val is order of arg in ^ tester
+ var matcher = anyKeyVal(keys, vals);
+
+ /* istanbul ignore next: debug */
+ if (debug) {
+ console.log('matcher for traverse...', keys, vals);
+ }
+
+ // bound to the traverser
+ traverse_1(result).forEach(function(key, x, traverser) {
+ if (traverser.isRoot) {
+ // nothing
+ }
+ else if (matcher(key, x)) {
+ /* istanbul ignore next: debug */
+ if (debug) {
+ console.log('------- match ------- ', key, x);
+ }
+
+ onMatch(x, traverser);
+ }
+ else if (onNonMatch) {
+ /* istanbul ignore next: debug */
+ if (debug) {
+ console.log('------- NONmatch ------- ', key, x);
+ }
+
+ onNonMatch(x, traverser);
+ }
+ });
+
+ this.set(TRAVERSED_KEY, result);
+ return _true(shouldReturn) ? result : this
+ };
+
+ /**
+ * value traversed in traverse
+ * @since 1.0.0
+ * @see TraverseChain.traverse
+ * @return {Object | Array | any} traversed
+ *
+ * @example
+ *
+ * const traverser = new Traverser()
+ * traverser.obj(['duck', 'duck', 'goose'])
+ * traverser.vals(['g**se'])
+ * traverser.traverse()
+ *
+ * traverser.traversed()
+ * //=> ['goose']
+ *
+ * @example
+ *
+ * const eh = {
+ * me: true,
+ * nested: {
+ * really: {
+ * deep: {
+ * super: false,
+ * not: 'eh',
+ * canada: true,
+ * modules: [{parser: 'hi'}],
+ * },
+ * matchme: 'minime',
+ * notme: 'eh',
+ * },
+ * },
+ * }
+ *
+ * const chain = new Chain()
+ * Object.assign(chain, eh)
+ *
+ * const traverser = chain
+ * .merge(eh)
+ * .traverse(true)
+ * .keys([/super/, /parser/, /store/, /meta/])
+ * .vals([/minime/])
+ * .call(false)
+ *
+ * traverser.traversed()
+ * //=> {
+ * className: 'DotProp',
+ * me: true,
+ * nested: {
+ * really: {
+ * deep: {
+ * not: 'eh',
+ * canada: true,
+ * modules: [{}],
+ * },
+ * notme: 'eh',
+ * },
+ * },
+ * }
+ *
+ */
+ Traverser.prototype.traversed = function traversed () {
+ return this.get(TRAVERSED_KEY)
+ };
+
+ return Traverser;
+ }(ChainedMapBase));
+
+ /* ___filename___: dist/TraverseChain.js */
+
+ /* ___filename___: dist/compose/Transform.js */
+
+
+
+
+
+
+
+
+
+
+ /**
+ * @param {Class | Composable} Target composable class
+ * @return {TransformChain} class
+ * @example
+ * compose(class {})
+ * //=> TransformChain
+ */
+ var Transform = function (Target) {
+ var set = Target.prototype.set;
+
+ /**
+ * @class TransformChain
+ * @member TransformChain
+ * @extends {ChainedMap}
+ * @memberOf compose
+ * @category Chainable
+ *
+ * @tests TransformChain
+ * @types TransformChain
+ *
+ * @symb 🤖
+ * @type {Map}
+ *
+ * @see deps/traverse
+ * @see TraverseChain
+ *
+ * {@link https://github.com/iluwatar/java-design-patterns/tree/master/state state-pattern}
+ * {@link https://github.com/iluwatar/java-design-patterns/tree/master/strategy strategy-pattern}
+ */
+ // return class Transform extends Target {
+ // -------------------------------------------
+
+ /**
+ * @desc traverse `this`, or `this.entries`
+ * @since 1.0.2
+ *
+ * @param {boolean | traversable} [useThis=false] use the instance properties that are `mapish` as well
+ * @return {TraverseChain} @chainable
+ *
+ * @see TraverseChain
+ * @see js-traverse
+ *
+ * @example
+ * TAKE FROM TRAVERSECHAIN
+ */
+ Target.prototype.traverse = function traverseChain(useThis) {
+ if ( useThis === void 0 ) useThis = false;
+
+ /* prettier-ignore */
+ return new TraverseChain(this)
+ .obj(_false(useThis)
+ ? this.entries(true)
+ : _true(useThis)
+ ? this
+ : useThis
+ )
+ };
+
+ /**
+ * @since 1.0.2
+ * @memberOf TransformChain
+ *
+ * @param {string | Function} key currently just string
+ * @param {Function} value callback accepting the value as only arg to transform with
+ * @return {TransformChain} @chainable
+ *
+ * @TODO dot-prop here
+ *
+ * @example
+ *
+ * // coerce values with .id into the value they hold
+ * chain
+ * .transform('dis', val => (typeof val === 'string' ? val : val.id))
+ *
+ * chain.set('dis', 'eh')
+ * chain.get('dis')
+ * //=> 'eh'
+ *
+ * chain.set('dis', {id: 'eh'})
+ * chain.get('dis')
+ * //=> 'eh'
+ *
+ *
+ * @example
+ *
+ * import {format} from 'date-fns/esm'
+ * import {Chain} from 'chain-able'
+ *
+ * const chain = new Chain()
+ * chain.transform('created_at', date => format(date, 'MM/DD/YYYY'))
+ * chain.set('created_at', new Date())
+ *
+ * // is formatted human-readable pretty!
+ * const {created_at} = chain.entries()
+ * //=> '02/11/2014'
+ *
+ */
+ Target.prototype.transform = function transform(key, value) {
+ return this.meta(transformers, key, value)
+ };
+
+ /**
+ * @memberOf TransformChain
+ *
+ * @override
+ * @inheritdoc
+ * @since 1.0.0
+ *
+ * @param {Primitive} key key to set with
+ * @param {any} val value to set for key
+ * @param {undefined | string | Array} dotPropKey special key used for initializing dot prop values in an optimized way to keep reference
+ * @return {Chainable} @chainable
+ *
+ * @see this.observe, this.transform
+ */
+ Target.prototype.set = function transformSet(key, val, dotPropKey) {
+ var this$1 = this;
+
+ var value = val;
+
+ // get
+ var transformers$$2 = this.meta(transformers, key);
+ for (var t = 0; t < transformers$$2.length; t++) {
+ value = transformers$$2[t].call(this$1, value, this$1);
+ }
+
+ // super.set(key, value)
+ set.call(this, key, value);
+
+ // get
+ var observers$$2 = this.meta(observers);
+
+ // skip the below if we have no observers
+ if (!observers$$2.length) {
+ return this
+ }
+
+ var data = {key: dotPropKey, value: value};
+ if (_undefined(dotPropKey)) {
+ data.key = obj(value) ? paths(key, value) : key;
+ }
+
+ for (var o = 0; o < observers$$2.length; o++) {
+ observers$$2[o](data);
+ }
+
+ return this
+ };
+
+ // @TODO
+ // // https://stackoverflow.com/questions/31158902/is-it-possible-to-sort-a-es6-map-object
+ // ordered(comperator = null) {
+ // // this.set = this.before(this.set)
+ // this.set = (key, value) => {
+ // // have to iterate over the keys before setting
+ // // and then after merging in values, update
+ // if (this.store.has(key)) {
+ // // first
+ // let keys = this.store.keys()
+ // if (isFunction(comperator)) keys = keys.sort(comperator)
+ //
+ // // after
+ // const store = this.store
+ // this.store = new Map()
+ // keys.forEach(keyInOrder => this.store.set(key, store.get(key)))
+ // store.clear()
+ // }
+ // }
+ // }
+
+ // --- remap ---
+ /**
+ * @desc remap properties from 1 to another, for example, apis with inconsistent naming
+ * @memberOf TransformChain
+ * @since 1.0.0
+ * @symb 🗺
+ *
+ * @param {string | Object} from property name string, or {[from]: to}
+ * @param {string} [to=undefined] property name to change key to
+ * @return {Chain} @chainable
+ *
+ * @see TransformChain.transform
+ * @IDEA could also be a function, but then might as well use .transform
+ *
+ * @example
+ *
+ * chain
+ * .remap('dis', 'dat')
+ * .from({dis: true})
+ *
+ * chain.entries()
+ * //=> {dat: true}
+ *
+ * @example
+ *
+ * chain
+ * .remap({dis: 'dat'})
+ * .from({dis: 1, other: true}}
+ *
+ * chain.entries()
+ * //=> {dist: 1, other: true}
+ *
+ */
+ Target.prototype.remap = function chainRemap(from, to) {
+ var this$1 = this;
+
+ var remap = obj(from) ? from : {[from]: to};
+
+ /* prettier-ignore */
+ keys(remap).forEach(function (key) { return this$1.transform(key, function (val) {
+ this$1.set(remap[key], val);
+ return val
+ }); });
+
+ return this
+ };
+
+ return Target
+ };
+
+ /* ___filename___: dist/deps/dot/has.js */
+
+
+
+
+ /**
+ * @name dot.has
+ * @memberOf dot
+ * @func
+ * @since 3.0.0
+ * @extends dot/getPathSegments
+ *
+ * @param {Object} obj the object to retrieve the nested property from.
+ * @param {Dottable | string | Array} path dot-prop-path to use
+ * @return {boolean} has at path
+ *
+ * @example
+ *
+ * dot.has({a: {b: 2}}, 'a.b'); //=> true
+ * dot.has({a: {b: 2}}, ['a', 'b']); //=> true
+ * dot.has({c: {b: 2}}, ['a', 'b']); //=> undefined
+ *
+ */
+ var has$1 = function dotHas(obj$$2, path) {
+ if (!dottable(obj$$2, path)) {
+ return false
+ }
+
+ var pathArr = segments(path);
+
+ for (var i = 0; i < pathArr.length; i++) {
+ if (obj(obj$$2)) {
+ if (!(pathArr[i] in obj$$2)) {
+ return false
+ }
+
+ obj$$2 = obj$$2[pathArr[i]];
+ }
+ else {
+ return false
+ }
+ }
+
+ return true
+ };
+
+ /* ___filename___: dist/deps/dot/delete.js */
+
+
+
+
+
+ /**
+ * @desc delete a path on an object
+ * @name dot.delete
+ * @memberOf dot
+ * @func
+ * @since 3.0.0
+ * @extends dot/getPathSegments
+ *
+ * @param {Object} obj the object to DELETE the nested property from.
+ * @param {Dottable | string | Array} path dot-prop-path to use
+ * @return {void}
+ *
+ *
+ * @example
+ *
+ * dot.get({a: {b: 2}}, 'a.b'); //=> 2
+ * dot.get({a: {b: 2}}, ['a', 'b']); //=> 2
+ * dot.get({c: {b: 2}}, ['a', 'b']); //=> undefined
+ *
+ */
+ var _delete = function dotdelete(obj$$2, path) {
+ if (!dottable(obj$$2, path)) {
+ return
+ }
+
+ var pathArr = segments(path);
+
+ for (var i = 0; i < pathArr.length; i++) {
+ var p = pathArr[i];
+
+ if (i === lengthMinusOne(pathArr)) {
+ delete obj$$2[p];
+ return
+ }
+
+ obj$$2 = obj$$2[p];
+
+ if (!obj(obj$$2)) {
+ return
+ }
+ }
+ };
+
+ /* ___filename___: dist/deps/dot/has.js */
+
+ /* ___filename___: dist/deps/dot/delete.js */
+
+ /* ___filename___: dist/deps/dot/dot-prop.js */
+ // const escape = require('./escape')
+ // const dottable = require('./dottable')
+ // const segments = require('./segments')
+ // const paths = require('. paths')
+
+
+
+
+
+ var dotProp = {
+ has: has$1,
+ get: get,
+ set: set$2,
+ delete: _delete,
+ };
+
+ /* ___filename___: dist/deps/dot/dot-prop.js */
+
+ var index$20 = dotProp;
+
+ /* ___filename___: dist/deps/is/dot.js */
+
+
+
+
+ /**
+ * @since 3.0.0
+ * @memberOf is
+ * @name isDot
+ *
+ * @TODO update with conditional
+ *
+ * @param {*} x value to check
+ * @return {boolean} x isDot
+ *
+ * @see isArray
+ * @see isString
+ * @see includes
+ *
+ * @example
+ * isDot('eh.oh') //=> true
+ * isDot('eh') //=> false
+ * isDot(['eh', 'oh']) //=> true
+ */
+ var dot = function isDot(x) {
+ return array(x) || (string(x) && x.includes('.'))
+ };
+
+ /* ___filename___: dist/deps/is/dot.js */
+
+ /* ___filename___: dist/compose/DotProp.js */
+ /**
+ * @since 2.0.0
+ */
+
+
+
+ /**
+ * @desc checks if this.meta.dot != false & isDot(key) - scoped
+ *
+ * @private
+ * @since 3.0.1
+ *
+ * @param {string} key key in .get/.has/.delete/set
+ * @param {DotProp} thisArg Chain
+ * @return {boolean} shouldDot
+ *
+ * @see DotProp.dot
+ * @see deps/is/dot
+ * @see deps/meta
+ * @see https://lodash.com/docs/#get
+ * @see https://github.com/sindresorhus/dot-prop
+ *
+ * @example
+ *
+ * const chain = new DotProp()
+ * shouldDot('me.me', chain)
+ * //=> true
+ *
+ * const chain = new DotProp()
+ * shouldDot('me', chain)
+ * //=> false
+ *
+ * const chain = new DotProp()
+ * chain.dot(false)
+ * shouldDot('me.me', chain)
+ * //=> false
+ *
+ */
+ var shouldDot = function (key, thisArg) { return thisArg.meta.dot !== false && dot(key); };
+
+ /**
+ * @class DotProp
+ * @member Observe
+ * @extends {ChainedMap}
+ * @memberOf compose
+ * @category Chainable
+ *
+ * @param {Class | Composable} Target composable class
+ * @return {DotProp} class
+ *
+ * @tests DotProp
+ * @types DotProp
+ *
+ * @see deps/dot
+ *
+ * @example
+ *
+ * const {compose} = require('chain-able')
+ * const {DotProp} = compose
+ * new DotProp()
+ * //=> DotProp
+ *
+ * @example
+ *
+ * const chain = new Chain()
+ *
+ * chain.set('moose.simple', 1)
+ * //=> Chain
+ *
+ * chain.get('moose.simple')
+ * //=>1
+ *
+ * chain.get('moose')
+ * //=> {simple: 1}
+ *
+ * chain.set('moose.canada.eh', true).set('moose.canada.igloo', true)
+ * //=> Chain
+ *
+ * //set, has, get, delete :-)
+ * chain.delete('moose.canada.eh')
+ * //=> Chain
+ *
+ * //also works with an array (moose.canada.igloo)
+ * chain.get(['moose', 'canada', 'igloo'])
+ * //=> true
+ *
+ */
+ var DotProp = function (Target) {
+ // is this any better?
+ var entries = Target.prototype.entries;
+ var set = Target.prototype.set;
+ var has = Target.prototype.has;
+ var get = Target.prototype.get;
+ var del = Target.prototype.delete;
+
+ /**
+ * @method dot
+ * @methodTarget DotProp
+ * @since 3.0.1
+ *
+ * @param {boolean} [useDot=undefined] use dot prop or not
+ * @return {DotProp} @chainable
+ *
+ * @see deps/meta
+ *
+ * @example
+ *
+ * const chain = new Target()
+ * chain.dot(false)
+ * chain.set('moose.simple', 1)
+ *
+ * toArr(chain.store.keys())
+ * //=> ['moose.simple']
+ *
+ */
+ Target.prototype.dot = function enableDisableDot(useDot) {
+ this.meta.dot = useDot;
+ return this
+ };
+
+ /**
+ * @desc since we have a map,
+ * we need to ensure the first property is available
+ * otherwise we have an empty map.entries obj
+ * which does nothing by reference
+ * @since 3.0.1
+ * @memberOf DotProp
+ *
+ * @override
+ * @inheritdoc
+ *
+ * @see TargetedMap.set
+ * @see .dot
+ *
+ * @example
+ * const chain = new Target()
+ *
+ * chain.set('moose.simple', 1)
+ * //=> Target store:Map: { moose: { simple: 1 } }
+ */
+ Target.prototype.set = function dotSet(key, val) {
+ if (shouldDot(key, this)) {
+ // first accessor
+ // @example: `canada` in `canada.eh`
+ var prop = key.split('.').shift();
+
+ // we already know it is .dot, call super instead
+ // if (!super.has(prop)) super.set(prop, {})
+
+ // spread
+ var data = entries.call(this);
+
+ // set on the spread data
+ index$20.set(data, key, val);
+
+ // is already by ref, but be extra safe, + observables
+ return set.call(this, prop, data[prop], key)
+ }
+ return set.call(this, key, val)
+ };
+
+ /**
+ * @desc dot-prop enabled get
+ * @method get
+ * @memberOf DotProp
+ *
+ * @since 3.0.1
+ * @override
+ * @inheritdoc
+ *
+ * @param {Primitive} key dot prop key, or any primitive key
+ * @param {any} [fallback=undefined] fallback value, if it cannot find value with key path
+ * @return {any} value for path, or fallback value if provided
+ *
+ * @see ChainedMap.get
+ * @see deps/dot
+ * @see deps/is/dot
+ *
+ * @TODO dot-prop on non-store instance.property when using nested chains...
+ *
+ * @example
+ *
+ * chain.set('moose.simple', 1)
+ * //=> Chain
+ *
+ * chain.get('moose.simple')
+ * //=>1
+ *
+ * chain.get('moose')
+ * //=> {simple: 1}
+ *
+ * @example
+ *
+ * //also works with an array (moose.simple)
+ * chain.get(['moose', 'simple'])
+ * //=> 1
+ *
+ */
+ Target.prototype.get = function dotGet(key, fallback) {
+ return shouldDot(key, this)
+ ? index$20.get(entries.call(this), key, fallback)
+ : get.call(this, key)
+ };
+
+ /**
+ * @method has
+ * @methodOf DotProp
+ * @since 3.0.1
+ * @override
+ * @inheritdoc
+ *
+ * @see deps/dot
+ * @see deps/is/dot
+ *
+ * @example
+ *
+ * chain.set('one.two', 3)
+ * chain.has('one.two')
+ * //=> true
+ *
+ */
+ Target.prototype.has = function dotHas(key) {
+ return shouldDot(key, this)
+ ? index$20.has(entries.call(this), key)
+ : has.call(this, key)
+ };
+
+ /**
+ * @method delete
+ * @methodOf DotProp
+ * @since 3.0.1
+ *
+ * @override
+ * @inheritdoc
+ * @see deps/dot
+ * @see deps/is/dot
+ *
+ * @example
+ *
+ * chain.set('moose.canada.eh', true)
+ * chain.set('moose.canada.igloo', true)
+ * //=> Chain
+ *
+ * chain.delete('moose.canada.eh')
+ * //=> Chain
+ *
+ * chain.has('moose.canada.eh')
+ * //=> true
+ *
+ * //still has moose.canada.igloo
+ * chain.has('moose.canada')
+ * //=> true
+ *
+ */
+ Target.prototype.delete = function dotDelete(key) {
+ return shouldDot(key, this)
+ ? index$20.delete(entries.call(this), key)
+ : del.call(this, key)
+ };
+
+ return Target
+ };
+
+ /* ___filename___: dist/compose/Observe.js */
+
+ /* ___filename___: dist/compose/Shorthands.js */
+
+ /* ___filename___: dist/compose/Transform.js */
+
+ /* ___filename___: dist/compose/DotProp.js */
+
+ /* ___filename___: dist/compose/compose.js */
+
+
+
+
+
+
+
+
+ var ComposableExtensions = [Observe, Shorthands, Transform, DotProp];
+
+ /**
+ * @desc compose chains all the way up from Chainable
+ * @since 3.0.0
+ *
+ * @param {Class | Function | undefined} [target=ChainedMap] class or function to extend
+ * @param {Array | undefined} [extensions=[Observe, Shorthands, Transform, DotProp]] Array of extensions to compose together left to right
+ * @return {Class | Function} composed
+ *
+ * @tutorial examples/playground/compose
+ * @tutorial examples/babel/decorators
+ *
+ * @name compose
+ * @func compose
+ * @member compose
+ * @tests compose
+ * @types compose
+ * @symb 🎼
+ *
+ * @see https://formidable.com/blog/2017/infinite-state-composition-with-freactal/
+ * @see https://blog.javascripting.com/2016/02/02/encapsulation-in-redux/
+ * @see https://www.barbarianmeetscoding.com/blog/2016/01/04/safer-javascript-object-composition-with-traits-and-traits-dot-js/
+ * @see https://medium.com/javascript-scene/why-learn-functional-programming-in-javascript-composing-software-ea13afc7a257
+ * @see https://hackernoon.com/javascript-functional-composition-for-every-day-use-22421ef65a10
+ * @see https://github.com/stoeffel/awesome-fp-js
+ *
+ * @example
+ *
+ * class Eh extends compose() {}
+ * new Eh() instanceof Chainable
+ * //=> true
+ *
+ * @example
+ *
+ * class Target {}
+ * class Eh extends compose(Target) {}
+ * new Eh() instanceof Target
+ * //=> true
+ *
+ * @example
+ *
+ * class Target {}
+ * const mixin = SuperClass => class extends SuperClass {}
+ * class Eh extends compose(Target, ) {}
+ * new Eh() instanceof Chainable
+ * //=> true
+ *
+ * @example
+ *
+ * class Winning {}
+ * class Yes extends compose(Winning) {
+ * get winning() {
+ * return true
+ * }
+ * }
+ * const yes = new Yes()
+ * yes instanceof Winning && yes.winning
+ * //=> true
+ *
+ */
+ function compose(target, extensions) {
+ var extend = _undefined(extensions) ? ComposableExtensions : extensions;
+ var composed = target;
+
+ if (target && target instanceof Object) {
+ composed = ChainedMap.compose(Chainable.compose(target));
+ }
+ else {
+ composed = ChainedMap;
+ }
+
+ for (var index = 0; index < extend.length; index++) {
+ composed = extend[index](composed) || composed || ChainedMap;
+ }
+
+ return composed
+ }
+
+ compose.Observe = Observe;
+ compose.Shorthands = Shorthands;
+ compose.Transform = Transform;
+ compose.DotProp = DotProp;
+
+ var compose_1 = compose;
+
+ /* ___filename___: dist/compose/compose.js */
+
+ var index$16 = compose_1;
+
+ /* ___filename___: dist/deps/fp/mapWhere.js */
+
+
+
+
+ /**
+ * Creates an array of values by running each property of `object` thru
+ * `iteratee`. The iteratee is invoked with three arguments: (value, key, object).
+ *
+ * @memberOf fp
+ * @since 5.0.0
+ * @category Object
+ *
+ * @param {Object} obj The object to iterate over.
+ * @param {Function} predicate The function invoked per iteration.
+ * @return {Array} Returns the new mapped array.
+ *
+ * @see https://github.com/lodash/lodash/blob/master/map.js
+ *
+ * @example
+ *
+ * const square = n => n * n
+ * map({ 'a': 4, 'b': 8 }, square)
+ * // => [16, 64] (iteration order is not guaranteed)
+ *
+ */
+ function mapWhere(obj, predicate) {
+ var output = {};
+ var isArrayObj = array(obj);
+ var keys = keysObjOrArray(obj);
+
+ for (var index = 0; index < keys.length; index++) {
+ var key = isArrayObj ? index : keys[index];
+ var value = obj[key];
+
+ if (predicate(value, key, obj)) {
+ output[key] = value;
+ }
+ }
+
+ return output
+ }
+
+ var mapWhere_1 = curry(2, mapWhere);
+
+ /* ___filename___: dist/deps/reduce/toObj.js */
+ var toObj = function reduceObj(array, iterator) {
+ return array.reduce(function(reduced, next) {
+ iterator(reduced, next);
+ return reduced
+ }, {})
+ };
+
+ /* ___filename___: dist/deps/fp/mapWhere.js */
+
+ /* ___filename___: dist/deps/reduce/toObj.js */
+
+ /* ___filename___: dist/deps/reduce/clean.js */
+
+
+
+
+
+
+ // const [isNotReal, isNotEmpty] = [isReal, isEmpty].map(not)
+ // const isNotEmptyOrNotReal = or(isNotReal, isNotEmpty)
+ var mapNotEmpty = mapWhere_1('_', function (x) { return real(x) && !empty(x); });
+
+ /**
+ * @desc goes through the maps,
+ * and the map values,
+ * reduces them to array
+ * then to an object using the reduced values
+ *
+ * @memberOf reduce
+ * @since 4.0.0 <- moved as a dep function
+ * @since 0.4.0
+ *
+ * @param {Object} obj object to clean, usually .entries()
+ * @return {Object} reduced object, without `notReal` values
+ *
+ * @TODO seems to be overkill with reducing mapping just copy & ignore or delete?
+ *
+ * @see reduce
+ * @see isObjWithKeys
+ * @see isNotEmptyArray
+ * @see isReal
+ * @see http://underscorejs.org/#reduce
+ *
+ * @example
+ *
+ * const map = new ChainedMap()
+ *
+ * map
+ * .set('emptyArr', [])
+ * .set('arr', [1])
+ * .set('nill', null)
+ * .set('emptyObj', {})
+ * .set('obj', {keys: true})
+ *
+ * clean(map.entries())
+ * //=> {arr: [1], obj: {keys: true}}
+ *
+ */
+ var clean = function clean(obj) {
+ var mapped = mapNotEmpty(obj);
+ var keys$$2 = keys(mapped);
+ var iterator = function (reduced, key) { return (reduced[key] = mapped[key]); };
+
+ return toObj(keys$$2, iterator)
+ };
+
+ /* ___filename___: dist/deps/traversers/eq.js */
+
+
+ var eq$2 = traverse_1.eq;
+
+ var index$22 = validatorBuilder;
+
+ /* ___filename___: dist/ChainedSet.js */
+
+ /* ___filename___: dist/FactoryChain.js */
+
+ /* ___filename___: dist/deps/reduce/clean.js */
+
+ /* ___filename___: dist/deps/traversers/eq.js */
+
+ var index = createCommonjsModule(function (module) {
+ // dep
+
+ // core
+
+
+
+ // merge
+
+
+
+ // easy
+
+
+ // composer
+
+
+
+ // export
+ var exp = index$16();
+ exp.chainable = construct(1, exp);
+ exp.builder = construct(1, MethodChain_1);
+ exp.Chain = exp;
+ exp.compose = index$16;
+
+ // deps
+ exp.traverse = traverse_1;
+ exp.addMethodFactories = MethodChain_1.add;
+
+ exp.toArr = toArr; // exp.toarr =
+ exp.camelCase = camelCase;
+ exp.dot = index$20;
+ exp.matcher = index$18;
+ exp.reduce = index$4;
+ exp.clean = clean;
+ exp.meta = index$6;
+ exp.eq = eq$2;
+ exp.types = index$22;
+ exp.encase = index$14;
+ exp.curry = curry;
+ exp.replace = replace;
+
+ exp.addTypes = exp.types.addTypes;
+
+ // core
+ exp.Chainable = Chainable;
+ exp.ChainedSet = ChainedSet_1;
+ exp.ChainedMap = ChainedMap;
+ exp.FactoryChain = FactoryChain_1;
+ exp.MethodChain = MethodChain_1;
+
+ // merge
+ exp.MergeChain = MergeChain_1;
+ exp.merge = index$2;
+
+ exp.is = index$12;
+
+ assign(exp, exp.is);
+
+ // @NOTE: no need for exporting as an __esModule,
+ // it adds additional checking wrapper
+ module.exports = exp;
+
+
+ });
+
+ var index$1 = unwrapExports(index);
+
+ return index$1;
+
+})));
+//# sourceMappingURL=index.js.map
diff --git a/dists/dev/index.js b/dists/dev/index.js
new file mode 100644
index 0000000..4f0e4ed
--- /dev/null
+++ b/dists/dev/index.js
@@ -0,0 +1,10130 @@
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+ typeof define === 'function' && define.amd ? define(factory) :
+ (global.ChainAble = factory());
+}(this, (function () { 'use strict';
+
+ function unwrapExports (x) {
+ return x && x.__esModule ? x['default'] : x;
+ }
+
+ function createCommonjsModule(fn, module) {
+ return module = { exports: {} }, fn(module, module.exports), module.exports;
+ }
+
+ /* ___filename___: dist/deps/util/assign.js */
+ var assign = Object.assign;
+
+ /* ___filename___: dist/deps/is/undefined.js */
+ /**
+ * @desc Checks if `value` is `undefined`.
+ * @category Lang
+ *
+ * @param {*} x value
+ * @return {boolean} isUndefined
+ *
+ * @since 4.0.0-alpha.1
+ * @memberOf is
+ * @func isUndefined
+ *
+ * @see is/nullOrUndefined
+ * @see https://github.com/infernojs/inferno/blob/master/packages/inferno-shared/src/index.ts#L57
+ *
+ * @NOTE || typeof x === 'undefined'
+ *
+ * @example
+ *
+ * isUndefined(undefined)
+ * //=> true
+ * isUndefined(void 0)
+ * //=> true
+ *
+ * isUndefined(null)
+ * //=> false
+ * isUndefined(NaN)
+ * //=> false
+ * isUndefined({})
+ * //=> false
+ * isUndefined('')
+ * //=> false
+ * isUndefined(1)
+ * //=> false
+ * isUndefined(false)
+ * //=> false
+ *
+ */
+ var _undefined = function (x) { return x === undefined; };
+
+ /* ___filename___: dist/deps/symbols/iterator.js */
+ var iterator = Symbol.iterator;
+
+ // typeof Symbol !== 'undefined'
+ // ? Symbol.iterator
+ // : '@@iterator'
+
+ /* ___filename___: dist/deps/symbols/instance.js */
+ var instance = Symbol.hasInstance;
+
+ /* ___filename___: dist/deps/symbols/primitive.js */
+ var primitive = Symbol.toPrimitive;
+
+ /* ___filename___: dist/deps/is/prototypeOf.js */
+ var prototypeOf = function (obj, comparator) { return Object.prototype.isPrototypeOf.call(obj, comparator); };
+
+ /* ___filename___: dist/deps/is/toS.js */
+ /**
+ * The base implementation of `getTag` without fallbacks for buggy environments.
+ *
+ * @memberOf is
+ * @since 3.0.0
+ *
+ * @param {*} obj The value to `Object.prototype.toString.call(obj)`.
+ * @return {string} Returns the `toStringTag`.
+ *
+ * @see https://github.com/lodash/lodash/blob/master/.internal/baseGetTag.js
+ * @see https://github.com/jonschlinkert/kind-of
+ * @see https://github.com/substack/js-traverse/blob/master/index.js#L285
+ * @see http://luxiyalu.com/object-prototype-tostring-call/
+ *
+ * @TODO obj[Symbol.toStringTag]
+ *
+ * @example
+ *
+ * toS({})
+ * //=> '[Object object]'
+ *
+ * toS(function() {})
+ * //=> '[Object function]'
+ *
+ */
+ var toS = function (obj) { return Object.prototype.toString.call(obj); };
+
+ /* ___filename___: dist/deps/is/toS.js */
+
+ /* ___filename___: dist/deps/is/map.js */
+
+
+ /**
+ * @desc Checks if `value` is classified as a `Map` object.
+ * @param {*} x value
+ * @return {boolean} isMap
+ *
+ * @since 3.0.0
+ * @memberOf is
+ * @func isMap
+ * @see https://github.com/jonschlinkert/kind-of
+ *
+ * @example
+ *
+ * isMap(new Map())
+ * //=> true
+ * isMap(new Map.entries())
+ * //=> false
+ * isMap(new Set())
+ * //=> false
+ * isMap({})
+ * //=> false
+ * isMap('')
+ * //=> false
+ * isMap(1)
+ * //=> false
+ * isMap(new WeakMap)
+ * // => false
+ *
+ * @example
+ *
+ * const e = {}
+ * eh[Symbol.toStringTag] = '[object Map]'
+ * isMap(eh)
+ *
+ * @example
+ *
+ * class Eh extends Map()
+ * isMap(new Eh())
+ * //=> true
+ *
+ */
+ var map = function isMap(x) {
+ // return x instanceof Map ||
+ return toS(x) === '[object Map]'
+ };
+
+ /* ___filename___: dist/deps/is/set.js */
+
+
+ /**
+ * Checks if `value` is classified as a `Set` object.
+ *
+ * @since 4.3.0
+ * @category Lang
+ * @param {*} x The value to check.
+ * @return {boolean} Returns `true` if `value` is a set, else `false`.
+ *
+ * @example
+ *
+ * isSet(new Set)
+ * // => true
+ *
+ * isSet(new WeakSet)
+ * // => false
+ *
+ */
+ var set = function isSet(x) {
+ return x instanceof Set || toS(x) === '[object Set]'
+ // return toS(x) === '[object Set]'
+ };
+ // x instanceof Set ||
+
+ /* ___filename___: dist/deps/is/function.js */
+ /**
+ * Checks if `value` is classified as a `Function` object.
+ * @category Lang
+ *
+ * @param {*} x The value to check.
+ * @return {boolean} x isFunction
+ *
+ * @since 3.0.0
+ * @memberOf is
+ * @func isFunction
+ *
+ * @NOTE || x instanceof Function
+ *
+ * @polyfill safari=9
+ * The use of `Object#toString` avoids issues with the `typeof` operator
+ * in Safari 9 which returns 'object' for typed arrays and other constructors.
+ * there is no polyfill for this
+ * https://github.com/krambuhl/custom-event-polyfill/issues/2
+ * browser usage is < 0.3%, very edge case
+ *
+ * @example
+ *
+ * isFunction(function() {})
+ * //=> true
+ * isFunction(() => {})
+ * //=> true
+ * isFunction(new Function())
+ * //=> true
+ *
+ * isFunction(1)
+ * //=> false
+ * isFunction('')
+ * //=> false
+ * isFunction(/abc/)
+ * // => false
+ */
+ var _function = function isFunction(x) {
+ return typeof x === 'function'
+ };
+
+ /* ___filename___: dist/deps/is/stringPrimitive.js */
+
+
+ /**
+ * Checks if `value` is classified as a `String` **primitive**.
+ *
+ * @since 3.0.0
+ * @category Lang
+ * @memberOf is
+ * @param {*} x The value to check.
+ * @returns {boolean} Returns `true` if `value` is a string, else `false`.
+ *
+ * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String
+ * @see https://github.com/lodash/lodash/blob/master/isString.js
+ * @see is/string
+ *
+ * @example
+ *
+ * isString('abc')
+ * // => true
+ *
+ * isString(new String('abc'))
+ * // => false
+ *
+ * isString(1)
+ * // => false
+ */
+ var stringPrimitive = function (x) { return typeof x === 'string'; };
+
+ /* ___filename___: dist/deps/is/stringPrimitive.js */
+
+ /* ___filename___: dist/deps/is/string.js */
+
+
+
+ /**
+ * Checks if `value` is classified as a `String` primitive or object.
+ *
+ * @since 3.0.0
+ * @category Lang
+ *
+ * @memberOf is
+ * @extends isStringPrimitive
+ * @variation also allows String objects
+ *
+ * @param {*} x The value to check.
+ * @return {boolean} Returns `true` if `value` is a string, else `false`.
+ *
+ * @see https://github.com/lodash/lodash/blob/master/isString.js
+ * @see isStringPrimitive
+ *
+ * @example
+ *
+ * isString('abc')
+ * // => true
+ *
+ * isString(new String('abc'))
+ * // => true
+ *
+ * isString(1)
+ * // => false
+ */
+ var string = function (x) { return stringPrimitive(x) || toS(x) === '[object String]'; };
+
+ /* ___filename___: dist/deps/is/false.js */
+ /**
+ * @param {*} x value
+ * @return {boolean} isFalse
+ *
+ * @since 4.0.0-alpha.1
+ * @memberOf is
+ * @func isFalse
+ *
+ * @example
+ *
+ * isFalse(false)
+ * //=> true
+ * isFalse(true)
+ * //=> false
+ * isFalse(0)
+ * //=> false
+ * isFalse('')
+ * //=> false
+ *
+ */
+ var _false = function isFalse(x) {
+ return x === false
+ };
+
+ /* ___filename___: dist/deps/util/noop.js */
+ /**
+ * @name noop
+ *
+ * @func
+ * @since 5.0.0
+ * @return {void}
+ *
+ * {@link https://github.com/sindresorhus/noop3 noop3}
+ * @see {@link noop3}
+ *
+ * @example
+ *
+ * noop
+ *
+ * @example
+ *
+ * noop()
+ *
+ */
+ var noop = function noop() { /* noop */ };
+
+ /* ___filename___: dist/deps/util/keys.js */
+ var keys = Object.keys;
+ // function keys(obj) {
+ // var res = []
+ // for (var key in obj)
+ // { res.push(key) }
+ // return res
+
+ /* ___filename___: dist/deps/util/assign.js */
+
+ /* ___filename___: dist/deps/define.js */
+
+
+ /**
+ * @desc default to configurable and enumerable, unless configured otherwise
+ * @since 4.0.0
+ *
+ * @param {Object} obj object to define on
+ * @param {Primitive} name property name to define
+ * @param {Object} descriptor object descriptor
+ * @return {void}
+ *
+ * @tutorial https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty
+ *
+ * @example
+ *
+ * var desc = Object.getOwnPropertyDescriptor(obj, 'eh', {get: () => console.log('eh')})
+ *
+ */
+ var define = function(obj, name, descriptor) {
+ Object.defineProperty(
+ obj,
+ name,
+ assign(
+ {
+ configurable: true,
+ enumerable: true,
+ },
+ descriptor
+ )
+ );
+ };
+
+ /* ___filename___: dist/deps/ignored.js */
+ var ignored = function (key) { return key === 'parent' || key === 'store' || key === 'meta' || key === 'className'; };
+
+ // key === 'decorated' ||
+ // key === 'transformers' ||
+ // key === 'inspect' ||
+
+ /* ___filename___: dist/deps/env/dev.js */
+ /* istanbul ignore next: wip build */
+ var dev = process.env.NODE_ENV !== 'production';
+
+ /* ___filename___: dist/deps/symbols/iterator.js */
+
+ /* ___filename___: dist/deps/symbols/instance.js */
+
+ /* ___filename___: dist/deps/symbols/primitive.js */
+
+ /* ___filename___: dist/deps/is/prototypeOf.js */
+
+ /* ___filename___: dist/deps/is/map.js */
+
+ /* ___filename___: dist/deps/is/set.js */
+
+ /* ___filename___: dist/deps/is/undefined.js */
+
+ /* ___filename___: dist/deps/is/function.js */
+
+ /* ___filename___: dist/deps/is/string.js */
+
+ /* ___filename___: dist/deps/is/false.js */
+
+ /* ___filename___: dist/deps/util/noop.js */
+
+ /* ___filename___: dist/deps/util/keys.js */
+
+ /* ___filename___: dist/deps/define.js */
+
+ /* ___filename___: dist/deps/ignored.js */
+
+ /* ___filename___: dist/deps/env/dev.js */
+
+ /* ___filename___: dist/Chainable.js */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ // @TODO change from `||` to if else
+ var shouldClear = function (key, property) { return !ignored(key) &&
+ (map(property) || set(property) || (property && property.store)); };
+
+ var ComposeChainable = function (Target) {
+ /* istanbul ignore next: dev */
+ if (dev) {
+ if (!Target || !Target.prototype) {
+ console.log({Target: Target});
+ throw new TypeError('did not have a super class / target base')
+ }
+ }
+
+ /**
+ * @desc Trait class that can inherit any class passed into compose, extended by ChainedMap & ChainedSet
+ *
+ * @member Chainable
+ * @class Chainable
+ * @category Chainable
+ * @type {Chainable}
+ *
+ * @prop {Chainable | any} parent
+ * @prop {string} className
+ *
+ * {@link https://github.com/iluwatar/java-design-patterns/tree/master/chain chain-pattern}
+ * @see {@link chain-pattern}
+ *
+ * @see ChainedMap
+ * @see ChainedSet
+ *
+ * @tests Chainable
+ * @types Chainable
+ */
+ var Chainable = (function (Target) {
+ function Chainable(parent) {
+ Target.call(this);
+ if (parent) { this.parent = parent; }
+ this.className = this.constructor.name;
+ }
+
+ if ( Target ) Chainable.__proto__ = Target;
+ Chainable.prototype = Object.create( Target && Target.prototype );
+ Chainable.prototype.constructor = Chainable;
+
+ /**
+ * @desc Iterator for looping values in the store
+ *
+ * @memberOf Chainable
+ * @since 0.5.0
+ *
+ * @type {generator}
+ * @return {Object} {value: undefined | any, done: true | false}
+ *
+ * @NOTE assigned to a variable so buble ignores it
+ *
+ *
+ * @see https://github.com/sindresorhus/quick-lru/blob/master/index.js
+ * @see https://stackoverflow.com/questions/36976832/what-is-the-meaning-of-symbol-iterator-in-this-context
+ * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/iterator
+ * @see this.store
+ * @tests iteration
+ *
+ * @example
+ *
+ * const chain = new Chain().set('eh', 1)
+ * for (var [key, val] of chain) console.log({[key]: val})
+ * //=> {eh: 1}
+ *
+ * @example
+ *
+ * *[Symbol.iterator](): void { for (const item of this.store) yield item }
+ *
+ * @example
+ *
+ * const {ChainedSet} = require('chain-able')
+ * const set = new ChainedSet()
+ * set.add('eh')
+ *
+ * for (const arr of set) {
+ * const [key, val] = arr
+ *
+ * key
+ * //=> 0
+ *
+ * val
+ * //=> 'eh'
+ *
+ * arr.length
+ * //=> 2
+ * }
+ *
+ */
+ Chainable.prototype[iterator] = function () {
+ var values = this.values();
+ var size = this.store.size;
+ var entries = this.entries ? this.entries() : 0;
+ var keys$$1 = entries === 0 ? new Array(size) : keys(entries);
+
+ return {
+ i: 0,
+ next: function next() {
+ var i = this.i;
+ var key = i;
+ var val = values[i];
+ if (entries) { key = keys$$1[i]; }
+
+ // done - no more values, or iteration reached size
+ if ((_undefined(key) && _undefined(val)) || size <= i) {
+ return {value: undefined, done: true}
+ }
+
+ this.i++;
+
+ // return
+ return {value: [key, val], done: false}
+ },
+ }
+ };
+
+ /**
+ * @desc for ending nested chains
+ * @since 0.4.0
+ * @memberOf Chainable
+ *
+ * @return {Chainable | any}
+ *
+ * @see Chainable.parent
+ * @see FactoryChain
+ *
+ * @example
+ *
+ * const parent = 'eh'
+ * const child = newChain(parent)
+ * child.end()
+ * //=> 'eh'
+ *
+ */
+ Chainable.prototype.end = function end () {
+ return this.parent
+ };
+
+ /**
+ * @desc when the condition is true,
+ * trueBrancher is called,
+ * else, falseBrancher is called
+ *
+ * @memberOf Chainable
+ * @since 4.0.0 <- added string-as-has(condition)
+ * @since 2.0.0
+ *
+ * @param {boolean | string} condition when string, checks this.get
+ * @param {Function} [trueBrancher=Function] called when true
+ * @param {Function} [falseBrancher=Function] called when false
+ * @return {Chainable} @chainable
+ *
+ * @example
+ *
+ *
+ * const prod = process.env.NODE_ENV === 'production'
+ * chains.when(prod, c => c.set('prod', true), c => c.set('prod', false))
+ *
+ *
+ */
+ Chainable.prototype.when = function when (condition, trueBrancher, falseBrancher) {
+ if (condition) {
+ if (_function(trueBrancher)) {
+ if (string(condition)) {
+ if (this.get(condition)) {
+ trueBrancher(this);
+ }
+ }
+ else {
+ trueBrancher(this);
+ }
+ }
+ }
+ else if (_function(falseBrancher)) {
+ falseBrancher(this);
+ }
+
+ return this
+ };
+
+ /**
+ * @desc clears the map,
+ * goes through this properties,
+ * calls .clear if they are instanceof Chainable or Map
+ *
+ * @memberOf Chainable
+ * @since 4.0.0 (moved only to Chainable, added option to clear this keys)
+ * @since 0.4.0 (in ChainedMap)
+ * @since 0.3.0 (in Chainable)
+ *
+ * @param {boolean | undefined} [clearPropertiesThatAreChainLike=true] checks properties on the object, if they are `chain-like`, clears them as well
+ * @return {Chainable} @chainable
+ *
+ * @see https://github.com/fliphub/flipchain/issues/2
+ * @see ChainedSet
+ * @see ChainedMap
+ *
+ * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/clear map-clear}
+ * @see {@link map-clear}
+ *
+ * @example
+ *
+ * const chain = new Chain()
+ * chain.set('eh', 1)
+ * chain.entries()
+ * //=> {eh: 1}
+ * chain.clear()
+ * chain.entries()
+ * //=> {}
+ *
+ */
+ Chainable.prototype.clear = function clear (clearPropertiesThatAreChainLike) {
+ var this$1 = this;
+
+ this.store.clear();
+
+ if (_false(clearPropertiesThatAreChainLike)) { return this }
+
+ var keys$$1 = keys(this);
+ for (var k = 0; k < keys$$1.length; k++) {
+ var key = keys$$1[k];
+ var property = this$1[key];
+ if (shouldClear(key, property)) { this$1[key].clear(); }
+ }
+
+ return this
+ };
+
+ /**
+ * @desc calls .delete on this.store.map
+ * @since 0.3.0
+ * @memberOf Chainable
+ *
+ * @param {Primitive} key on a Map: key referencing the value. on a Set: the index
+ * @return {Chainable}
+ *
+ * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/has
+ * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/has
+ * @see ChainedSet
+ * @see ChainedMap
+ *
+ * @example
+ *
+ * const chain = new Chain()
+ * chain.set('eh', 1)
+ * chain.get('eh')
+ * // => 1
+ * chain.delete('eh', 1)
+ * chain.get('eh')
+ * // => undefined
+ *
+ */
+ Chainable.prototype.delete = function delete$1 (key) {
+ this.store.delete(key);
+ return this
+ };
+
+ /**
+ * @desc checks whether the store has a value for a given key
+ * @memberOf Chainable
+ * @since 0.3.0
+ *
+ * @param {any} keyOrValue key when Map, value when Set
+ * @return {boolean}
+ *
+ * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/has map-has}
+ * @see {@link map-has}
+ *
+ * @example
+ *
+ * const chain = new Chain()
+ * chain.set('eh', 1).has('eh')
+ * //=> true
+ * chain.has('canada')
+ * //=> false
+ *
+ */
+ Chainable.prototype.has = function has (keyOrValue) {
+ return this.store.has(keyOrValue)
+ };
+
+ /**
+ * @desc spreads the entries from ChainedMap.store.values
+ * allocates a new array, adds the values from the iterator
+ *
+ * @memberOf Chainable
+ * @since 0.4.0
+ *
+ * @return {Array} toArr(this.store.values())
+ *
+ * @NOTE look at Chainable.constructor to ensure not to use `new Array...`
+ * @NOTE moved from ChainedMap and ChainedSet to Chainable @2.0.2
+ * @NOTE this was [...] & Array.from(this.store.values())
+ *
+ * {@link https://kangax.github.io/compat-table/es6/#test-Array_static_methods compat-array-static-methods}
+ * {@link https://stackoverflow.com/questions/20069828/how-to-convert-set-to-array set-to-array}
+ * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/values mozilla-map-values}
+ * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/values mozilla-set-values}
+ *
+ * @see {@link mozilla-map-values}
+ * @see {@link mozilla-set-values}
+ * @see {@link compat-array-static-methods}
+ * @see {@link set-to-array}
+ *
+ *
+ * @example
+ *
+ * const chain = new Chain()
+ * chain.set('eh', 1)
+ * chain.values()
+ * //=> [1]
+ *
+ */
+ Chainable.prototype.values = function values () {
+ var allocated = new Array(this.store.size);
+ var i = 0;
+ this.store.forEach(function (v) { return (allocated[i++] = v); });
+ return allocated
+ };
+
+ /**
+ * @desc symbol method for toString, toJSON, toNumber
+ * @memberOf Chainable
+ * @since 1.0.2
+ * @version 2
+ *
+ * @param {string} hint enum[default, string, number]
+ * @return {Primitive}
+ *
+ * {@link http://2ality.com/2015/09/well-known-symbols-es6.html#default-tostring-tags well-known-symbols-es6}
+ * @see {@link well-known-symbols-es6}
+ *
+ * @example
+ *
+ * const chain = new Chain()
+ * chain.toNumber = () => 1
+ * +chain;
+ * //=> 1
+ * chain + 1
+ * //=>
+ *
+ * @example
+ *
+ * const chain = new Chain()
+ * chain.toString = () => 'eh'
+ * chain + ''
+ * //=> 'eh'
+ *
+ */
+ Chainable.prototype[primitive] = function (hint) {
+ /* prettier-ignore */
+ /**
+ * hint === 'number'
+ * `s`tring is 115
+ * `n`umber is 110
+ * 110 & 4 = 1
+ * 115 & 4 = 0
+ *
+ * if (hint === 'string' && this.toJSON) return this.toJSON()
+ * else if (hint === 'number' && this.toNumber) return this.toNumber()
+ */
+ if (hint === 'number' && this.toNumber) { return this.toNumber() }
+
+ // hint === 'string'
+ if (this.toJSON) { return this.toJSON() }
+
+ // hint === 'default'
+ return this.toString()
+ };
+
+ return Chainable;
+ }(Target));
+
+ var ChainPrototype = Chainable.prototype;
+
+ /**
+ * @memberOf Chainable
+ * @name length
+ * @method length
+ * @readonly
+ * @since 0.5.0
+ * @see ChainedMap.store
+ * @return {number}
+ * @example for (var i = 0; i < chain.length; i++)
+ */
+ define(ChainPrototype, 'length', {
+ enumerable: false,
+ get: function get() {
+ return this.store.size
+ },
+ });
+ define(ChainPrototype, instance, {
+ enumerable: false,
+ value: function (instance$$1) { return instance$$1 && (prototypeOf(ChainPrototype, instance$$1) || instance$$1.store); },
+ });
+
+ return Chainable
+ };
+
+ // class {}
+ var c = ComposeChainable(noop);
+
+ /**
+ * @since 3.0.0
+ * @func
+ * @example
+ *
+ * class Target {}
+ * const TargetChain = Chainable.compose(Target)
+ * const chain = new TargetChain()
+ * chain instanceof Target
+ * //=> true
+ *
+ */
+ c.compose = ComposeChainable;
+
+ var Chainable = c;
+
+ /* ___filename___: dist/deps/is/objTypeof.js */
+ /**
+ * @param {*} x value
+ * @return {boolean} isObjLoose
+ *
+ * @since 3.0.0
+ * @memberOf is
+ * @func isObjLoose
+ * @see is/obj
+ * @see is/objWithKeys
+ * @see is/objStrict
+ * @see is/null
+ *
+ * @example
+ *
+ * isObjLoose(new Object())
+ * //=> true
+ * isObjLoose({})
+ * //=> true
+ * isObjLoose(Object.create(null))
+ * //=> true
+ * isObjLoose(null)
+ * //=> true
+ *
+ * isObjLoose(new Set())
+ * //=> false
+ * isObjLoose(function() {})
+ * //=> false
+ * isObjLoose('')
+ * //=> false
+ * isObjLoose(1)
+ * //=> false
+ *
+ */
+ var objTypeof = function (x) { return typeof x === 'object'; };
+
+ /* ___filename___: dist/deps/is/null.js */
+ /**
+ * @param {*} x value
+ * @return {boolean} isNull
+ *
+ * @since 3.0.0
+ * @memberOf is
+ * @func isNull
+ *
+ * @example
+ *
+ * isNull(null)
+ * //=> true
+ *
+ * isNull(undefined)
+ * //=> false
+ * isNull(void 0)
+ * //=> false
+ * isNull({})
+ * //=> false
+ * isNull('')
+ * //=> false
+ * isNull(1)
+ * //=> false
+ *
+ */
+ var _null = function (x) { return x === null; };
+
+ /* ___filename___: dist/deps/is/null.js */
+
+ /* ___filename___: dist/deps/is/nullOrUndefined.js */
+
+
+
+ /**
+ * @desc Checks if `value` is `null` or `undefined`.
+ * @alias isNil
+ * @category Lang
+ *
+ * @param {*} x value
+ * @return {boolean} isNullOrUndefined
+ *
+ * @since 4.0.0-alpha.1
+ * @memberOf is
+ * @func isNullOrUndefined
+ *
+ * @see is/null
+ * @see is/undefined
+ * @see https://github.com/infernojs/inferno/blob/master/packages/inferno-shared/src/index.ts#L23
+ *
+ * @example
+ *
+ * isNullOrUndefined(null)
+ * //=> true
+ * isNullOrUndefined(undefined)
+ * //=> true
+ * isNullOrUndefined(void 0)
+ * //=> true
+ *
+ * isNullOrUndefined(NaN)
+ * //=> false
+ * isNullOrUndefined({})
+ * //=> false
+ * isNullOrUndefined('')
+ * //=> false
+ * isNullOrUndefined(1)
+ * //=> false
+ * isNullOrUndefined(false)
+ * //=> false
+ *
+ */
+ var nullOrUndefined = function isNullOrUndef(x) {
+ return _undefined(x) || _null(x)
+ };
+
+ /* ___filename___: dist/deps/is/objTypeof.js */
+
+ /* ___filename___: dist/deps/is/nullOrUndefined.js */
+
+ /* ___filename___: dist/deps/is/objNotNull.js */
+
+
+
+ /**
+ * @param {*} x value
+ * @return {boolean} isObjStrict
+ *
+ * @since 3.0.0
+ * @memberOf is
+ * @func isObjStrict
+ * @see is/obj
+ * @see is/objWithKeys
+ * @see is/objTypeof
+ * @see is/null
+ * @see https://github.com/sindresorhus/is-obj/blob/master/index.js
+ * @TODO !Array.isArray
+ *
+ * @extends isObjTypeof
+ * @variation null will not count as an object
+ *
+ * @example
+ *
+ * isObjStrict(new Object())
+ * //=> true
+ * isObjStrict({})
+ * //=> true
+ * isObjStrict(Object.create(null))
+ * //=> true
+ * isObjStrict(null)
+ * //=> false
+ *
+ * isObjStrict(new Set())
+ * //=> false
+ * isObjStrict(function() {})
+ * //=> false
+ * isObjStrict('')
+ * //=> false
+ * isObjStrict(1)
+ * //=> false
+ *
+ */
+ var objNotNull = function (x) { return !nullOrUndefined(x) && objTypeof(x); };
+
+ /* ___filename___: dist/deps/is/array.js */
+ /**
+ * @func isArray
+ * @todo https://github.com/facebook/immutable-js/blob/master/src/utils/isArrayLike.js
+ * @see https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray
+ * @type {Function}
+ * @since 3.0.0
+ */
+ var array = Array.isArray;
+
+ // function isArray(xs) {
+ // return Object.prototype.toString.call(xs) === '[object Array]'
+ // }
+
+ /* ___filename___: dist/deps/is/true.js */
+ /**
+ * @param {*} x value
+ * @return {boolean} isTrue
+ *
+ * @since 4.0.0-alpha.1
+ * @memberOf is
+ * @func isTrue
+ *
+ * @example
+ *
+ * isTrue(true)
+ * //=> true
+ * isTrue(false)
+ * //=> false
+ * isTrue(1)
+ * //=> false
+ * isTrue('')
+ * //=> false
+ *
+ */
+ var _true = function (x) { return x === true; };
+
+ /* ___filename___: dist/deps/is/regexp.js */
+
+
+ /**
+ * Checks if `value` is classified as a `RegExp` object.
+ *
+ * @since 0.1.0
+ * @category Lang
+ * @param {*} x The value to check.
+ * @return {boolean} Returns `true` if `value` is a regexp, else `false`.
+ * @see https://github.com/lodash/lodash/blob/master/isRegExp.js
+ *
+ * @example
+ *
+ * isRegExp(/abc/)
+ * // => true
+ *
+ * isRegExp('/abc/')
+ * // => false
+ *
+ */
+ var regexp = function (x) { return toS(x) === '[object RegExp]'; };
+ // obj instanceof RegExp ||
+
+ /* ___filename___: dist/deps/is/date.js */
+
+
+ /**
+ * @param {*} x value
+ * @return {boolean} isDate
+ *
+ * @since 3.0.0
+ * @memberOf is
+ * @func isDate
+ * @extends toS
+ *
+ * @example
+ *
+ * isDate(new Date())
+ * //=> true
+ * isDate(Date.now())
+ * //=> false
+ * isDate(1)
+ * //=> false
+ * isDate('')
+ * //=> false
+ *
+ * @example
+ *
+ * const e = {}
+ * eh[Symbol.toStringTag] = '[Object Date]'
+ * isDate(eh)
+ * //=> true
+ *
+ * @example
+ *
+ * class Eh extends Date()
+ * isDate(new Eh())
+ * //=> true
+ */
+ var date = function isDate(x) {
+ return toS(x) === '[object Date]'
+ // x instanceof Date ||
+ };
+
+ /* ___filename___: dist/deps/is/true.js */
+
+ /* ___filename___: dist/deps/is/boolean.js */
+
+
+
+
+ /**
+ * @desc Checks if `value` is classified as a boolean primitive or object.
+ * @category Lang
+ * @since 3.0.0
+ *
+ * @param {*} x value
+ * @return {boolean} isBoolean
+ *
+ * @extends isTrue
+ * @extends isFalse
+ * @see is/toS
+ * @memberOf is
+ * @func isBoolean
+ *
+ * @NOTE could also have typeof x === 'boolean' || (/true|false/).test(x)
+ *
+ * @example
+ *
+ * isBoolean(false)
+ * //=> true
+ * isBoolean(new Boolean(1))
+ * //=> true
+ * isBoolean(1)
+ * //=> false
+ * isBoolean('')
+ * //=> false
+ *
+ */
+ var boolean_1 = function isBoolean(x) {
+ return _true(x) || _false(x) || toS(x) === '[object Boolean]'
+ };
+
+ /* ___filename___: dist/deps/is/array.js */
+
+ /* ___filename___: dist/deps/util/simpleKindOf.js */
+
+
+
+ /* prettier-ignore */
+ /**
+ * @desc when Array -> 'array'
+ * when null -> 'null'
+ * else `typeof x`
+ * @param {any} x
+ * @return {string} type
+ */
+ var simpleKindOf = function (x) {
+ return array(x)
+ ? 'array'
+ : _null(x)
+ ? 'null'
+ : typeof x
+ };
+
+ /* ___filename___: dist/deps/conditional/includes/includes.js */
+ var includes = function (haystack, needle) { return haystack.includes(needle); };
+
+ /* ___filename___: dist/deps/conditional/includes/includes.js */
+
+ var index$4 = includes;
+
+ /* ___filename___: dist/deps/dopemerge/emptyTarget.js */
+
+
+ /**
+ * @desc make a new empty Array or Object for cloning
+ * @memberOf dopemerge
+ * @name emptyTarget
+ * @since 2.0.0
+ * @func
+ *
+ * @param {*} val array or object to return an empty one of
+ * @return {Object | Array} depending on the data type of val
+ *
+ * @example
+ *
+ * emptyTarget({eh: true})
+ * //=> {}
+ *
+ * emptyTarget([1])
+ * //=> []
+ *
+ */
+ var emptyTarget = function emptyTarget(val) {
+ return array(val) ? [] : {}
+ };
+
+ /* ___filename___: dist/deps/is/objNotNull.js */
+
+ /* ___filename___: dist/deps/is/regexp.js */
+
+ /* ___filename___: dist/deps/is/date.js */
+
+ /* ___filename___: dist/deps/is/boolean.js */
+
+ /* ___filename___: dist/deps/util/simpleKindOf.js */
+
+ /* ___filename___: dist/deps/dopemerge/emptyTarget.js */
+
+ /* ___filename___: dist/deps/dopemerge/dopemerge.js */
+ /* eslint complexity: "OFF" */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ /**
+ * @desc 1: not null object
+ * 2: object toString is not a date or regex
+ *
+ * @category merge
+ * @memberOf dopemerge
+ *
+ * @since 2.0.0
+ * @param {*} x value to check
+ * @return {boolean}
+ *
+ * @example
+ *
+ * isMergeableObj({})
+ * //=> true
+ *
+ * isMergeableObj(Object.create(null))
+ * // => true
+ *
+ * isMergeableObj(new Date())
+ * //=> false
+ *
+ * isMergeableObj(/eh/)
+ * //=> false
+ *
+ */
+ function isMergeableObj(x) {
+ return objNotNull(x) && !regexp(x) && !date(x)
+ }
+
+ /**
+ * Defaults to `false`.
+ * If `clone` is `true` then both `x` and `y` are recursively cloned as part of the merge.
+ *
+ * @memberOf dopemerge
+ * @since 2.0.0
+ *
+ * @param {*} value value to clone if needed
+ * @param {DopeMergeOptions} optsArg dopemerge options, could contain .clone
+ * @return {Object | Array | any} cloned or original value
+ *
+ * @see emptyTarget
+ * @see isMergeableObj
+ *
+ * @example
+ *
+ * var obj = {eh: true}
+ *
+ * cloneIfNeeded(obj, {clone: true}) === obj
+ * //=> false
+ *
+ * cloneIfNeeded(obj, {clone: false}) === obj
+ * //=> true
+ *
+ */
+ function cloneIfNeeded(value, optsArg) {
+ return _true(optsArg.clone) && isMergeableObj(value)
+ ? deepmerge(emptyTarget(value), value, optsArg)
+ : value
+ }
+
+ /* prettier-ignore */
+ /**
+ * The merge will also merge arrays and array values by default.
+ * However, there are nigh-infinite valid ways to merge arrays,
+ * and you may want to supply your own.
+ * You can do this by passing an `arrayMerge` function as an option.
+ *
+ * @memberOf dopemerge
+ * @since 2.0.0
+ *
+ * @param {*} target array merged onto, could be emptyTarget if cloning
+ * @param {*} source original source array
+ * @param {*} optsArg dopemerge options
+ * @return {Array | *} merged array
+ *
+ * @example
+ *
+ * function concatMerge(destinationArray, sourceArray, options) {
+ * destinationArray
+ * //=> [1, 2, 3]
+ *
+ * sourceArray
+ * //=> [3, 2, 1]
+ *
+ * options
+ * //=> { arrayMerge: concatMerge }
+ *
+ * return destinationArray.concat(sourceArray)
+ * }
+ * merge([1, 2, 3], [3, 2, 1], { arrayMerge: concatMerge })
+ * //=> [1, 2, 3, 3, 2, 1]
+ *
+ */
+ function defaultArrayMerge(target, source, optsArg) {
+ var destination = target.slice();
+
+ for (var i = 0; i < source.length; i++) {
+ var v = source[i];
+ if (_undefined(destination[i])) {
+ destination[i] = cloneIfNeeded(v, optsArg);
+ }
+ else if (isMergeableObj(v)) {
+ destination[i] = deepmerge(target[i], v, optsArg);
+ }
+ // @see https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#Bitwise_NOT
+ // === -1
+ // eslint-disable-next-line prefer-includes/prefer-includes
+ else if (!~target.indexOf(v)) {
+ destination.push(cloneIfNeeded(v, optsArg));
+ }
+ }
+ return destination
+ }
+
+ function mergeObj(target, source, optsArg) {
+ var destination = {};
+ if (isMergeableObj(target)) {
+ var targetKeys = keys(target);
+ for (var k = 0; k < targetKeys.length; k++) {
+ destination[targetKeys[k]] = cloneIfNeeded(target[targetKeys[k]], optsArg);
+ }
+ }
+ var sourceKeys = keys(source);
+ for (var s = 0; s < sourceKeys.length; s++) {
+ var key = sourceKeys[s];
+ if (!isMergeableObj(source[key]) || !target[key]) {
+ destination[key] = cloneIfNeeded(source[key], optsArg);
+ }
+ else {
+ destination[key] = deepmerge(target[key], source[key], optsArg);
+ }
+ }
+
+ return destination
+ }
+
+ function deepmerge(target, source, optsArg) {
+ if (array(source)) {
+ var arrayMerge = optsArg.arrayMerge;
+ return array(target)
+ ? arrayMerge(target, source, optsArg)
+ : cloneIfNeeded(source, optsArg)
+ }
+
+ // else
+ return mergeObj(target, source, optsArg)
+ }
+
+ /* prettier-ignore */
+ /**
+ * Merge the enumerable attributes of two objects deeply.
+ * Merge two objects `x` and `y` deeply, returning a new merged object with the
+ * elements from both `x` and `y`.
+ * If an element at the same key is present for both `x` and `y`, the value from
+ * `y` will appear in the result.
+ * Merging creates a new object, so that neither `x` or `y` are be modified.
+ * However, child objects on `x` or `y` are copied over -
+ * if you want to copy all values, you must pass `true` to the clone option.
+ *
+ *
+ * @member dopemerge
+ * @category merge
+ *
+ * @param {*} obj1 left
+ * @param {*} obj2 right
+ * @param {*} opts dopemerge options
+ * @return {Object | Array | any} merged
+ *
+ * {@link https://github.com/KyleAMathews/deepmerge deepmerge}
+ * @see {@link deepmerge}
+ *
+ * @types dopemerge
+ * @tests deepmerge
+ *
+ * @example
+ *
+ * var x = {
+ * foo: {bar: 3},
+ * array: [{
+ * does: 'work',
+ * too: [1, 2, 3],
+ * }],
+ * }
+ *
+ * var y = {
+ * foo: {baz: 4},
+ * quux: 5,
+ * array: [
+ * {
+ * does: 'work',
+ * too: [4, 5, 6],
+ * },
+ * {
+ * really: 'yes',
+ * },
+ * ],
+ * }
+ *
+ * var expected = {
+ * foo: {
+ * bar: 3,
+ * baz: 4,
+ * },
+ * array: [
+ * {
+ * does: 'work',
+ * too: [1, 2, 3, 4, 5, 6],
+ * },
+ * {
+ * really: 'yes',
+ * },
+ * ],
+ * quux: 5,
+ * }
+ *
+ * merge(x, y)
+ * //=> expected
+ *
+ */
+ function dopemerge(obj1, obj2, opts) {
+ // if they are identical, fastest === check
+ if (obj1 === obj2) {
+ return obj1
+ }
+
+ // setup options
+ var options = assign(
+ {
+ arrayMerge: defaultArrayMerge,
+ stringToArray: true,
+ boolToArray: false,
+ ignoreTypes: ['null', 'undefined'],
+ // debug: true,
+ },
+ opts || {}
+ );
+ var ignoreTypes = options.ignoreTypes;
+ var stringToArray = options.stringToArray;
+ var boolToArray = options.boolToArray;
+ var clone = options.clone;
+
+ // @NOTE: much better size but oh well
+ // const ignoreTypes = ['null', 'undefined']
+ // const stringToArray = true
+ // const boolToArray = false
+ // const clone = true
+
+ // check one then check the other
+ if (_true(index$4(ignoreTypes, simpleKindOf(obj1)))) {
+ return obj2
+ }
+ else if (_true(index$4(ignoreTypes, simpleKindOf(obj2)))) {
+ return obj1
+ }
+ else if (boolean_1(obj1) && boolean_1(obj2)) {
+ // @NOTE uglifier optimizes into a wicked ternary
+ return boolToArray ? [obj1, obj2] : obj2
+ }
+ else if (string(obj1) && string(obj2)) {
+ return stringToArray ? [obj1, obj2] : obj1 + obj2
+ }
+ else if (array(obj1) && string(obj2)) {
+ return (clone ? obj1.slice(0) : obj1).concat([obj2])
+ }
+ else if (string(obj1) && array(obj2)) {
+ return (clone ? obj2.slice(0) : obj2).concat([obj1])
+ }
+ else {
+ return deepmerge(obj1, obj2, options)
+ }
+ }
+
+ var dopemerge_1 = dopemerge;
+
+ /* ___filename___: dist/deps/dopemerge/dopemerge.js */
+
+ var index$2 = dopemerge_1;
+
+ /* ___filename___: dist/deps/util/from.js */
+ /**
+ * @tutorial https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/from
+ * @see https://github.com/lodash/lodash/blob/master/.internal/setToArray.js
+ * ^ could use if needed
+ */
+ var from = Array.from;
+
+ /* ___filename___: dist/deps/util/from.js */
+
+ /* ___filename___: dist/deps/reduce/reduce.js */
+
+
+ /**
+ * @desc Map -> Object
+ * @since 4.0.0
+ *
+ * @param {Map} map map to reduce, calls entries, turns into an array, then object
+ * @return {Object} reduced object
+ *
+ * @see ArrayFrom
+ *
+ * @example
+ *
+ * var emptyMap = new Map()
+ * reduce(emptyMap)
+ * // => {}
+ *
+ * @example
+ *
+ * var map = new Map()
+ * map.set('eh', 1)
+ * reduce(map)
+ * // => {eh: 1}
+ *
+ */
+ var reduce = function (map) {
+ var reduced = {};
+
+ // only need to do this if we actually have values in our Map
+ if (map.size !== 0) {
+ reduced = from(map.entries()).reduce(function (acc, ref) {
+ var key = ref[0];
+ var value = ref[1];
+
+ acc[key] = value;
+ return acc
+ }, reduced);
+ }
+
+ return reduced
+ };
+
+ /* ___filename___: dist/deps/reduce/reduce.js */
+
+ var index$6 = reduce;
+
+ /* ___filename___: dist/deps/is/obj.js */
+
+
+
+
+ /**
+ * @func isObj
+ *
+ * Checks if `value` is the
+ * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
+ * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
+ *
+ * @since 3.0.0
+ * @category Lang
+ *
+ * @param {*} value The value to check.
+ * @return {boolean} Returns `true` if `value` is an object, else `false`.
+ *
+ * @memberOf is
+ * @see http://stackoverflow.com/questions/34111902/why-do-lodashs-isobject-isplainobject-behave-differently-than-typeof-x
+ * @see https://github.com/lodash/lodash/blob/master/isObject.js
+ * @NOTE Object.prototype.toString.call(val) === '[object Object]'
+ *
+ * @example
+ *
+ * isObject({})
+ * // => true
+ *
+ * isObject([1, 2, 3])
+ * // => true
+ *
+ * isObject(Function)
+ * // => true
+ *
+ * isObject(null)
+ * // => false
+ *
+ */
+ var obj = function (x) { return !_null(x) && (objTypeof(x) || _function(x)); };
+
+ /* ___filename___: dist/deps/is/obj.js */
+
+ /* ___filename___: dist/deps/reduce/entries.js */
+
+
+
+
+
+
+ /**
+ * @desc recursively reduce maps and objects that include reducable data
+ * @since 4.0.0
+ *
+ * @sig reduced => object => isMap(object) -> reduced; merge(object, reduced)
+ *
+ * @param {Object | any} reduced merged object and reduced
+ * @return {Function} Function(values: Object)
+ *
+ * @see https://www.airpair.com/javascript/javascript-array-reduce
+ * @see ChainedMap
+ *
+ * @example
+ *
+ * const map = new Map()
+ * map.set('eh', true)
+ * const nested = new Map()
+ * nested.set('reduced', true)
+ *
+ * const chain = {
+ * entries() {
+ * return {
+ * nested: reduce(nested),
+ * key: true,
+ * }
+ * },
+ * }
+ * const reduced = reduce(map)
+ * reduceEntries(reduced)({chain})
+ * // => {
+ * eh: true,
+ * chain: {
+ * nested: {
+ * reduced: true,
+ * key: true,
+ * },
+ * },
+ * }
+ *
+ * @example
+ *
+ * const reducedIgnored = {
+ * canada: {
+ * store: chain,
+ * },
+ * }
+ * const ignored = reduceEntries(reduced)(reducedIgnored)
+ * //=> {
+ * eh: true,
+ * chain: {
+ * nested: {
+ * reduced: true,
+ * },
+ * key: true,
+ * },
+ * }
+ *
+ */
+ var entries = function (reduced) { return function (obj$$1) {
+ var keys$$2 = keys(obj$$1);
+
+ for (var k = 0; k < keys$$2.length; k++) {
+ var key = keys$$2[k];
+
+ if (ignored(key)) {
+ continue
+ }
+
+ var value = obj$$1[key];
+ if (obj(value) && _function(value.entries)) {
+ assign(reduced, {[key]: value.entries(true) || {}});
+ }
+ }
+
+ return reduced
+ }; };
+
+ /* ___filename___: dist/deps/is/iterator.js */
+
+
+ /**
+ * @param {*} x value
+ * @return {boolean} isIterator
+ *
+ * @since 3.0.0
+ * @memberOf is
+ * @func isIterator
+ * @see https://github.com/jonschlinkert/kind-of/pull/12
+ *
+ * @example
+ *
+ * isIterator(new Set().values())
+ * //=> true
+ * isIterator(new Map.entries())
+ * //=> true
+ * isIterator(new Map())
+ * //=> false
+ * isIterator('')
+ * //=> false
+ * isIterator(1)
+ * //=> false
+ *
+ * @example
+ *
+ * const e = {}
+ * eh[Symbol.toStringTag] = '[Map Iterator]'
+ * isIterator(eh)
+ * //=> true
+ * eh[Symbol.toStringTag] = '[Set Iterator]'
+ * isIterator(eh)
+ * //=> true
+ *
+ * @example
+ *
+ * class Eh extends Set()
+ * isIterator(new Eh().values())
+ * //=> true
+ *
+ */
+ // eslint-disable-next-line
+ var iterator$2 = function (x) { return ~toS(x).indexOf('Iterator'); };
+
+ /* ___filename___: dist/deps/is/iterator.js */
+
+ /* ___filename___: dist/deps/to-arr.js */
+
+
+
+
+
+
+
+ /**
+ * @desc anything into an array
+ * @sig * => Array
+ * @since 0.0.1
+ *
+ * @param {any} ar turn this into an array
+ * @return {Array} anything into an array
+ *
+ * @tests deps/to-arr
+ * @types deps
+ *
+ * @example
+ *
+ * toarr([])
+ * // => []
+ *
+ * toarr('')
+ * // => ['']
+ *
+ * toarr('1,2')
+ * // => ['1', '2']
+ *
+ * toarr('1,2')
+ * // => ['1', '2']
+ *
+ * const map = new Map()
+ * map.set('eh', true)
+ * const arr = toarr(map.entries())
+ * // => ['eh', true]
+ *
+ * const set = new Set()
+ * set.add('eh')
+ * set.add(true)
+ * const arr = toarr(map.entries())
+ * // => ['eh', true]
+ *
+ * toarr('').concat(toarr(false)).concat(toarr(null))
+ * // => ['', false, null]
+ *
+ */
+ var toArr = function(ar) {
+ // @NOTE: !'' === true
+ if (stringPrimitive(ar)) { return ar.includes(',') ? ar.split(',') : [ar] }
+ else if (!ar) { return [ar] }
+ else if (array(ar)) { return ar }
+ else if (set(ar) || map(ar) || ar.values) {
+ /**
+ * @desc when using `new Set().values`... no forEach o.o
+ * .values is also on `Object`...
+ */
+ return from(ar.values(ar))
+ }
+ else if (iterator$2(ar)) { return from(ar) }
+ else { return [ar] }
+ };
+
+ /* ___filename___: dist/deps/to-arr.js */
+
+ /* ___filename___: dist/deps/concat.js */
+
+
+ /**
+ * @desc conat two values, coerce to arrays
+ * @since 4.0.0
+ *
+ * @func
+ * @name concat
+ *
+ * @param {Array | *} one toArr1
+ * @param {Array | *} two toArr2
+ * @return {Array} [one, two]
+ *
+ * @example
+ *
+ * concat([1], [2]) //=> [1, 2]
+ * concat([1], 2) //=> [1, 2]
+ * concat(1, 2) //=> [1, 2]
+ * concat(new Set([1]), 2) //=> [1, 2]
+ *
+ * // kind of weird...
+ * concat(null, 2) //=> [2]
+ * concat(undefined, 2) //=> [2]
+ * concat(1, null) //=> [1, null]
+ *
+ */
+ var concat = function (one, two) { return toArr(one || []).concat(toArr(two)); };
+
+ /* ___filename___: dist/deps/fp/always.js */
+ /**
+ * Returns a function that always returns the given value. Note that for
+ * non-primitives the value returned is a reference to the original value.
+ *
+ * This function is known as `const`, `constant`, or `K` (for K combinator) in
+ * other languages and libraries.
+ *
+ * @alias always
+ * @alias constant
+ * @func
+ * @memberOf fp
+ * @since v5.0.0
+ * @category Function
+ * @sig a -> (* -> a)
+ *
+ * @param {*} value The value to wrap in a function
+ * @return {Function} A Function :: * -> val.
+ *
+ * @see https://github.com/ramda/ramda/issues/1038
+ * @see https://github.com/ramda/ramda/blob/master/src/always.js
+ *
+ * @example
+ *
+ * var t = always('Tee');
+ * t(); //=> 'Tee'
+ *
+ */
+
+ /* ___filename___: dist/deps/meta/transformers.js */
+ /* istanbul ignore next: wip build */
+ var transformers = process.env.NODE_ENV === 'production'
+ ? 'transformers'
+ : 'transformers';
+
+ /* ___filename___: dist/deps/meta/observers.js */
+ /* istanbul ignore next: wip build */
+ var observers = process.env.NODE_ENV === 'production'
+ ? 'observers'
+ : 'observers';
+
+ /* ___filename___: dist/deps/meta/shorthands.js */
+ /* istanbul ignore next: wip build */
+ var shorthands = process.env.NODE_ENV === 'production'
+ ? 'shorthands'
+ : 'shorthands';
+
+ /* ___filename___: dist/deps/meta/decorated.js */
+ /* istanbul ignore next: wip build */
+ var decorated = process.env.NODE_ENV === 'production'
+ ? 'decorated'
+ : 'decorated';
+
+ /* ___filename___: dist/deps/concat.js */
+
+ /* ___filename___: dist/deps/fp/always.js */
+
+ /* ___filename___: dist/deps/meta/transformers.js */
+
+ /* ___filename___: dist/deps/meta/observers.js */
+
+ /* ___filename___: dist/deps/meta/shorthands.js */
+
+ /* ___filename___: dist/deps/meta/decorated.js */
+
+ /* ___filename___: dist/deps/meta/meta.js */
+ // without it, the arguments & caller are uglier when drbugging
+
+
+
+
+
+
+
+
+
+
+
+
+
+ // will expand this later
+ var isInKeyMapAsSet = function (x) { return x === observers; };
+ var emptyArray = []; // always([])
+
+ // @NOTE: using `[]` deopts o.o
+ // eslint-disable-next-line
+ // this.shorthands = new Array()
+
+ /**
+ * @since 4.0.0
+ * @param {Chain} _this
+ * @return {Chain}
+ */
+ function getMeta(_this) {
+ // if we already have it, keep it
+ if (_this.meta) { return _this.meta }
+
+ // the store
+ // shorthands: key -> method
+ var store = {};
+
+ // --- uglifiable functions
+
+ /** @desc initialize the store maps when we need them */
+ /* prettier-ignore */
+ var ensureInitialized = function (name, value) {
+ if (!_undefined(store[name])) { return }
+
+ // if (
+ // name === TRANSFORMERS_KEY ||
+ // name === SHORTHANDS_KEY ||
+ // name === DECORATED_KEY
+ // ) {
+ // store[name] = new Map()
+ // }
+ // else
+ if (isInKeyMapAsSet(name)) {
+ store[name] = new Set();
+ }
+ else {
+ store[name] = new Map();
+ }
+ };
+
+ /**
+ * @since 4.0.0
+ * @param {Primitive} key
+ * @param {Primitive | undefined} [prop=undefined]
+ * @return {boolean}
+ */
+ var has = function (key, prop) {
+ if (_undefined(prop)) { return !!store[key].size }
+ else { return store[key].has(prop) }
+ };
+ /**
+ * @since 4.0.0
+ * @param {Primitive} key
+ * @param {Primitive | undefined} [prop=undefined]
+ * @return {any}
+ */
+ var get = function (key, prop) { return (has(key, prop) ? store[key].get(prop) : emptyArray); };
+
+ /**
+ * @since 4.0.0
+ * @param {Primitive} key
+ * @param {Primitive | undefined} [prop=undefined]
+ * @param {Primitive | undefined} [value=undefined]
+ * @return {void}
+ */
+ var set$$2 = function (key, prop, value) {
+ var storage = store[key];
+ // when it's a set, we have no `prop`, we just have .add
+ // so `prop = value` && `value = undefined`
+ if (set(storage)) {
+ storage.add(prop);
+ }
+ else {
+ // if (!has(key, prop)) return
+ var existing = storage.get(prop);
+ var val = concat(existing, value);
+ storage.set(prop, val);
+ }
+ };
+
+ /**
+ * @since 4.0.0
+ *
+ * @desc a single easily minifiable function,
+ * dynamically setting & getting depending on arguments
+ * to avoid nested property accessing
+ * only instantiating when values are **addded**
+ *
+ * @param {Primitive} key
+ * @param {Primitive | undefined} [prop=undefined]
+ * @param {undefined | any} [value=undefined] (when no value, it's a getter)
+ * @return {Array | Chain} depending on args
+ */
+ function meta(key, prop, value) {
+ if (process.env.NODE_ENV === 'DEBUG') {
+ console.log('USING META', {key: key, prop: prop, value: value});
+ }
+
+ /* prettier-ignore */
+ if (_undefined(value)) {
+ // when we want to just access the property, return an array
+ // @example `.meta('transformers')`
+ if (_undefined(prop)) {
+ if (_undefined(store[key])) { return emptyArray }
+ else { return store[key].size === 0 ? emptyArray : from(store[key].values()) }
+ }
+ // we have `key, prop`
+ //
+ // 1: should `prop` be a value, (isSet?)
+ else if (isInKeyMapAsSet(key)) {
+ ensureInitialized(key);
+ set$$2(key, prop);
+ }
+ // 2: prop is a key, we want to return the [..] for that specific property
+ // @example `.meta('transformers', 'eh')`
+ else if (_undefined(store[key])) { return emptyArray }
+ else { return toArr(get(key, prop)) }
+ }
+ // we have `key, prop, value`
+ else {
+ ensureInitialized(key);
+ // we have a value, let's add it
+ set$$2(key, prop, value);
+ }
+ return _this
+ }
+
+ // for debugging
+ meta.store = store;
+ // meta.debug = false
+
+ return meta
+ }
+
+ var meta = getMeta;
+
+ /* ___filename___: dist/deps/meta/meta.js */
+
+ var index$8 = meta;
+
+ /* ___filename___: dist/Chainable.js */
+
+ /* ___filename___: dist/deps/reduce/entries.js */
+
+ /* ___filename___: dist/ChainedMapBase.js */
+
+
+
+
+
+
+
+
+
+
+ /**
+ * this is to avoid circular requires
+ * because MergeChain & MethodChain extend this
+ * yet .method & .merge use those chains
+ * ...also, it serves as a non-references creator for extending new instances
+ * of Chainable, where it splits into (Map | Set) -> composed prototype decorators
+ *
+ *
+ * @file
+ * @since 4.0.0-alpha.1
+ * @inheritdoc
+ * @class ChainedMapBase
+ * @member ChainedMapBase
+ * @category Chainable
+ * @extends {Chainable}
+ * @type {Chainable}
+ *
+ * @types ChainedMapBase
+ * @tests ChainedMap
+ *
+ * @prop {Meta} meta meta fn
+ * @prop {Map} store main store
+ *
+ * {@link https://tc39.github.io/ecma262/#sec-map-objects emca-map}
+ * {@link https://ponyfoo.com/articles/es6-maps-in-depth pony-map}
+ * {@link https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Map mozilla-map}
+ * @see {@link pony-map}
+ * @see {@link mozilla-map}
+ * @see {@link emca-map}
+ *
+ * @see ChainedMap
+ * @see Chainable
+ * @see MergeChain
+ * @see MethodChain
+ * @see ChainedMap
+ *
+ */
+
+ var ComposeChainedMapBase = function (Target) {
+ return (function (Target) {
+ function ChainedMapBase(parent) {
+ Target.call(this, parent);
+
+ this.store = new Map();
+ this.meta = index$8(this);
+ }
+
+ if ( Target ) ChainedMapBase.__proto__ = Target;
+ ChainedMapBase.prototype = Object.create( Target && Target.prototype );
+ ChainedMapBase.prototype.constructor = ChainedMapBase;
+
+ /**
+ * @desc tap a value with a function
+ * @modifies this.store.get(name)
+ * @memberOf ChainedMapBase
+ * @version 0.7.0
+ * @since 4.0.0-alpha.1 <- moved from transform & shorthands
+ *
+ * @param {string | any} name key to `.get`
+ * @param {Function} fn function to tap with
+ * @return {Chain} @chainable
+ *
+ * {@link https://github.com/sindresorhus/awesome-tap awesome-tap}
+ * {@link https://github.com/midknight41/map-factory map-factory}
+ * {@link https://github.com/webpack/tapable tapable}
+ * @see {@link tapable}
+ *
+ * @see ChainedMapBase.set
+ * @see ChainedMapBase.get
+ *
+ * @example
+ *
+ * chain
+ * .set('moose', {eh: true})
+ * .tap('moose', moose => {moose.eh = false; return moose})
+ * .get('moose')
+ *
+ * // => {eh: false}
+ *
+ * @example
+ *
+ * const entries = new Chain()
+ * .set('str', 'emptyish')
+ * .tap('str', str => str + '+')
+ * .set('arr', [1])
+ * .tap('arr', arr => arr.concat([2]))
+ * .entries()
+ *
+ * //=> {str: 'emptyish+', arr: [1, 2]}
+ *
+ */
+ ChainedMapBase.prototype.tap = function tap (name, fn) {
+ return this.set(name, fn(this.get(name), index$2))
+ };
+
+ /**
+ * @desc checks each property of the object
+ * calls the chains accordingly
+ *
+ * @memberOf ChainedMapBase
+ * @since 0.5.0
+ *
+ * @param {Object} obj object with functions to hydrate from
+ * @return {Chainable} @chainable
+ *
+ * @TODO could also add parsing stringified
+ *
+ * @example
+ *
+ * const from = new Chain().from({eh: true})
+ * const eh = new Chain().set('eh', true)
+ * eq(from, eh)
+ * // => true
+ *
+ */
+ ChainedMapBase.prototype.from = function from (obj) {
+ var this$1 = this;
+
+ var keys$$1 = keys(obj);
+
+ for (var k = 0; k < keys$$1.length; k++) {
+ var key = keys$$1[k];
+ var value = obj[key];
+ var fn = this$1[key];
+
+ if (fn && fn.merge) {
+ fn.merge(value);
+ }
+ else if (_function(fn)) {
+ fn.call(this$1, value);
+ }
+ else {
+ this$1.set(key, value);
+ }
+ }
+
+ return this
+ };
+
+ /**
+ * @desc shorthand methods, from strings to functions that call .set
+ * @since 0.4.0
+ * @memberOf ChainedMapBase
+ *
+ * @param {Array} methods decorates/extends an object with new shorthand functions to get/set
+ * @return {ChainedMapBase} @chainable
+ *
+ * @example
+ *
+ * const chain1 = new Chain()
+ * chain1.extend(['eh'])
+ *
+ * const chain2 = new Chain()
+ * chain2.eh = val => this.set('eh', val)
+ *
+ * eq(chain2.eh, chain1.eh)
+ * //=> true
+ *
+ */
+ ChainedMapBase.prototype.extend = function extend (methods) {
+ var this$1 = this;
+
+ methods.forEach(function (method) {
+ this$1.meta(shorthands, method);
+ this$1[method] = function (value) { return this$1.set(method, value); };
+ });
+ return this
+ };
+
+ /**
+ * @desc spreads the entries from ChainedMapBase.store (Map)
+ * return store.entries, plus all chain properties if they exist
+ *
+ * @memberOf ChainedMapBase
+ * @version 4.0.0 <- improved reducing
+ * @since 0.4.0
+ *
+ * @param {boolean} [chains=false] if true, returns all properties that are chains
+ * @return {Object} reduced object containing all properties from the store, and when `chains` is true, all instance properties, and recursive chains
+ *
+ * //
+ *
+ * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/entries mozilla-map-entries}
+ * @see {@link mozilla-map-entries}
+ *
+ * @example
+ *
+ * map.set('a', 'alpha').set('b', 'beta').entries()
+ * //=> {a: 'alpha', b: 'beta'}
+ *
+ */
+ ChainedMapBase.prototype.entries = function entries$$1 (chains) {
+ var reduced = index$6(this.store);
+ if (_undefined(chains)) { return reduced }
+
+ var reducer = entries(reduced);
+ reducer(this);
+ reducer(reduced);
+ return reduced
+ };
+
+ /**
+ * @desc get value for key path in the Map store
+ * ❗ `debug` is a special key and is *not* included into .store
+ * it goes onto .meta
+ *
+ * @memberOf ChainedMapBase
+ * @version 4.0.0 <- moved debug here
+ * @since 0.4.0
+ *
+ * @param {Primitive} key Primitive data key used as map property to reference the value
+ * @return {any} value in .store at key
+ *
+ * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/get mozilla-map-get}
+ * @see {@link mozilla-map-get}
+ *
+ * @example
+ *
+ * const chain = new Chain()
+ * chain.set('eh', true)
+ * chain.get('eh')
+ * //=> true
+ *
+ * chain.get('nope')
+ * //=> undefined
+ *
+ */
+ ChainedMapBase.prototype.get = function get (key) {
+ if (key === 'debug') { return this.meta.debug }
+ return this.store.get(key)
+ };
+
+ /**
+ * @desc sets the value using the key on store
+ * adds or updates an element with a specified key and value
+ *
+ * @memberOf ChainedMapBase
+ * @since 0.4.0
+ *
+ * @param {Primitive} key Primitive to reference the value
+ * @param {any} value any data to store
+ * @return {ChainedMapBase} @chainable
+ *
+ * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/set mozilla-map-set}
+ *
+ * @see {@link mozilla-map-set}
+ * @see ChainedMapBase.store
+ *
+ * @example
+ *
+ * const chain = new Chain()
+ * chain.set('eh', true)
+ * chain.get('eh')
+ * //=> true
+ *
+ */
+ ChainedMapBase.prototype.set = function set (key, value) {
+ this.store.set(key, value);
+ return this
+ };
+
+ return ChainedMapBase;
+ }(Target))
+ };
+
+ /**
+ * @desc ChainedMapBase composer
+ * @alias ComposeMap
+ * @type {Composer}
+ * @method compose
+ * @memberOf ChainedMapBase
+ *
+ * @param {Class | Object | Composable} [Target=Chainable] class to extend
+ * @return {Class} ChainedMapBase
+ *
+ * @example
+ *
+ * const heh = class {}
+ * const composed = ChainedMapBase.compose(heh)
+ * const hehchain = new Composed()
+ * hehchain instanceof heh
+ * //=> true
+ *
+ */
+ var cmc = ComposeChainedMapBase(Chainable);
+ cmc.compose = ComposeChainedMapBase;
+
+ var ChainedMapBase = cmc;
+
+ /* ___filename___: dist/deps/env/debug.js */
+ var debug = process.env.NODE_ENV === 'debug'; // || process.env.DEBUG = true
+
+ /* ___filename___: dist/deps/util/keysObjOrArray.js */
+
+
+
+
+ /**
+ * Creates an array of the own enumerable property names of `object`.
+ *
+ * **Note:** Non-object values are coerced to objects. See the
+ * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
+ * for more details.
+ *
+ * @since 0.1.0
+ * @category Object
+ *
+ * @param {Object} object The object to query.
+ * @return {Array} Returns the array of property names.
+ *
+ * @see deps/util/props
+ * @see values, valuesIn
+ * @see https://github.com/lodash/lodash/blob/master/.internal/getAllKeys.js
+ * @see https://github.com/lodash/lodash/blob/master/keys.js
+ * @TODO https://github.com/lodash/lodash/blob/master/.internal/arrayLikeKeys.js
+ *
+ * @example
+ *
+ * function Foo() {
+ * this.a = 1
+ * this.b = 2
+ * }
+ *
+ * Foo.prototype.c = 3
+ *
+ * keys(new Foo)
+ * // => ['a', 'b'] (iteration order is not guaranteed)
+ *
+ * keys('hi')
+ * // => ['0', '1']
+ *
+ */
+
+ var zeroOneLength = function (obj$$2) { return (obj$$2.length > 1 ? obj$$2.length - 1 : obj$$2.length === 1 ? 1 : 0); };
+
+ var keysObjOrArray = function keys$$2(obj$$2) {
+ return array(obj$$2)
+ ? new Array(zeroOneLength(obj$$2))
+ : obj(obj$$2) ? keys(obj$$2) : []
+
+ // for (var key in obj) gathered.push(key)
+ // return gathered
+ };
+
+ /* ___filename___: dist/deps/util/keysObjOrArray.js */
+
+ /* ___filename___: dist/deps/is/empty.js */
+
+
+
+
+
+ /* prettier-ignore */
+ /**
+ * Returns `true` if the given value is its type's empty value;
+ * `false` otherwise.
+ *
+ * @func
+ * @memberOf is
+ * @since v0.1.0
+ * @category Logic
+ * @sig a -> Boolean
+ *
+ * @param {*} x value to check if empty
+ * @return {boolean}
+ *
+ * @see empty
+ * @see https://github.com/ramda/ramda/issues/1228
+ *
+ * @example
+ *
+ * isEmpty([1, 2, 3]); //=> false
+ * isEmpty([]); //=> true
+ * isEmpty(''); //=> true
+ * isEmpty(null); //=> false
+ * isEmpty({}); //=> true
+ * isEmpty({length: 0}); //=> false
+ *
+ */
+ var empty = function isEmpty(x) {
+ if (x === '') { return true }
+ else if (nullOrUndefined(x)) { return false }
+ else if (obj(x) || array(x)) { return keysObjOrArray(x).length === 0 }
+ else { return false }
+
+ // else return (
+ // // null|undefined = empty
+ // // isNullOrUndefined(x) ||
+ // // '' = empty
+ // // [] | {} = empty
+ // keys(x).length === 0
+ // )
+ };
+
+ /* ___filename___: dist/deps/is/error.js */
+
+
+ /**
+ * @param {*} x value
+ * @return {boolean} isError
+ *
+ * @since 4.0.0
+ * @memberOf is
+ * @func isError
+ *
+ * @example
+ *
+ * isError(new Error())
+ * //=> true
+ * isError(new Error().stack)
+ * //=> false
+ * isError(1)
+ * //=> false
+ * isError('')
+ * //=> false
+ *
+ * @example
+ *
+ * const e = {}
+ * eh[Symbol.toStringTag] = '[Object Error]'
+ * isError(eh)
+ * //=> true
+ *
+ * @example
+ *
+ * class Eh extends Error()
+ * isError(new Eh())
+ * //=> true
+ *
+ */
+ var error$1 = function isError(x) {
+ // console.log('isError', toS(x), x)
+ return toS(x) === '[object Error]'
+ // x instanceof Error ||
+ };
+
+ /* ___filename___: dist/deps/is/symbol.js */
+
+
+ /**
+ * Checks if `value` is classified as a `Symbol` primitive or object.
+ *
+ * @since 4.0.0
+ * @category Lang
+ * @memberOf is
+ *
+ * @param {*} value The value to check.
+ * @return {boolean} Returns `true` if `value` is a symbol, else `false`.
+ *
+ * @example
+ *
+ * isSymbol(Symbol.iterator)
+ * // => true
+ *
+ * isSymbol('abc')
+ * // => false
+ *
+ */
+ var symbol = function (x) { return toS(x) === '[object Symbol]'; };
+
+ /* ___filename___: dist/deps/is/async.js */
+
+
+ /**
+ * @category Lang
+ *
+ * @param {*} x value
+ * @return {boolean} isAsync
+ * @since 4.0.0-beta.2
+ *
+ * @memberOf is
+ * @func isAsync
+ *
+ * @example
+ *
+ * isAsync(async function() {})
+ * //=> true
+ * isAsync(new Promise(r => r()))
+ * //=> false
+ * isAsync({})
+ * //=> false
+ * isAsync(function() {})
+ */
+ var async = function isAsync(x) {
+ return toS(x) === '[object AsyncFunction]'
+ };
+
+ /* ___filename___: dist/deps/is/promise.js */
+
+
+ /**
+ * @desc is a Promise
+ * @param {*} x value
+ * @return {boolean} x isPromise
+ *
+ * @since 4.0.0-beta.2
+ * @memberOf is
+ * @func isPromise
+ *
+ * @see https://github.com/jonschlinkert/kind-of/blob/master/index.js#L66
+ * @see https://github.com/sindresorhus/promise-fun
+ *
+ * @example
+ *
+ * isPromise(new Promise(r => r))
+ * //=> true
+ * isPromise(async function() {})
+ * //=> false // on some environments, true
+ *
+ * isPromise({})
+ * //=> false
+ * isPromise(Object.create(null))
+ * //=> false
+ * isPromise(null)
+ * //=> false
+ * isPromise(new Set())
+ * //=> false
+ * isPromise(function() {})
+ * //=> false
+ * isPromise('')
+ * //=> false
+ * isPromise(1)
+ * //=> false
+ *
+ */
+ var promise = function (x) { return toS(x) === '[object Promise]'; };
+
+ /* ___filename___: dist/deps/is/async.js */
+
+ /* ___filename___: dist/deps/is/promise.js */
+
+ /* ___filename___: dist/deps/is/asyncish.js */
+
+
+
+ /**
+ * @desc async function or promise
+ * @category Lang
+ *
+ * @param {*} x value
+ * @return {boolean} x isAsyncish
+ * @since 4.0.0-beta.2
+ *
+ * @memberOf is
+ * @func isAsyncish
+ * @extends isAsyncish
+ * @extends isPromise
+ * @variation isAsyncish OR isPromise
+ *
+ * @example
+ *
+ * isAsyncish(async function() {})
+ * //=> true
+ * isAsyncish(new Promise(r => r()))
+ * //=> true
+ *
+ * isAsyncish({})
+ * //=> false
+ * isAsyncish(function() {})
+ */
+ var asyncish = function (x) { return async(x) || promise(x); };
+
+ /* ___filename___: dist/deps/is/numberPrimitive.js */
+ /**
+ * @param {*} x value
+ * @return {boolean} isNumberPrimitive
+ *
+ * @since 3.0.0
+ * @memberOf is
+ * @func isNumberPrimitive
+ * @see is/real
+ *
+ * @example
+ *
+ * isNumberPrimitive(1)
+ * //=> true
+ * isNumberPrimitive(Number(1))
+ * //=> true
+ * isNumberPrimitive(NaN)
+ * //=> true
+ * isNumberPrimitive(new Number(1))
+ * //=> false
+ *
+ * isNumberPrimitive(null)
+ * //=> false
+ * isNumberPrimitive(undefined)
+ * //=> false
+ * isNumberPrimitive(void 0)
+ * //=> false
+ * isNumberPrimitive({})
+ * //=> false
+ * isNumberPrimitive('')
+ * //=> false
+ * isNumberPrimitive(false)
+ * //=> false
+ *
+ */
+ var numberPrimitive = function (x) { return typeof x === 'number'; };
+
+ /* ___filename___: dist/deps/is/numberPrimitive.js */
+
+ /* ___filename___: dist/deps/is/primitive.js */
+
+
+
+
+
+ /**
+ * Checks if `value` is classified as a `String` **primitive**.
+ *
+ * @since 3.0.0
+ * @category Lang
+ * @memberOf is
+ * @param {*} x The value to check.
+ * @returns {boolean} Returns `true` if `value` is a string, else `false`.
+ *
+ * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String
+ * @see https://github.com/lodash/lodash/blob/master/isString.js
+ * @see is/string
+ *
+ * @example
+ *
+ * isPrimitive('abc') // => true
+ * isPrimitive(new String('abc')) // => false
+ * isPrimitive(1) // => true
+ * isPrimitive([]) // => false
+ * isPrimitive('') // => true
+ * isPrimitive({}) // => false
+ *
+ */
+ var primitive$2 = function isPrimitive(node) {
+ return (
+ nullOrUndefined(node) ||
+ stringPrimitive(node) ||
+ numberPrimitive(node) ||
+ boolean_1(node) // isBooleanPrimitive
+ )
+ };
+
+ /* ___filename___: dist/deps/fp/isPlaceholder.js */
+ var isPlaceholder = function _isPlaceholder(x) {
+ return x === '_'
+ };
+
+ /* ___filename___: dist/deps/fp/arity.js */
+ /* istanbul ignore next: metadata, one is covered, all are covered */
+ /* prettier-ignore */
+ /**
+ * @desc just for `.length` of a function?
+ * @memberOf fp
+ *
+ * @since 5.0.0
+ * @param {number} n number of arguments
+ * @param {Function} fn function to wrap
+ * @return {Function} function with params
+ *
+ * @TODO keeping this means change uglify...
+ *
+ * @example
+ * const wan = one => console.log(one)
+ * arity(1, wan)
+ * => function(one => wan(one))
+ */
+ var arity = function _arity(n, fn) {
+ /* eslint-disable no-unused-vars */
+ if (n === 0) { return function() { return fn.apply(this, arguments) } }
+ else if (n === 1) { return function(a0) { return fn.apply(this, arguments) } }
+ else if (n === 2) { return function(a0, a1) { return fn.apply(this, arguments) } }
+ else if (n === 3) { return function(a0, a1, a2) { return fn.apply(this, arguments) } }
+ else if (n === 4) { return function(a0, a1, a2, a3) { return fn.apply(this, arguments) } }
+ else if (n === 5) { return function(a0, a1, a2, a3, a4) { return fn.apply(this, arguments) } }
+ else if (n === 6) { return function(a0, a1, a2, a3, a4, a5) { return fn.apply(this, arguments) } }
+ else if (n === 7) { return function(a0, a1, a2, a3, a4, a5, a6) { return fn.apply(this, arguments) } }
+ else if (n === 8) { return function(a0, a1, a2, a3, a4, a5, a6, a7) { return fn.apply(this, arguments) } }
+ else if (n === 9) { return function(a0, a1, a2, a3, a4, a5, a6, a7, a8) { return fn.apply(this, arguments) } }
+ else if (n === 10) { return function(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) { return fn.apply(this, arguments) } }
+ };
+
+ /* ___filename___: dist/deps/fp/isPlaceholder.js */
+
+ /* ___filename___: dist/deps/fp/arity.js */
+
+ /* ___filename___: dist/deps/fp/curry.js */
+
+
+
+
+ /**
+ * Returns a curried equivalent of the provided function, with the specified
+ * arity. The curried function has two unusual capabilities. First, its
+ * arguments needn't be provided one at a time. If `g` is `R.curryN(3, f)`, the
+ * following are equivalent:
+ *
+ * - `g(1)(2)(3)`
+ * - `g(1)(2, 3)`
+ * - `g(1, 2)(3)`
+ * - `g(1, 2, 3)`
+ *
+ * Secondly, the special placeholder value [`R.__`](#__) may be used to specify
+ * "gaps", allowing partial application of any combination of arguments,
+ * regardless of their positions. If `g` is as above and `_` is [`R.__`](#__),
+ * the following are equivalent:
+ *
+ * - `g(1, 2, 3)`
+ * - `g(_, 2, 3)(1)`
+ * - `g(_, _, 3)(1)(2)`
+ * - `g(_, _, 3)(1, 2)`
+ * - `g(_, 2)(1)(3)`
+ * - `g(_, 2)(1, 3)`
+ * - `g(_, 2)(_, 3)(1)`
+ *
+ * @func
+ * @memberOf fp
+ * @since v0.5.0
+ * @category Function
+ * @sig Number -> (* -> a) -> (* -> a)
+ *
+ * @param {Number} length The arity of the curried function.
+ * @param {Array} received An array of arguments received thus far.
+ * @param {Function} fn The function to curry.
+ * @return {Function} A new, curried function.
+ *
+ * @see R.curry
+ *
+ * @example
+ *
+ * var sumArgs = (...args) => R.sum(args);
+ *
+ * var curriedAddFourNumbers = R.curryN(4, sumArgs);
+ * var f = curriedAddFourNumbers(1, 2);
+ * var g = f(3);
+ * g(4); //=> 10
+ *
+ */
+ function _curryN(length, received, fn) {
+ return function() {
+ var arguments$1 = arguments;
+
+ var combined = [];
+ var argsIdx = 0;
+ var left = length;
+ var combinedIdx = 0;
+
+ while (combinedIdx < received.length || argsIdx < arguments.length) {
+ var result = (void 0);
+
+ if (
+ combinedIdx < received.length &&
+ (!isPlaceholder(received[combinedIdx]) || argsIdx >= arguments$1.length)
+ ) {
+ result = received[combinedIdx];
+ }
+ else {
+ result = arguments$1[argsIdx++];
+ // argsIdx += 1
+ }
+ combined[combinedIdx++] = result;
+ if (!isPlaceholder(result)) {
+ left -= 1;
+ }
+ // combinedIdx += 1
+ }
+ return left <= 0
+ ? fn.apply(this, combined)
+ : arity(left, _curryN(length, combined, fn))
+ }
+ }
+
+ /**
+ * Returns a curried equivalent of the provided function, with the specified
+ * arity. The curried function has two unusual capabilities. First, its
+ * arguments needn't be provided one at a time. If `g` is `R.curryN(3, f)`, the
+ * following are equivalent:
+ *
+ * - `g(1)(2)(3)`
+ * - `g(1)(2, 3)`
+ * - `g(1, 2)(3)`
+ * - `g(1, 2, 3)`
+ *
+ * Secondly, the special placeholder value [`R.__`](#__) may be used to specify
+ * "gaps", allowing partial application of any combination of arguments,
+ * regardless of their positions. If `g` is as above and `_` is [`R.__`](#__),
+ * the following are equivalent:
+ *
+ * - `g(1, 2, 3)`
+ * - `g(_, 2, 3)(1)`
+ * - `g(_, _, 3)(1)(2)`
+ * - `g(_, _, 3)(1, 2)`
+ * - `g(_, 2)(1)(3)`
+ * - `g(_, 2)(1, 3)`
+ * - `g(_, 2)(_, 3)(1)`
+ *
+ * @func
+ * @memberOf fp
+ * @since v0.5.0
+ * @category Function
+ * @sig Number -> (* -> a) -> (* -> a)
+ *
+ * @param {Number} length The arity for the returned function.
+ * @param {Function} fn The function to curry.
+ * @return {Function} A new, curried function.
+ *
+ * @see ramda
+ *
+ * @example
+ *
+ * var sumArgs = (...args) => R.sum(args);
+ *
+ * var curriedAddFourNumbers = R.curryN(4, sumArgs);
+ * var f = curriedAddFourNumbers(1, 2);
+ * var g = f(3);
+ * g(4); //=> 10
+ *
+ */
+ var curry = function curryN(length, fn) {
+ return arity(length, _curryN(length, [], fn))
+ };
+
+ /* ___filename___: dist/deps/fp/curry.js */
+
+ /* ___filename___: dist/deps/fp/prop.js */
+
+
+ /**
+ * Returns a function that when supplied an object returns the indicated
+ * property of that object, if it exists.
+ *
+ * @func
+ * @memberOf fp
+ * @since v5.0.0
+ * @category Object
+ * @sig s -> {s: a} -> a | Undefined
+ *
+ * @param {String} p The property name
+ * @param {Object} obj The object to query
+ * @return {*} The value at `obj.p`.
+ *
+ * @see R.path
+ *
+ * @example
+ *
+ * R.prop('x', {x: 100}); //=> 100
+ * R.prop('x', {}); //=> undefined
+ *
+ */
+ var prop = curry(2, function (p, obj) { return obj[p]; });
+
+ /* ___filename___: dist/deps/fp/prop.js */
+
+ /* ___filename___: dist/deps/util/length.js */
+
+
+ // reduces size by hundreds of bytes gzipped...
+ var length = prop('length');
+
+ /* ___filename___: dist/deps/util/length.js */
+
+ /* ___filename___: dist/deps/util/lengthMinusOne.js */
+
+
+ // lengthMinusOne
+ var lengthMinusOne = function (x) { return length(x) - 1; };
+
+ /* ___filename___: dist/deps/util/lengthMinusOne.js */
+
+ /* ___filename___: dist/deps/dot/segments.js */
+
+
+
+
+ var cache;
+
+ /**
+ * @name dotPropSegments
+ * @since 4.0.0
+ * @memberOf dot
+ *
+ * @param {string | Array} path dot-prop-path
+ * @return {Array} array path
+ *
+ * @example
+ *
+ * dotPropSegments('eh.oh') //=> ['eh', 'oh']
+ * dotPropSegments(['eh', 'oh']) //=> ['eh', 'oh']
+ * dotPropSegments('ehoh') //=> ['ehoh']
+ *
+ */
+ var segments = function (path) {
+ if (!cache) { cache = new Map(); }
+ if (cache.has(path)) { return cache.get(path) }
+ if (array(path)) { return path }
+
+ var pathArr = path.split('.');
+ var parts = [];
+
+ for (var i = 0; i < pathArr.length; i++) {
+ var p = pathArr[i];
+
+ /**
+ * @example 1
+ * '\.eh' -1 === '\\' (true)
+ * +1 !== undefined (true, eh)
+ *
+ * @example 2
+ * '.eh' -1 === '\\' (false, undefined)
+ * +1 !== undefined (true, eh)
+ *
+ * @example 3
+ * '\.' -1 === '\\' (true)
+ * +1 !== undefined (false, eh)
+ */
+ while (p[lengthMinusOne(p)] === '\\' && !_undefined(pathArr[i + 1])) {
+ p = p.slice(0, -1) + '.' + pathArr[++i];
+ }
+
+ parts.push(p);
+ }
+
+ cache.set(path, parts);
+ return parts
+ };
+
+ /* ___filename___: dist/deps/dot/dottable.js */
+
+
+
+
+ // const isDot = require('./is/dot')
+ // const isDottable = (obj, path) => isObj(obj) && isDot(path)
+ var dottable = function (obj$$2, path) { return (obj(obj$$2) && string(path)) || array(path); };
+
+ /* ___filename___: dist/deps/dot/segments.js */
+
+ /* ___filename___: dist/deps/dot/dottable.js */
+
+ /* ___filename___: dist/deps/dot/set.js */
+
+
+
+
+
+ var set$2 = function dotset(obj$$2, path, value) {
+ if (!dottable(obj$$2, path)) {
+ return
+ }
+
+ var pathArr = segments(path);
+
+ for (var i = 0; i < pathArr.length; i++) {
+ var p = pathArr[i];
+
+ if (!obj(obj$$2[p])) {
+ obj$$2[p] = {};
+ }
+
+ // isLast
+ if (i === lengthMinusOne(pathArr)) {
+ obj$$2[p] = value;
+ }
+
+ obj$$2 = obj$$2[p];
+ }
+ };
+
+ /* ___filename___: dist/deps/is/error.js */
+
+ /* ___filename___: dist/deps/traversers/copy.js */
+
+
+
+
+
+
+ /* prettier-ignore */
+ /**
+ * @desc copy any primitive value, part of clone
+ * @version 5.0.0
+ * @since 3.0.0
+ * @name copy
+ * @see clone
+ * @memberOf Traverse
+ *
+ * @param {*} src value to copy
+ * @return {*} copied
+ *
+ * @example
+ *
+ * copy(/eh/gmi) //=> new RegExp('eh', 'gmi')
+ * copy(new Error('eh')) // => new Error with copied stack + msg
+ * copy([1]) // => [1]
+ * copy({}) // => {}
+ *
+ */
+ var copy = function copy(src) {
+ if (objNotNull(src)) {
+ var dst;
+
+ // if (isPrimitive(src)) {
+ // if (isNullOrUndefined(src)) {
+ // dst = src
+ // }
+
+ // @TODO @IMPORTANT @FIXME @!IMPORTANT - COVER THIS OR NOT?
+ // for string value number boolean objects...
+ // if (isString(src)) {
+ // dst = src + ''
+ // }
+ // else if (isNumber(src)) {
+ // dst = src + 0
+ // }
+ // else if (isBoolean(src)) {
+ // dst = !!src
+ // }
+ // else
+
+ // lists... <- needs to have dot-prop support on Map/Set
+ // if (isMap(src)) {
+ // dst = new Map()
+ // const obj = reduce(src)
+ // // src.clear()
+ // ObjectKeys(obj).forEach(key => dst.set(key, obj[key]))
+ // return dst
+ // }
+ // else if (isSet(src)) {
+ // dst = new Set()
+ // // could clone here too
+ // const obj = toarr(src)
+ // // src.clear()
+ // obj.forEach(value => dst.add(value))
+ // return dst
+ // }
+
+ // ------
+ if (array(src)) {
+ dst = [];
+ }
+ // was new date(src.getTime())
+ // || isBoolean(src) || isNumber(src) || isString(src)
+ else if (date(src)) {
+ dst = new src.constructor(src.valueOf());
+ }
+ else if (regexp(src)) {
+ // dst = new RegExp(src)
+ dst = new RegExp(src.src, src.toString().match(/[^/]*$/)[0]);
+ dst.lastIndex = src.lastIndex;
+ }
+ else if (error$1(src)) {
+ dst = new Error(src.message);
+ dst.stack = src.stack;
+ }
+ else {
+ dst = Object.create(Object.getPrototypeOf(src));
+ }
+
+ // @TODO: copy descriptor
+ // eslint-disable-next-line
+ for (var prop in src) {
+ dst[prop] = src;
+ // const desc = Object.getOwnPropertyDescriptor(src, prop)
+ // Object.defineProperty(dst, prop, desc)
+ }
+ return dst
+ }
+ else {
+ // require('fliplog').red('is NOT OBJ').echo()
+ return src
+ }
+ };
+
+ /* ___filename___: dist/deps/is/enumerable.js */
+ var enumerable = function (obj, prop) { return Object.prototype.propertyIsEnumerable.call(obj, prop); };
+
+ /* ___filename___: dist/deps/is/enumerable.js */
+
+ /* ___filename___: dist/deps/dot/get.js */
+
+
+
+
+
+
+
+ /**
+ * @name dot.get
+ * @memberOf dot
+ * @func
+ * @since 3.0.0
+ * @extends dot/getPathSegments
+ *
+ * @param {Object} obj the object to retrieve the nested property from.
+ * @param {Dottable | string | Array} path dot-prop-path to use
+ * @param {*} fallback use when there is no value at specified path
+ * @return {*} value at path or fallback
+ *
+ * @example
+ *
+ * dot.get({a: {b: 2}}, 'a.b'); //=> 2
+ * dot.get({a: {b: 2}}, ['a', 'b']); //=> 2
+ * dot.get({c: {b: 2}}, ['a', 'b']); //=> undefined
+ *
+ */
+ var get = function(obj, path, fallback) {
+ if (!dottable(obj, path)) {
+ return _undefined(fallback) ? obj : fallback
+ }
+
+ var pathArr = segments(path);
+
+ for (var i = 0; i < pathArr.length; i++) {
+ if (!enumerable(obj, pathArr[i])) {
+ return fallback
+ }
+
+ obj = obj[pathArr[i]];
+
+ if (nullOrUndefined(obj)) {
+ /*
+ * `obj` is either `undefined` or `null` so we want to stop the loop, and
+ * if this is not the last bit of the path, and
+ * if it did't return `undefined`
+ * it would return `null` if `obj` is `null`
+ * but we want `get({foo: null}, 'foo.bar')` to equal `undefined`, or the supplied fallback, not `null`
+ */
+ if (i !== lengthMinusOne(pathArr)) {
+ return fallback
+ }
+
+ break
+ }
+ }
+
+ return obj
+ };
+
+ /* ___filename___: dist/deps/util/hasOwnProperty.js */
+ var hasOwnProperty_1 = function (haystack, needle) { return Object.prototype.hasOwnProperty.call(haystack, needle); };
+
+ // function(obj, key) {
+ // return key in obj
+ // }
+
+ /* ___filename___: dist/deps/util/hasOwnProperty.js */
+
+ /* ___filename___: dist/deps/traversers/eqValue.js */
+ // conditionals
+ /* eslint complexity: "OFF" */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ // const ENV_DEBUG = require('../env/debug')
+ var ENV_DEBUG$1 = true;
+
+ var isNotRealOrNotEqToString = function (x, y) { return !x || !y || x.toString() !== y.toString(); };
+
+ /* prettier-ignore */
+ /**
+ * @desc checks value equality, used by eq which compares all types
+ * @since 4.1.0
+ * @memberOf Traverse
+ * @protected
+ *
+ * @TODO !!!!!! USE ENUM FLAGS ON LOOSE TO ALLOW MORE CONFIG FOR ==, COMPARATOR, VALUEOF, walk proto (check ownProps...)...
+ *
+ * @param {*} x compare to y
+ * @param {*} y compare to x
+ * @param {boolean | number} [loose=false] use == checks when typof !=
+ * @return {boolean}
+ *
+ * @example
+ *
+ * eqValue(1, 1) //=> true
+ * eqValue('1', 1) //=> false
+ * eqValue('1', 1, true) //=> true
+ * eqValue({}, {}) //=> true
+ *
+ */
+ var eqValue = function eqValue(x, y, loose) {
+ /* istanbul ignore next: dev */
+ if (ENV_DEBUG$1) {
+ console.log('eqValue', {x: x, y: y, loose: loose});
+ }
+
+ // if (x === y) {
+ // if (ENV_DEBUG) {
+ // console.log('===', {x, y})
+ // }
+ // // noop
+ // }
+ // else
+
+ if (nullOrUndefined(x) || nullOrUndefined(y)) {
+ /* istanbul ignore next: dev */
+ if (ENV_DEBUG$1) {
+ console.log('null or undef !=', {x: x, y: y});
+ }
+
+ if (x !== y) {
+ return false
+ }
+ }
+ else if (typeof x !== typeof y) {
+ // eslint-disable-next-line
+ if (_true(loose) && x == y) {
+ // ignore
+ }
+ else {
+ /* istanbul ignore next: dev */
+ if (ENV_DEBUG$1) {
+ console.log('typeof !=', {x: x, y: y});
+ }
+
+ return false
+ }
+ }
+ // @TODO put this up first?
+ else if (toS(x) !== toS(y)) {
+ /* istanbul ignore next: dev */
+ if (ENV_DEBUG$1) {
+ console.log('diff str types', {x: toS(x), y: toS(y)});
+ }
+
+ return false
+ }
+ else if (objNotNull(x)) {
+ // use .equals if the method exists
+ if (hasOwnProperty_1(x, 'equals')) {
+ return x.equals(y)
+ }
+
+ /* istanbul ignore next: dev */
+ if (ENV_DEBUG$1) {
+ console.log('isObjNotNull', {x: x});
+ }
+
+ // if (isArray(x)) {
+ // if (x.length !== y.length) {
+ // return false
+ // }
+ // }
+
+ // @NOTE .toString will be covered for functions and regexes in objStrict
+ if (regexp(x) || regexp(y)) {
+ /* istanbul ignore next: dev */
+ if (ENV_DEBUG$1) {
+ console.log('regexp', {x: x, y: y});
+ }
+
+ if (isNotRealOrNotEqToString(x, y)) {
+ /* istanbul ignore next: dev */
+ if (ENV_DEBUG$1) {
+ console.log('regexp !=', {x: x, y: y});
+ }
+
+ return false
+ }
+ }
+ else if (date(x) || date(y)) {
+ /* istanbul ignore next: dev */
+ if (ENV_DEBUG$1) {
+ console.log('dates', {x: x, y: y});
+ }
+
+ if (!date(x) || !date(y) || x.getTime() !== y.getTime()) {
+ /* istanbul ignore next: dev */
+ if (ENV_DEBUG$1) {
+ console.log('!= dates', {x: x, y: y});
+ }
+
+ return false
+ }
+ }
+ else if (error$1(x) || error$1(y)) {
+ /* istanbul ignore next: dev */
+ if (ENV_DEBUG$1) {
+ console.log('isError', {x: x, y: y});
+ }
+
+ if (!error$1(x) || !error$1(y) || x.stack !== y.stack) {
+ /* istanbul ignore next: dev */
+ if (ENV_DEBUG$1) {
+ console.log('!= errors', {x: x, y: y});
+ }
+
+ return false
+ }
+ }
+ else if (array(x) && !array(y)) {
+ /* istanbul ignore next: dev */
+ if (ENV_DEBUG$1) {
+ console.log('isArray(x) || isArray(y)!');
+ }
+
+ return false
+ }
+ else if (!array(x) && array(y)) {
+ /* istanbul ignore next: dev */
+ if (ENV_DEBUG$1) {
+ console.log('!isArray(x) && isArray(y):');
+ }
+
+ return false
+ }
+
+ // @TODO considering, we already know it is not null & undefined
+ // if (isPrimitive(x) || isPrimitive(y)) {
+ // return x.valueOf() === y.valueOf()
+ // }
+
+ else {
+ // @TODO ObjectOrArrayKeys, but have to have else where they are both array
+ //
+ // @NOTE it will traverse through values if they are == here
+ var xKeys = keys(x);
+ var yKeys = keys(y).length;
+
+ // diff length
+ if (xKeys.length !== yKeys) {
+ /* istanbul ignore next: dev */
+ if (ENV_DEBUG$1) {
+ console.log('!= obj key length', {xKeys: xKeys, yKeys: yKeys});
+ }
+
+ return false
+ }
+
+ for (var k = 0; k < xKeys.length; k++) {
+ if (!hasOwnProperty_1(y, xKeys[k])) {
+ /* istanbul ignore next: dev */
+ if (ENV_DEBUG$1) {
+ console.log('!= obj property', {y: y, val: xKeys[k]});
+ }
+
+ return false
+ }
+ }
+ }
+ }
+ else if (toS(x) === toS(y) && x !== y) {
+ // isString(x) || isBoolean(x) || isNumber(x) || isIterator(x)
+ /* istanbul ignore next: dev */
+ if (ENV_DEBUG$1) {
+ console.log('same str types - diff values', {s: toS(x), x: x, y: y});
+ }
+
+ return false
+ }
+ // // @TODO put this up first?
+ // else if (toS(x) !== toS(y)) {
+ // /* istanbul ignore next: dev */
+ // if (ENV_DEBUG) {
+ // console.log('diff str types', {x: toS(x), y: toS(y)})
+ // }
+ //
+ // return false
+ // }
+
+ // go deeper
+ else if (_function(x) || _function(y)) {
+ /* istanbul ignore next: dev */
+ if (ENV_DEBUG$1) {
+ console.log('isFunction(x) && isFunction(y):');
+ console.log(x.toString());
+ console.log(y.toString());
+ }
+
+ if (isNotRealOrNotEqToString(x, y)) {
+ /* istanbul ignore next: dev */
+ if (ENV_DEBUG$1) {
+ console.log('x.toString() !== y.toString()', x.toString() !== y.toString());
+ }
+ return false
+ }
+ else {
+ return true
+ }
+ }
+ // @TODO why?
+ else if (obj(x) && obj(y)) {
+ /* istanbul ignore next: dev */
+ if (ENV_DEBUG$1) {
+ console.log('isObj(x) && isObj(y):');
+ }
+
+ return false
+ }
+ // else {
+ /* istanbul ignore next: dev */
+ if (ENV_DEBUG$1) {
+ console.log('eqeqeq:', {[toS(x) + 'X']: x, [toS(y) + 'Y']: y});
+ }
+ return true
+ // }
+ };
+
+ /* ___filename___: dist/deps/dot/get.js */
+
+ /* ___filename___: dist/deps/is/empty.js */
+
+ /* ___filename___: dist/deps/env/debug.js */
+
+ /* ___filename___: dist/deps/traversers/eqValue.js */
+
+ /* ___filename___: dist/deps/traversers/_eq.js */
+ // conditionals
+ /* eslint complexity: "OFF" */
+
+ // const traverse = require('../traverse')
+
+
+
+
+
+
+
+ /* prettier-ignore */
+ /**
+ * @name eq
+ * @since 3.0.0
+ * @version 5.0.0
+ * @memberOf Traverse
+ *
+ * @see https://github.com/facebook/immutable-js/blob/master/src/utils/deepEqual.js
+ * @see https://github.com/substack/node-deep-equal
+ * @see http://ramdajs.com/docs/#equals
+ * @see https://lodash.com/docs/4.17.4#isEqual
+ * @see https://github.com/angular/angular.js/blob/master/src/Angular.js
+ *
+ * @param {Traverse} traverse traversejs
+ * @param {*} a compare to b
+ * @param {*} b compare to a
+ * @param {boolean} [loose] compare loosely
+ * @param {boolean} [scoped] doing a second pass, private
+ * @return {boolean} isEqual
+ *
+ * @extends eqValue
+ *
+ * @example
+ *
+ * eq(1, 1) //=> true
+ * eq(1, '1') //=> false
+ * eq(1, '1', true) //=> true
+ * eq([1], [1]) //=> true
+ *
+ */
+ var _eq = function (traverse) { return function eq(a, b, loose, stackA, stackB) {
+ if ( stackA === void 0 ) stackA = [];
+ if ( stackB === void 0 ) stackB = [];
+
+ /* istanbul ignore next: dev */
+ if (debug) {
+ console.log('\n');
+ }
+
+ var equal = true;
+ var node = b;
+ var nodes = [node];
+
+ var instance = traverse(a);
+
+ var notEqual = function () {
+ equal = false;
+ instance.stop();
+ };
+
+ /* istanbul ignore next: dev */
+ if (debug) {
+ console.log('eq?');
+ }
+
+ instance.forEach(function(key, y, traverser) {
+ // @NOTE do base comparisons on values that are not actually iteratable
+ // aka, .isRoot
+ if (_null(key)) {
+ // always-valid state opionion vs always-invalid
+ // so it only returns false when it is !== fosho
+ if (eqValue(node, y, loose) === false) { return notEqual() }
+ else { return }
+ }
+
+ /* istanbul ignore next: dev */
+ if (debug) {
+ console.log('eq: iterating:');
+ }
+
+ // could use it as a fallback if undefined && y !== undefined
+ // const xyz = get(b, traverser.path.join('.'), b)
+
+ var x = node;
+
+ // isNotLeafAndIsObj
+ if (objNotNull(node) && !empty(node)) {
+ /* istanbul ignore next: dev */
+ if (debug) {
+ console.log('is leaf, is not empty node, going deeper');
+ }
+
+ // so x is our current one,
+ // if node is not empty, use the key, push the value
+ // and when it is empty, and it is not a leaf but has nodes, pop back up
+ x = node[key];
+ nodes.push(x);
+ }
+
+ // ENV_DEBUG
+ // console.log({[key]: {x, xyz, y, nodes, path: traverser.path.join('.')}})
+
+ // for next loop!!!
+ if (!this.isLeaf && !empty(nodes)) {
+ /* istanbul ignore next: dev */
+ if (debug) {
+ console.log('is not leaf, has nodes stack, pop');
+ }
+ node = nodes.pop();
+ }
+
+ /* istanbul ignore next: dev */
+ if (debug) {
+ console.log({key: key, y: y, x: x, a: a, b: b});
+ }
+
+ var eqv = eqValue(x, y, loose);
+
+ /* istanbul ignore next: dev */
+ if (debug) {
+ console.log({eqv: eqv});
+ }
+
+ if (eqv === false) {
+ // equal
+ notEqual();
+ }
+ });
+
+ // cleanup
+ nodes = undefined;
+ node = undefined;
+
+ return equal
+ }; };
+
+ /* ___filename___: dist/deps/cache/pooler.js */
+ /* eslint consistent-this: ["error", "Klass"] */
+
+
+
+ /**
+ * @symb 🎱
+ * @member pooler
+ * @type {Object}
+ */
+ // const pooler = }}
+
+ /**
+ * @desc call destructor on a pooled instance, put it back in the pool
+ * @since 5.0.0
+ * @memberOf pooler
+ *
+ * @param {Object} instance call destructor
+ * @return {void}
+ *
+ * @example
+ *
+ * class Eh {}
+ * addPoolingTo(Eh)
+ * const eh = Eh.getPooled()
+ * eh.release()
+ *
+ */
+ function standardReleaser(instance) {
+ var Klass = this;
+
+ if (debug) {
+ if (instance instanceof Klass) {
+ throw new Error(
+ "Trying to release an instance\n into a pool of a different type."
+ )
+ }
+ }
+
+ instance.destructor();
+ if (Klass.instancePool.length < Klass.poolSize) {
+ Klass.instancePool.push(instance);
+ }
+ }
+
+ /**
+ * Static poolers. Several custom versions for each potential number of
+ * arguments. A completely generic pooler is easy to implement, but would
+ * require accessing the `arguments` object. In each of these, `this` refers to
+ * the Class itself, not an instance. If any others are needed, simply add them
+ * here, or in their own files.
+ *
+ * @since 5.0.0
+ * @memberOf pooler
+ *
+ * @param {Object} copyFieldsFrom obj with instance pool
+ * @return {Object} instance of Klass
+ *
+ * @example
+ *
+ * class Eh {}
+ * addPoolingTo(Eh)
+ * const eh = Eh.getPooled() //=> oneArgumentPooler(Eh)
+ * eh.release()
+ *
+ */
+ function oneArgumentPooler(copyFieldsFrom) {
+ var Klass = this;
+ if (Klass.instancePool.length) {
+ var instance = Klass.instancePool.pop();
+ Klass.call(instance, copyFieldsFrom);
+ return instance
+ }
+ else {
+ return new Klass(copyFieldsFrom)
+ }
+ }
+
+ var DEFAULT_POOL_SIZE = 10;
+ var DEFAULT_POOLER = oneArgumentPooler;
+
+ /**
+ * Augments `CopyConstructor` to be a poolable class, augmenting only the class
+ * itself (statically) not adding any prototypical fields. Any CopyConstructor
+ * you give this may have a `poolSize` property, and will look for a
+ * prototypical `destructor` on instances.
+ *
+ * @since 5.0.0
+ * @memberOf pooler
+ *
+ * @param {Function | Object} CopyConstructor Constructor that can be used to reset.
+ * @param {Function} pooler Customizable pooler.
+ * @return {Object} enhanced constructor, decorated with pooler
+ *
+ * @example
+ *
+ * class Eh {}
+ * addPoolingTo(Eh) // can optionally pass in pooler as second arg
+ * //=> Eh.instancePool = []
+ * //=> Eh.getPooled = pooler || singleArgumentPooler
+ * //=> Eh.poolSize = 10
+ * //=> Eh.release = standardReleaser
+ *
+ */
+ function addPoolingTo(CopyConstructor, pooler) {
+ // Casting as any so that flow ignores the actual implementation and trusts
+ // it to match the type we declared
+ var NewKlass = CopyConstructor;
+
+ NewKlass.instancePool = [];
+ NewKlass.getPooled = pooler || DEFAULT_POOLER;
+ if (!NewKlass.poolSize) { NewKlass.poolSize = DEFAULT_POOL_SIZE; }
+ NewKlass.release = standardReleaser;
+
+ return NewKlass
+ }
+
+ var pooler = addPoolingTo;
+
+ /* ___filename___: dist/deps/is/symbol.js */
+
+ /* ___filename___: dist/deps/is/asyncish.js */
+
+ /* ___filename___: dist/deps/is/primitive.js */
+
+ /* ___filename___: dist/deps/dot/set.js */
+
+ /* ___filename___: dist/deps/traversers/copy.js */
+
+ /* ___filename___: dist/deps/traversers/_eq.js */
+
+ /* ___filename___: dist/deps/cache/pooler.js */
+
+ /* ___filename___: dist/deps/traverse.js */
+ // conditionals
+ /* eslint complexity: "OFF" */
+
+ // inlined rollup
+ /* eslint import/max-dependencies: "OFF" */
+
+ // one file
+ /* eslint max-lines: "OFF" */
+
+ // debug conditionals
+ /* eslint max-depth: "OFF" */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ // const props = require('./util/props')
+
+ // const ENV_DEBUG = require('./env/debug')
+ // const ENV_DEBUG = true
+ var ENV_DEBUG = false;
+
+ function isIteratable(node) {
+ // ez ones
+ if (obj(node) || array(node)) { return true }
+
+ var notIteratable =
+ primitive$2(node) ||
+ regexp(node) ||
+ date(node) ||
+ symbol(node) ||
+ asyncish(node) ||
+ // isNative(node) ||
+ error$1(node);
+
+ if (notIteratable) { return false }
+ else { return true }
+
+ // if (isNullOrUndefined(node)) {
+ // }
+ // else if (isString(node)) {
+ // }
+ // else if (isNumber(node)) {
+ // }
+ // else if (isBoolean(node)) {
+ // }
+ // else if (isRegExp(node)) {
+ // }
+ // else if (isDate(node)) {
+ // }
+ // else if (isSymbol(node) || isAsyncish(node)) {
+ // }
+ // else if (isNative(node)) {
+ // }
+ // else {
+ // return true
+ // }
+ // return false
+ }
+
+ // function isSpecial(x) {
+ // // isPromise(x) ||
+ // return isSymbol(x) || isError(x) ||
+ // // || isGenerator(x)
+ // }
+
+ /**
+ * {@link https://github.com/wmira/object-traverse/blob/master/index.js }
+ * {@link https://www.npmjs.com/browse/keyword/traverse }
+ * {@link https://www.npmjs.com/package/tree-walk }
+ * {@link https://www.npmjs.com/package/1tree }
+ * {@link https://www.npmjs.com/package/pathway }
+ * {@link https://www.npmjs.com/package/@mojule/tree }
+ *
+ * --------------------
+ *
+ * if needed, clone
+ *
+ * first things to check are number/string/boolean/null/undefined
+ *
+ * then check non-iteratables
+ * symbol, promise,
+ *
+ * then check conversions
+ * - map, set
+ *
+ * then check empties
+ * - obj
+ * - fn
+ *
+ * -------
+ *
+ * numbers f-or first/last
+ * and as a sort of hash like
+ * 1 + 2 + 4 = ISLEAF & ISROOT ?
+ *
+ * Array
+ *
+ * Object Function Date Error Map Set
+ *
+ * String
+ * Number NaN Infinity
+ * Boolean
+ *
+ *
+ * null undefined
+ *
+ * Promise Symbol
+ *
+ * ----
+ *
+ * @emits before
+ * @emits pre
+ * @emits post
+ * @emits after
+ */
+
+ /**
+ * @class
+ * @desc Traverse class, pooled
+ * @alias IterAteOr
+ * @member Traverse
+ * @constructor
+ * @since 5.0.0
+ *
+ * @param {Traversable} iteratee value to iterate, clone, copy, check for eq
+ * @param {Object | undefined} [config] wip config for things such as events or configs
+ *
+ * @extends pooler
+ * @see traverse
+ * @TODO make this a trie OR a linked-list
+ *
+ * @example
+ *
+ * new Traverse([1])
+ * new Traverse([], {})
+ *
+ */
+ function Traverse(iteratee, config) {
+ // always cleared when done anyway
+ this.parents = new Set();
+
+ this.iteratee = iteratee;
+ this.parent = iteratee;
+ this.root = iteratee;
+ this.reset();
+
+ // to pass in the events (as commented below) without messing up scope?
+ // if (config.on) this.on = config.on
+ return this
+ }
+
+ Traverse.prototype.reset = function() {
+ this.path = [];
+ this.key = undefined;
+ this.isAlive = true;
+ this.isCircular = false;
+ this.isLeaf = false;
+ this.isRoot = true;
+
+ // iterates +1 so start at 0
+ this.depth = -1;
+ };
+
+ /**
+ * @desc find parent,
+ * is there a parent
+ * above the current depth
+ * with the same value,
+ * making it circular?
+ *
+ * @memberOf Traverse
+ * @since 5.0.0
+ * @private
+ *
+ * @param {number} depth current depth, to find parent >=
+ * @param {parent} value parent value to find
+ * @return {boolean} hasParent
+ *
+ * @example
+ *
+ * var obj = {eh: ['eh']}
+ * traverse(obj).addParent(0, obj)
+ *
+ */
+ Traverse.prototype.hasParent = function(depth, value) {
+ // or array
+ if (!obj(value)) { return false }
+ return this.parents.has(value)
+ };
+
+ /**
+ * @desc add parent, to prevent circular iterations
+ * @memberOf Traverse
+ * @since 5.0.0
+ * @private
+ *
+ * @param {number} depth current depth, to add parent to >=
+ * @param {parent} value parent value to add
+ * @return {void}
+ *
+ * @example
+ *
+ * var obj = {eh: ['eh']}
+ * traverse(obj).addParent(0, obj)
+ *
+ */
+ Traverse.prototype.addParent = function(depth, value) {
+ if (!obj(value)) { return }
+ if (this.parents.size >= 100) { this.clear(); }
+ this.parents.add(value);
+ };
+
+ /**
+ * @desc remove all parents, reset the map
+ *
+ * @memberOf Traverse
+ * @since 5.0.0
+ * @private
+ *
+ * @return {void}
+ *
+ * @example
+ *
+ * var obj = {eh: ['eh']}
+ * traverse(obj).forEach((key, value, t) => {
+ * t.parents
+ * //=> Set([obj])
+ * t.clear()
+ * t.parents
+ * //=> Set[]
+ * })
+ *
+ */
+ Traverse.prototype.clear = function() {
+ if (!_undefined(this.parents)) { this.parents.clear(); }
+ };
+
+ /**
+ * @memberOf Traverse
+ * @since 5.0.0
+ * @private
+ *
+ * @param {number} depth current depth, to find parents >=
+ * @param {parent} value parent value to remove
+ * @return {void}
+ *
+ * @example
+ *
+ * var obj = {eh: ['eh']}
+ * traverse(obj).removeParent(0, obj)
+ *
+ */
+ Traverse.prototype.removeParent = function(depth, value) {
+ this.parents.delete(value);
+ };
+
+ /**
+ * @desc this is the main usage of Traverse
+ * @memberOf Traverse
+ * @since 3.0.0
+ * @version 5.0.0
+ *
+ * @param {Function} cb callback for each iteration
+ * @return {*} mapped result or original value, depends how it is used
+ *
+ * @example
+ *
+ * traverse([1, 2, 3]).forEach((key, value) => console.log({[key]: value}))
+ * //=> {'0': 1}
+ * //=> {'1': 2}
+ * //=> {'2': 3}
+ *
+ */
+ Traverse.prototype.forEach = function iterateForEach(cb) {
+ /* istanbul ignore next: dev */
+ if (ENV_DEBUG) {
+ console.log('\n forEach \n');
+ }
+
+ var result = this.iterate(cb);
+
+ // TODO: HERE, WHEN THIS IS ADDED, CAN BREAK SOME TESTS? SCOPED PARENTS MAP?
+ Traverse.release(this);
+
+ return result
+ };
+
+ /**
+ * @desc stop the iteration
+ * @modifies this.isAlive = false
+ * @memberOf Traverse
+ *
+ * @return {void}
+ *
+ * @example
+ *
+ * traverse({eh: true, arr: []}).forEach((key, val, t) => {
+ * if (isArray(val)) this.stop()
+ * })
+ *
+ */
+ Traverse.prototype.stop = function stop() {
+ this.isAlive = false;
+ // this.release()
+ };
+
+ /**
+ * @TODO skip 1 branch
+ * @version 5.0.0
+ * @since 3.0.0
+ * @memberOf Traverse
+ *
+ * @return {void}
+ *
+ * @example
+ *
+ * traverse([1, 2, 3, [4]]).forEach((key, val, t) => {
+ * if (isArray(val)) t.skip()
+ * })
+ *
+ */
+ Traverse.prototype.skip = function skip() {
+ this.skipBranch = true;
+ };
+
+ /* prettier-ignore */
+ /**
+ * @TODO move into the wrapper? if perf allows?
+ *
+ * @desc checks whether a node is iteratable
+ * @modifies this.isIteratable
+ * @modifies this.isLeaf
+ * @modifies this.isCircular
+ *
+ * @memberOf Traverse
+ * @protected
+ *
+ * @param {*} node value to check
+ * @return {void}
+ *
+ * @example
+ *
+ * .checkIteratable({eh: true})
+ * //=> this.isLeaf = false
+ * //=> this.isCircular = false
+ * //=> this.isIteratable = true
+ *
+ * .checkIteratable({} || [])
+ * //=> this.isLeaf = true
+ * //=> this.isCircular = false
+ * //=> this.isIteratable = false
+ *
+ * var circular = {}
+ * circular.circular = circular
+ * .checkIteratable(circular)
+ * //=> this.isLeaf = false
+ * //=> this.isCircular = true
+ * //=> this.isIteratable = true
+ *
+ */
+ Traverse.prototype.checkIteratable = function check(node) {
+ this.isIteratable = isIteratable(node);
+ // just put these as an array?
+ if (_true(this.isIteratable)) {
+ // native = leaf if not root
+ this.isLeaf = false;
+ var path = this.path.join('.');
+
+
+ if (this.hasParent(path, node)) {
+ /* istanbul ignore next: dev */
+ if (ENV_DEBUG) {
+ console.log('circular___________', {node: node, path: this.path});
+ }
+ this.isCircular = true;
+ }
+ else {
+ this.addParent(path, node);
+ this.isCircular = false;
+ }
+
+ /* istanbul ignore next: dev */
+ if (ENV_DEBUG) {
+ // console.log('IS_CIRCULAR_JSON', isCircular(node), this.isCircular, node)
+ }
+ }
+ else {
+ // ---
+ this.isLeaf = true;
+ this.isCircular = false;
+ }
+ };
+
+ /* prettier-ignore */
+ /**
+ * Remove the current element from the output.
+ * If the node is in an Array it will be spliced off.
+ * Otherwise it will be deleted from its parent.
+ *
+ * @memberOf Traverse
+ * @version 5.0.0
+ * @since 2.0.0
+ *
+ * @param {undefined | Object} [arg] optional obj to use, defaults to this.iteratee
+ * @return {void}
+ *
+ * @example
+ *
+ * traverse([0]).forEach((key, val, it) => it.remove())
+ * //=> []
+ *
+ * traverse({eh: true}).forEach((key, val, it) => it.remove())
+ * //=> {}
+ *
+ * traverse({eh: true, str: 'stringy'}).forEach((key, val, it) => {
+ * if (!isString(val)) it.remove()
+ * })
+ * //=> {str: 'stringy'}
+ *
+ */
+ Traverse.prototype.remove = function removes(arg) {
+ if (_undefined(this.key)) { return }
+
+ var obj$$2 = arg || this.iteratee;
+
+ if (!obj(obj$$2)) { return }
+
+ /* istanbul ignore next: dev */
+ if (ENV_DEBUG) {
+ console.log('remove');
+ console.log({parent: this.parent, key: this.key, obj: obj$$2});
+ }
+
+ this.removeParent(obj$$2);
+
+ this.skip();
+
+ delete obj$$2[this.key];
+ delete this.parent[this.key];
+ // if (isObj(obj)) deleteFromObjOrArray(obj, this.key)
+ // else deleteFromObjOrArray(this.parent, this.key)
+ // deleteFromObjOrArray(this.parent, this.key)
+ // deleteFromObjOrArray(this.iteratee, this.key)
+
+ // if (isUndefined(obj)) {
+ // // throw new Error('why?')
+ // }
+ // else if (isArray(obj)) {
+ // /* istanbul ignore next: dev */
+ // if (ENV_DEBUG) {
+ // console.log('traverse:remove:array', obj, this.key)
+ // }
+ //
+ // obj.splice(this.key, 1)
+ // }
+ // else if (isObjNotNull(obj)) {
+ // /* istanbul ignore next: dev */
+ // if (ENV_DEBUG) {
+ // console.log('traverse:remove:obj', this.key)
+ // }
+ //
+ // delete obj[this.key]
+ // }
+ //
+ // if (isObjNotNull(this.parent)) {
+ // delete this.parent[this.key]
+ //
+ // /* istanbul ignore next: dev */
+ // if (ENV_DEBUG) {
+ // console.log('traverse:remove:parent', this.key)
+ // }
+ // }
+ // if (isObjNotNull(this.iteratee)) {
+ // delete this.iteratee[this.key]
+ //
+ // /* istanbul ignore next: dev */
+ // if (ENV_DEBUG) {
+ // console.log('traverse:remove:iteratee', this.key)
+ // }
+ // }
+
+ /* istanbul ignore next: dev */
+ if (ENV_DEBUG) {
+ console.log('traverse:remove:', this.key, {obj: obj$$2, iteratee: this.iteratee});
+ }
+ };
+
+ /**
+ * @desc update the value for the current key
+ * @version 5.0.0
+ * @since 2.0.0
+ * @memberOf Traverse
+ *
+ * @param {*} value this.iteratee[this.key] = value
+ * @return {void}
+ *
+ * @example
+ *
+ * traverse({eh: true})
+ * .forEach((key, val, traverser) => {
+ * if (this.isRoot) return
+ * traverser.update(false)
+ * })
+ * //=> {eh: false}
+ *
+ */
+ Traverse.prototype.update = function update(value) {
+ set$2(this.root, this.path, value);
+ };
+
+ /**
+ * @desc mark the iteration as done, clear the map
+ * @NOTE this recycles the instance in the pooler to re-use allocated objects
+ * @memberOf Traverse
+ * @private
+ * @since 5.0.0
+ *
+ * @return {void}
+ *
+ * @see Traverse.iterate
+ *
+ * @example
+ *
+ * traverse([]).destructor()
+ *
+ */
+ Traverse.prototype.destructor = function destructor() {
+ this.iteratee = undefined;
+ this.parent = undefined;
+ this.reset();
+
+ this.clear();
+ };
+
+ /* prettier-ignore */
+ /**
+ * @TODO handler for Set & Map so they can be skipped or traversed, for example when cloning...
+ * @TODO add hook to add custom checking if isIteratable
+ * @TODO deal with .isRoot if needed
+ * @TODO examples with clone and stop
+ *
+ * @memberOf Traverse
+ * @protected
+ * @sig on(key: null | Primitive, val: any, instance: Traverse): any
+ *
+ * @param {Function} on callback fn for each iteration
+ * @return {*} this.iteratee
+ *
+ * @example
+ *
+ * iterate([])
+ * //=> []
+ * //=> on(null, [])
+ *
+ * @example
+ *
+ * iterate([1])
+ * //=> [1]
+ * //=> on(null, [1])
+ * //=> on('1', 1)
+ *
+ * @example
+ *
+ * //primitive - same for any number, string, symbol, null, undefined
+ * iterate(Symbol('eh'))
+ * //=> Symbol('eh')
+ * //=> on(Symbol('eh'))
+ *
+ * @example
+ *
+ * var deeper = {eh: 'canada', arr: [{moose: true}, 0]}
+ * iterate(deeper)
+ * //=> deeper // returns
+ * //=> on(null, deeper, this) // root
+ *
+ * //=> on('eh', 'canada', this) // 1st branch
+ *
+ * //=> on('arr', [{moose: true}, 0], this)
+ * //=> on('arr.0', [{moose: true}], this)
+ * //=> on('arr.0.moose', true, this)
+ * //=> on('arr.1', [0], this)
+ *
+ *
+ */
+ Traverse.prototype.iterate = function iterate(on) {
+ var this$1 = this;
+
+ /* istanbul ignore next : dev */
+ if (ENV_DEBUG) {
+ // require('fliplog')
+ // .bold(this.path.join('.'))
+ // .data(parents.keys())
+ // .echo()
+ console.log('\n...iterate...\n');
+ }
+
+ if (this.isAlive === false) {
+ /* istanbul ignore next : dev */
+ if (ENV_DEBUG) {
+ console.log('DEAD');
+ }
+
+ return Traverse.release(this)
+ }
+
+ var node = this.iteratee;
+
+ // convert to iteratable
+ if (map(node)) {
+ node = index$6(node);
+ }
+ else if (set(node)) {
+ node = toArr(node);
+ }
+
+ // @TODO: maybe only right before sub-loop
+ this.addParent(this.depth, node);
+
+ var nodeIsArray = array(node);
+ var nodeIsObj = nodeIsArray || obj(node);
+
+ // ---
+
+ // @event
+ if (!_undefined(this.onBefore)) {
+ // eslint-disable-next-line no-useless-call
+ this.onBefore(this);
+ }
+
+ /* istanbul ignore next : dev */
+ if (ENV_DEBUG) {
+ // const str = require('pretty-format')({nodeIsObj, nodeIsArray, node})
+ // require('fliplog').verbose(1).data({nodeIsObj, nodeIsArray, node}).echo()
+ // console.log(node, parents)
+ // console.log(str)
+ console.log({nodeIsObj: nodeIsObj, nodeIsArray: nodeIsArray, node: node});
+ }
+
+ /**
+ * call as root, helpful when we
+ * - iterate something with no keys
+ * - iterate a non-iteratable (symbol, error, native, promise, etc)
+ */
+ if (_true(this.isRoot)) {
+ on.call(this, null, node, this);
+ this.isRoot = false;
+ }
+
+ var isObjOrArray = nodeIsArray || nodeIsObj;
+
+ // if (isObjOrArray) {
+ // // @event
+ // if (!isUndefined(this.onBefore)) {
+ // // eslint-disable-next-line no-useless-call
+ // this.onBefore(this)
+ // }
+ // }
+
+ // --------------------
+ // IF OBJWITHOUTKEYS, IF ARRAY WITHOUT LENGTH...
+ if (isObjOrArray && empty(node)) {
+ on.call(this, this.key, node, this);
+ this.iteratee = node;
+ }
+
+ // --------------------
+
+ else if (isObjOrArray) {
+ this.depth = this.path.length;
+
+ // @TODO SAFETY WITH `props(node)` <- fixes Error
+ var keys$$2 = nodeIsArray ? node : keys(node);
+
+ /* istanbul ignore next : dev */
+ if (ENV_DEBUG) {
+ console.log({keys: keys$$2});
+ // require('fliplog').verbose(1).data(this).echo()
+ }
+
+ // @event
+ // if (!isUndefined(this.onBefore)) this.onBefore()
+
+ // @NOTE: safety here
+ // this.checkIteratable(node)
+
+ // const last = keys[keys.length - 1]
+
+ // @loop
+ for (var key = 0; key < keys$$2.length; key++) {
+ // if (ENV_DEBUG)
+ // console.log('iterating:', {key})
+
+ // --- safety ---
+ if (this$1.isAlive === false) {
+ /* istanbul ignore next : dev */
+ if (ENV_DEBUG) {
+ console.log('DEAD');
+ }
+
+ return Traverse.release(this$1)
+ }
+
+ // @NOTE: look above add prev add parent
+ // addParent(this.depth, node)
+
+
+ // ----- setup our data ----
+
+ // to make it deletable
+ if (node !== this$1.iteratee) { this$1.parent = node; }
+
+ this$1.key = nodeIsArray ? key : keys$$2[key];
+ // this.isLast = key === last
+
+ /* istanbul ignore next: dev */
+ if (ENV_DEBUG) {
+ console.log('alive', this$1.key);
+ }
+
+ // @event
+ if (!_undefined(this$1.onPre)) {
+ // eslint-disable-next-line no-useless-call
+ this$1.onPre(this$1);
+ }
+
+
+ var value = node[this$1.key];
+
+ this$1.checkIteratable(value);
+ // addParent(value)
+ var pathBeforeNesting = this$1.path.slice(0);
+
+ // @NOTE: can go forward-backwards if this is after the nested iterating
+ this$1.path.push(this$1.key);
+ this$1.depth = this$1.path.length;
+
+ // ----- continue events, loop deeper when needed ----
+
+ // @NOTE since we check isAlive at the beginning of each loop
+ // could use .skip alongisde .stop
+ // @TODO @IMPORTANT @HACK @FIXME right here it should also handle the .stop
+ on.call(this$1, this$1.key, value, this$1);
+ if (_true(this$1.skipBranch)) {
+ this$1.skipBranch = false;
+ continue
+ }
+
+ /* istanbul ignore next: dev */
+ if (ENV_DEBUG) {
+ // require('fliplog').data(parents).echo()
+ // require('fliplog').data(this).echo()
+ }
+
+ // handle data
+ if (_true(this$1.isCircular)) {
+ /* istanbul ignore next: dev */
+ if (ENV_DEBUG) {
+ console.log('(((circular)))', this$1.key);
+ }
+
+ // on.call(this, this.key, value, this)
+ // this.path.pop()
+ this$1.path = pathBeforeNesting;
+
+ // this.isCircular = false
+ // break
+ continue
+ // return
+ }
+
+
+ // &&
+ if (_true(this$1.isIteratable)) {
+ /* istanbul ignore next: dev */
+ if (ENV_DEBUG) {
+ console.log('(((iteratable)))', this$1.key);
+ }
+
+ this$1.iteratee = value;
+ this$1.iterate(on);
+ this$1.path = pathBeforeNesting;
+ }
+
+ /* istanbul ignore next: dev */
+ if (ENV_DEBUG) {
+ if (this$1.isIteratable === false) {
+ console.log('not iteratable', this$1.key);
+ }
+
+ console.log('----------------- post ----------', node);
+ }
+
+ // @event
+ if (!_undefined(this$1.onPost)) {
+ // eslint-disable-next-line no-useless-call
+ this$1.onPost(this$1);
+ }
+
+ // cleanup, backup 1 level
+ this$1.path.pop();
+
+ this$1.removeParent(node);
+ }
+
+ // this.path.pop()
+ this.depth = this.path.length;
+ }
+ else {
+ // this.isLast = false
+ on.call(this, this.depth, node, this);
+ }
+
+ // @NOTE: careful
+ // removeParent(node)
+
+ // @NOTE: just for .after ?
+ this.iteratee = node;
+
+ // @event
+ if (!_undefined(this.onAfter)) {
+ // eslint-disable-next-line no-useless-call
+ this.onAfter(this);
+ }
+
+ this.path.pop();
+
+ return this.iteratee
+ };
+
+ // is smaller, but probably slower
+ // function onEvent(property) {
+ // return function(fn) {
+ // this[property] = function
+ // }
+ // }
+
+ // when it's some sort of itertable object, loop it further
+ // @TODO: need to handle these better without totally messing with bad scope
+ Traverse.prototype.pre = function(fn) {
+ this.onPre = fn;
+ };
+ Traverse.prototype.post = function(fn) {
+ this.onPost = fn;
+ };
+ Traverse.prototype.before = function(fn) {
+ this.onBefore = fn;
+ };
+ Traverse.prototype.after = function(fn) {
+ this.onAfter = fn;
+ };
+
+ // -----------------------
+
+ /**
+ * @TODO merge with dopemerge?
+ * @TODO needs tests converted back for this (observe tests do cover somewhat)
+ *
+ * @param {*} arg defaults to this.iteratee
+ * @return {*} cloned
+ *
+ * @example
+ *
+ * var obj = {}
+ * var cloned = traverse().clone(obj)
+ * obj.eh = true
+ * eq(obj, cloned)
+ * //=> false
+ *
+ */
+ Traverse.prototype.clone = clone;
+
+ /**
+ * @todo ugh, how to clone better with *recursive* objects?
+ * @param {any} src wip
+ * @return {any} wip
+ */
+ Traverse.prototype.copy = copy;
+
+ /**
+ * @desc clone any value
+ * @version 5.0.0
+ * @since 4.0.0
+ * @memberOf Traverse
+ * @extends copy
+ * @extends Traverse
+ *
+ * @param {*} arg argument to clone
+ * @return {*} cloned value
+ *
+ * @see dopemerge
+ * @example
+ *
+ * var obj = {eh: true}
+ * clone(obj) === obj //=> false
+ *
+ * var obj = {eh: true}
+ * var obj2 = clone(obj)
+ * obj.eh = false
+ * console.log(obj2.eh) //=> true
+ *
+ */
+ function clone(arg) {
+ var obj$$2 = _undefined(arg) ? this.iteratee : arg;
+ if (primitive$2(obj$$2)) { return obj$$2 }
+ var cloned = emptyTarget(obj$$2);
+ var current = cloned;
+
+ traverse(obj$$2).forEach(function (key, value, traverser) {
+ // t.isRoot
+ if (_null(key)) { return }
+
+ var copied = copy(value);
+ if (traverser.isCircular && array(value)) { copied = value.slice(0); }
+ set$2(current, traverser.path, copied);
+
+ // current[key] = traverser.copy(value)
+ // if (isObj(value)) current = current[key]
+ });
+
+ return cloned
+ }
+
+ // @TODO could just have traverse = Traverse.getPooled ?
+ pooler(Traverse);
+ function traverse(value) {
+ return Traverse.getPooled(value)
+ }
+
+ var traverse_1 = traverse;
+ var eq_1 = _eq(traverse);
+ var clone_1 = clone;
+ var copy_1 = copy;
+
+
+
+ traverse_1.eq = eq_1;
+ traverse_1.clone = clone_1;
+ traverse_1.copy = copy_1;
+
+ var index$10 = new Map();
+
+ /* ___filename___: dist/deps/traverse.js */
+
+ /* ___filename___: dist/deps/dot/paths.js */
+
+
+
+
+
+
+ var run = 0;
+
+ /* prettier-ignore */
+ /**
+ * @desc gathers dot.prop from any value, with a prefixed/base key
+ * @since 4.0.0
+ *
+ * @param {Primitive} key prefixing key for the paths, root path/key
+ * @param {Traversable} value traversable value to extract paths from
+ * @param {boolean | undefined} [longest] optionally filter to keep only longest/deepest paths
+ * @return {Array} paths[]
+ *
+ * @see deps/traverse
+ * @TODO should build a trie if doing this
+ * @NOTE had `onlyLongest` & `asString` but can just .join(',') to match
+ *
+ * @example
+ *
+ * dotPropPaths('', {oh: {eh: true}})
+ * //=> ['oh.eh']
+ *
+ * dotPropPaths('moose', {oh: {eh: true}})
+ * //=> ['moose.oh.eh']
+ *
+ */
+ var paths = function(key, value, longest) {
+ // if (cache.has(value)) return cache.get(value)
+
+ var paths = [];
+
+ /* istanbul ignore next: debug */
+ if (debug) {
+ console.log({value: value});
+ }
+
+ // gather all paths in the object
+ // filter to ensure only the longest paths are kept
+ //
+ // .map the paths to `dot-prop`,
+ // `matcher` takes in an array so it will work for all
+ traverse_1(value).forEach(function(x) {
+ // const currentPath = this.paths
+ var currentPath = this.path;
+
+ /* istanbul ignore next: debug */
+ if (debug) {
+ console.log('paths', run++, this.path);
+ }
+
+ // ignore
+ if (!currentPath) { return }
+ else if (!currentPath.length) { return }
+
+ // dot-prop the array of paths
+ // if we have a key, prefix it
+ paths.push(
+ (key ? key + '.' : '') +
+ (currentPath.join ? currentPath.join('.') : currentPath)
+ );
+ });
+
+ if (_true(longest)) {
+ // concat a string of all paths so we can unique each branch
+ // @example `canada.arr.0` vs `canada.arr`
+ paths = paths.filter(function (path) { return !paths.some(function (otherPath) { return otherPath !== path && index$4(otherPath, path); }
+ ); });
+ }
+
+ // cache.set(value, paths)
+
+ return paths
+ };
+
+ /* ___filename___: dist/deps/is/number.js */
+
+
+
+ /**
+ * @param {*} x value
+ * @return {boolean} isNumber
+ *
+ * @since 3.0.0
+ * @memberOf is
+ * @func isNumber
+ * @see is/real
+ * @extends numberPrimitive
+ * @variation also returns true for new Number object
+ *
+ * @see http://stackoverflow.com/questions/18082/validate-decimal-numbers-in-javascript-isnumeric
+ * @alternate !isNaN(parseFloat(n)) && isFinite(n)
+ *
+ * @example
+ *
+ * isNumber(1)
+ * //=> true
+ * isNumber(new Number(1))
+ * //=> true
+ * isNumber(Number(1))
+ * //=> true
+ * isNumber(NaN)
+ * //=> true
+ *
+ * isNumber(null)
+ * //=> false
+ * isNumber(undefined)
+ * //=> false
+ * isNumber(void 0)
+ * //=> false
+ * isNumber({})
+ * //=> false
+ * isNumber('')
+ * //=> false
+ * isNumber(false)
+ * //=> false
+ *
+ * @NOTE was not needed except for abstract ==
+ * const isObj = require('./obj')
+ * const isSymbol = require('./symbol')
+ * (isObj(x) || isSymbol(x)
+ * ? false
+ * : (/^0x[0-9a-f]+$/i).test(x) ||
+ * (/^[-+]?(?:\d+(?:\.\d*)?|\.\d+)(e[-+]?\d+)?$/).test(x))
+ *
+ */
+ var number = function (x) { return numberPrimitive(x) || toS(x) === '[object Number]'; };
+
+ /* ___filename___: dist/deps/is/number.js */
+
+ /* ___filename___: dist/deps/is/stringOrNumber.js */
+
+
+
+ /**
+ * Checks if `value` is classified as a `String` primitive or object.
+ *
+ * @since 3.0.0
+ * @category Lang
+ * @memberOf is
+ * @param {*} x The value to check.
+ * @return {boolean} Returns `true` if `value` is a string, else `false`.
+ *
+ * @see https://github.com/infernojs/inferno/blob/master/packages/inferno-shared/src/index.ts#L23
+ * @see https://github.com/lodash/lodash/blob/master/isString.js
+ *
+ * @example
+ *
+ * isString('abc')
+ * // => true
+ *
+ * isString(1)
+ * // => false
+ */
+ var stringOrNumber = function (x) { return string(x) || number(x); };
+
+ /* ___filename___: dist/deps/is/real.js */
+
+
+ /**
+ * @param {*} x value
+ * @return {boolean} isReal
+ *
+ * @since 3.0.0
+ * @memberOf is
+ * @func isReal
+ * @see is/null
+ * @see is/undefined
+ *
+ * @see http://2ality.com/2013/04/quirk-implicit-conversion.html
+ * @see https://javascriptrefined.io/nan-and-typeof-36cd6e2a4e43
+ * @see https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/isNaN
+ *
+ * @NOTE eslint-disable-next-line no-self-compare
+ * && x !== x
+ *
+ * @extends isNullOrUndefined
+ * @variation *not* isNullOrUndefined && false for NaN
+ *
+ * @example
+ *
+ * isReal(null)
+ * //=> false
+ * isReal(void 0)
+ * //=> false
+ * const nan = Number(undefined)
+ * isReal(nan)
+ * //=> false
+ *
+ * isReal({eh: true})
+ * //=> true
+ * isReal({})
+ * //=> true
+ * isReal(Object)
+ * //=> true
+ * isReal([])
+ * //=> true
+ * isReal(new Set())
+ * //=> true
+ * isReal(function() {})
+ * //=> true
+ * isReal('')
+ * //=> true
+ * isReal(1)
+ * //=> true
+ *
+ */
+ var real = function (x) { return !nullOrUndefined(x) && !Number.isNaN(x); };
+
+ /* ___filename___: dist/deps/is/objPure.js */
+
+
+
+
+
+ /**
+ * @name isObjPure
+ * @memberOf is
+ * @alias isObjNotArrayOrFunction
+ * @since 3.0.0
+ *
+ *
+ * @param {*} x value to check
+ * @return {boolean} is obj & !null & !undefined & !array & !function
+ *
+ * @extends isArray
+ * @extends isObjTypeof
+ * @extends isNullOrUndefined
+ * @extends isFunction
+ *
+ * @example
+ *
+ * isObjPure(function() {})
+ * //=> false
+ * isObjPure(null)
+ * //=> false
+ * isObjPure([])
+ * //=> false
+ *
+ * isObjPure({})
+ * //=> true
+ *
+ */
+ var objPure = function (x) { return !nullOrUndefined(x) && !array(x) && !_function(x) && objTypeof(x); };
+
+ /* ___filename___: dist/deps/is/objWithKeys.js */
+
+
+
+ /**
+ * @TODO @NOTE need to be more careful, needs to check for vanilla objects, not native ones since e.g. Error has no keys
+ *
+ * @param {*} x value
+ * @return {boolean} isObjWithKeys
+ *
+ * @since 3.0.0
+ * @memberOf is
+ * @func isObjWithKeys
+ * @see is/obj
+ * @see is/objWithKeys
+ * @see is/objStrict
+ * @see is/null
+ *
+ * @extends isObj
+ * @variation Object.keys(obj).length !== 0
+ *
+ * @example
+ *
+ * isObjWithKeys({eh: true})
+ * //=> true
+ * isObjWithKeys({})
+ * //=> false
+ * isObjWithKeys(new Object())
+ * //=> false
+ * isObjWithKeys(Object.create(null))
+ * //=> false
+ * isObjWithKeys(null)
+ * //=> false
+ * isObjWithKeys(new Set())
+ * //=> false
+ * isObjWithKeys(function() {})
+ * //=> false
+ * isObjWithKeys('')
+ * //=> false
+ * isObjWithKeys(1)
+ * //=> false
+ *
+ */
+ var objWithKeys = function (val) { return obj(val) && keys(val).length !== 0; };
+
+ /* ___filename___: dist/deps/conditional/or.js */
+
+
+ /**
+ * @desc first fn || second fn, curried
+ * @name or
+ * @memberOf conditional
+ * @since 4.0.1
+ * @func
+ *
+ * @param {Function} left first fn
+ * @param {Function} right second fn
+ * @param {*} x value to pass into left & right, curried
+ * @return {boolean} one of the functions return truthy
+ *
+ * @example
+ * const {isTrue, isFalse} = require('chain-able')
+ *
+ * const either = or(isFalse, isTrue)
+ *
+ * either([true])
+ * //=> true
+ *
+ * either([new Boolean(true)])
+ * //=> false
+ *
+ * either([1])
+ * //=> false
+ *
+ * // because curried
+ * or(isTrue, isFalse, true) //=> true
+ *
+ */
+ var or = curry(3, function (left, right, x) { return left(x) || right(x); });
+
+ /* ___filename___: dist/deps/conditional/or.js */
+
+ /* ___filename___: dist/deps/is/matcher.js */
+
+
+
+
+ /**
+ * @func isMatcher
+ * @memberOf is
+ * @since 3.0.0
+ *
+ * @param {*} x value to check
+ * @return {boolean} isFunction || isRegExp
+ *
+ * @see is/regexp
+ * @see is/function
+ * @see conditionals/or
+ *
+ * @example
+ *
+ * isMatcher(/(.*)/)
+ * //=> true
+ *
+ * isMatcher(x => true)
+ * //=> true
+ *
+ * isMatcher(1)
+ * //=> false
+ * isMatcher('.*')
+ * //=> false
+ *
+ */
+ var matcher = or(_function, regexp); // x => isFunction(x) || isRegExp(x)
+ // x instanceof RegExp
+
+ /* ___filename___: dist/deps/is/objPure.js */
+
+ /* ___filename___: dist/deps/is/objWithKeys.js */
+
+ /* ___filename___: dist/deps/is/real.js */
+
+ /* ___filename___: dist/deps/is/matcher.js */
+
+ // dont need these yet
+
+
+ // const isClass = require('./class')
+ // const isEnumerable = require('./enumerable')
+ // const isMapish = require('./mapish')
+
+ /**
+ * @member is
+ * @types is
+ * @tests is/*
+ *
+ * @see https://github.com/lodash/lodash/issues/3237
+ * @type {Object}
+ */
+ var index$12 = {
+ isObjWithKeys: objWithKeys,
+ isObj: obj,
+ // isObject: isObj,
+ isObjPure: objPure,
+ isObjNotNull: objNotNull,
+ isFunction: _function,
+ isReal: real,
+ toS: toS,
+ isDate: date,
+ isRegExp: regexp,
+ isError: error$1,
+ isBoolean: boolean_1,
+ isNumber: number,
+ isString: string,
+ isMap: map,
+ isSet: set,
+ isSymbol: symbol,
+ isPrototypeOf: prototypeOf,
+ isArray: array,
+ // new
+ isIterator: iterator$2,
+ isUndefined: _undefined,
+ isNull: _null,
+ isNill: nullOrUndefined,
+ isTrue: _true,
+ isMatcher: matcher,
+ };
+
+ /* ___filename___: dist/deps/string/camelCase.js */
+ /* prettier-ignore */
+ /**
+ * @desc camelCase
+ * @since 0.2.0
+ * @symb 🐫
+ *
+ * @param {string} str string to turn into camelCase
+ * @return {string} camelCased string
+ *
+ * @tutorial https://github.com/substack/camelize/blob/master/test/camel.js
+ * @tutorial https://github.com/andrewplummer/Sugar/blob/9c018a257a38714b81f7df033b74d236dbf1e861/lib/string.js
+ * @tutorial http://stackoverflow.com/questions/2970525/converting-any-string-into-camel-case
+ * @tutorial https://github.com/sindresorhus/camelcase
+ * @see https://stackoverflow.com/questions/1533131/what-useful-bitwise-operator-code-tricks-should-a-developer-know-about
+ * @TODO s.charAt(0).toLowerCase() + string.slice(1)
+ *
+ * @types deps
+ * @tests deps/camelCase
+ *
+ * @example
+ *
+ * camelCase('snake_case')
+ * //=> 'snakeCase'
+ *
+ */
+ var camelCase = function (str) { return str
+ // spaces with underscore
+ .replace(/\s+/g, '_')
+ // < underscores & dashes until whitespace or end
+ // > .toUpperCase x & '_'
+ .replace(/[_.-](\w|$)/g, function (m, x) { return x.toUpperCase(); }); };
+
+ /* ___filename___: dist/deps/conditional/not.js */
+ /**
+ * @desc return a negated function
+ * @name not
+ * @memberOf conditional
+ * @since 4.0.1
+ * @func
+ *
+ * @param {Function} fn any function
+ * @return {Function} !Function
+ *
+ * @example
+ *
+ * const falsed = not(x => true)
+ * const trued = not(x => false)
+ *
+ * trued()
+ * //=> true
+ *
+ * falsed()
+ * //=> false
+ *
+ */
+ var not = function (fn) { return function (x) { return !fn(x); }; };
+
+ // function not(predicate) {
+ // return function() {
+ // return !predicate.apply(this, arguments)
+ // }
+ // }
+
+ /* ___filename___: dist/deps/conditional/and.js */
+ /**
+ * @desc first fn & second fn
+ * @name and
+ * @memberOf conditional
+ * @since 4.0.1
+ * @func
+ *
+ * @param {Function} left first fn
+ * @param {Function} right second fn
+ * @return {boolean} both functions return truthy
+ *
+ * @example
+ *
+ * const both = and(x => typeof x === 'boolean', x => x === true)
+ *
+ * both([true])
+ * //=> true
+ *
+ * both([false])
+ * //=> false
+ *
+ * both([1])
+ * //=> false
+ *
+ */
+ var and = function (left, right) { return function (x) { return left(x) && right(x); }; };
+
+ /* ___filename___: dist/deps/conditional/all.js */
+
+
+ /**
+ * map all values in an array to see if all match
+ * @memberOf conditional
+ *
+ * @since 4.0.1
+ * @param {Function} predicate match the value
+ * @param {Array} array to match against predicate
+ * @return {boolean} all match predicate
+ *
+ * @see fp/curry
+ *
+ * @example
+ *
+ * const allBoolean = all(x => typeof x === 'boolean'q)
+ *
+ * allBoolean([true])
+ * //=> true
+ *
+ * allBoolean([1])
+ * //=> false
+ *
+ */
+ var all = curry(2, function (predicate, arr) {
+ for (var i in arr) {
+ if (!predicate(arr[i])) { return false }
+ }
+ return true
+ });
+
+ var all_1 = all;
+
+ /* ___filename___: dist/deps/conditional/and.js */
+
+ /* ___filename___: dist/deps/conditional/all.js */
+
+ /* ___filename___: dist/deps/is/arrayOf.js */
+
+
+
+
+ /**
+ * @desc every item in an array matches predicate
+ * @since 4.0.0 was in validatorBuilder
+ * @version 5.0.0
+ *
+ * @param {Function} predicate test to pass on every item in an array
+ * @return {boolean} all match predicate
+ *
+ * @example
+ *
+ * isArrayOf(isTrue)([true, true]) //=> true
+ * isArrayOf(isEmpty)(['']) //=> true
+ *
+ * isArrayOf(isBoolean)([true, false, 1, 2, 0]) //=> false
+ * isArrayOf(isString)(['string', Number]) //=> false
+ *
+ */
+ var arrayOf = function isArrayOf(predicate) {
+ return and(array, all_1(predicate))
+ };
+
+ /* ___filename___: dist/deps/conditional/not.js */
+
+ /* ___filename___: dist/deps/is/notRealOrIsEmpty.js */
+
+
+
+
+
+ /**
+ * @SIZE: another 10bytes for these fns
+ * @name isNotRealOrIsEmpty
+ *
+ * @see is/isReal
+ * @see is/isEmpty
+ * @see conditional/and
+ * @see conditional/not
+ *
+ * @type {Function}
+ */
+ var notRealOrIsEmpty = and(not(real), empty);
+
+ /* ___filename___: dist/deps/fp/replace.js */
+
+
+ /**
+ * Replace a substring or regex match in a string with a replacement.
+ *
+ * @func
+ * @memberOf fp
+ * @since v5.0.0
+ * @category String
+ * @sig RegExp|String -> String -> String -> String
+ *
+ * @param {RegExp|String} pattern A regular expression or a substring to match.
+ * @param {String} replacement The string to replace the matches with.
+ * @param {String} str The String to do the search and replacement in.
+ * @return {String} The result.
+ *
+ * @see https://github.com/ramda/ramda/blob/master/src/replace.js
+ *
+ * @example
+ *
+ * replace('foo', 'bar', 'foo foo foo'); //=> 'bar foo foo'
+ * replace(/foo/, 'bar', 'foo foo foo'); //=> 'bar foo foo'
+ *
+ * // Use the "g" (global) flag to replace all occurrences:
+ * replace(/foo/g, 'bar', 'foo foo foo'); //=> 'bar bar bar'
+ *
+ */
+ var replace = curry(3, function replace(regex, replacement, str) {
+ return str.replace(regex, replacement)
+ });
+
+ /* ___filename___: dist/ChainedMapBase.js */
+
+ /* ___filename___: dist/deps/string/camelCase.js */
+
+ /* ___filename___: dist/deps/is/arrayOf.js */
+
+ /* ___filename___: dist/deps/is/notRealOrIsEmpty.js */
+
+ /* ___filename___: dist/deps/fp/replace.js */
+
+ /* ___filename___: dist/deps/validators/validatorBuilder.js */
+ /**
+ * @since 4.0.0 <- moved out of the store, into scoped
+ * @since 1.0.0
+ * @desc library of validators to use by name
+ * @modifies this.validators
+ * @param {Object} validators
+ */
+
+
+
+
+
+
+
+
+
+
+
+
+
+ var validators = new ChainedMapBase();
+
+ // eslint-disable-next-line
+ var stripArithmeticSymbols = replace(/[?\[\]!\|]/g, '');
+ var escapedKey = function (x) { return camelCase('is-' + x); };
+ var enummy = function (enums) { return function (x) { return enums === x || enums.includes(x); }; };
+
+ // @TODO: .remap!!!
+ // @TODO: can use these to return noops with error logging on development
+ var get$2 = function (key) { return validators.get(key) || validators.get(escapedKey(key)) || enummy(key); };
+ var has = function (key) { return validators.has(key) || validators.get(escapedKey(key)); };
+ var set$4 = function (key, value) { return validators.set(key, value); };
+ var doesNotHave = not(has);
+
+ /**
+ * @desc add custom types for validation
+ * @category types
+ * @category schema
+ * @types schema
+ *
+ * @since 4.0.0 <- used with schema, used in method chain
+ * @since 3.0.0 <- took out
+ * @since 1.0.0
+ *
+ * @param {Object} types custom Types
+ *
+ * @see deps/validators/validatorFactory
+ *
+ * @example
+ *
+ * addTypes({yaya: x => typeof x === 'string'})
+ *
+ * const chain = new Chain().methods('eh').type('yaya').build()
+ *
+ * chain.eh('good')
+ * //=> chain
+ *
+ * chain.eh(!!'throws')
+ * //=> TypeError(false != {yaya: x => typeof x === 'string'})
+ *
+ * @example
+ *
+ * const custom = {}
+ * custom.enums = enums => x => enums.includes(x)
+ * custom['*'] = x => true
+ * addTypes(custom)
+ * //-> void
+ *
+ * new Chain().methods('eh').type('*').build().eh
+ * //=> validateType(custom['*'])
+ *
+ */
+ var addTypes = function (types) { return validators.from(index$2(validators.entries(), types)); };
+
+ addTypes(index$12);
+
+ var includesAndOr = function (x) { return x.includes('|') || x.includes('&'); };
+
+ /**
+ * @memberOf schema
+ * @category types
+ *
+ * @param {string} fullKey a key with `|` and/or '&'
+ * @return {Function} validator
+ *
+ * @example
+ *
+ * const isStringOrNumber = typeListFactory('string|number')
+ *
+ * isStringOrNumber(1)
+ * //=> true
+ * isStringOrNumber('one')
+ * //=> true
+ * isStringOrNumber(Object)
+ * //=> false
+ *
+ */
+ function typeListFactory(fullKey) {
+ // already have it
+ if (has(fullKey)) {
+ return get$2(fullKey)
+ }
+
+ // get all types
+ var orTypes = fullKey.split('|');
+ var andTypes = fullKey.split('&');
+
+ // ensure we have all validators - sets up conditionals
+ for (var v = 0; v < orTypes.length; v++) {
+ builder(orTypes[v]);
+ }
+
+ // go through all valid options, if any are true, good to go
+ set$4(fullKey, function (x) {
+ for (var v = 0; v < orTypes.length; v++) {
+ if (get$2(orTypes[v])(x)) {
+ return true
+ }
+ }
+ return false
+ });
+
+ return get$2(fullKey)
+ }
+
+ // @TODO how to iterate properly with the bitwise fn + AND
+ // add another param? ignore overly complex |& things? just allow 1?
+ // just show how to use these shorthand fn builders
+
+ /**
+ * @desc transform arithmetic strings into types
+ * @since 4.0.0-alpha.1
+ * @category types
+ *
+ * @param {Matchable} fullKey arithmetic type key
+ * @return {Matchable} function to match with, with .inspect for easy debugging
+ *
+ * @types schema
+ * @test typed
+ * @test schema
+ * @see is
+ * @todo coercing values to certain types: arithmeticTypeFactory('')
+ *
+ * @example
+ *
+ * arithmeticTypeFactory('?string')
+ * //=> x => !isReal(x) || isString(x)
+ *
+ * @example
+ *
+ * arithmeticTypeFactory('?string|string[]')
+ * //=> x => isString(x) || isArrayOf(isString)(x)
+ *
+ * @example
+ *
+ * arithmeticTypeFactory('!string')
+ * //=> x => not(isString)(x)
+ *
+ * @example
+ *
+ * types.addTypes({star: x => true})
+ * arithmeticTypeFactory('object|function|star')
+ * //=> x => isObj(x) || isFunction(x) || isStar(x)
+ *
+ * @example
+ *
+ * arithmeticTypeFactory('===')
+ * //=> x => (['===']).includes(x)
+ */
+ function arithmeticTypeFactory(fullKey) {
+ var key = stripArithmeticSymbols(fullKey);
+ var fn = get$2(key);
+ var optionalType = "?" + key;
+ var typeOrArrayOrType = key + "[]";
+ var notType = "!" + key;
+
+ var isValidOrNotRealOrEmptyStr = or(fn, notRealOrIsEmpty);
+ var isValidOrArrayOfValid = or(fn, arrayOf(fn));
+ if (doesNotHave(optionalType)) {
+ set$4(optionalType, isValidOrNotRealOrEmptyStr);
+ }
+ if (doesNotHave(typeOrArrayOrType)) {
+ set$4(typeOrArrayOrType, isValidOrArrayOfValid);
+ }
+ if (doesNotHave(notType)) {
+ set$4(notType, not(fn));
+ }
+
+ return get$2(fullKey)
+ }
+
+ // ----
+ // ; function split
+ // ----
+
+ // v- annoying on comments with ifs
+ /* prettier-ignore */
+ /**
+ * @desc @pattern @builder -> builds using multiple factories depending on conditons
+ * or abstractFactory whatever
+ * opinionated: if it's a function, it's a validator...
+ *
+ * @category types
+ * @since 4.0.0
+ * @param {string | Function | Primitive} fullKey arithmetic key to the validator
+ * @return {Function} validator
+ *
+ * @see https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/Default_parameters
+ * @NOTE if/else is for uglifying ternaries, even though else if is not needed
+ * @NOTE if key is number, iterating the array
+ *
+ * @example
+ *
+ * // functionType
+ * const isString = x => typeof x === 'string'
+ * builder(isString)
+ * // => isString
+ *
+ * @example
+ *
+ * // stringType (built in, or custom-keyed validator, or eqeqeq)
+ * builder('string')
+ * // => isString
+ *
+ * const enummy = builder('enum')
+ * // => x => ['enum'].includes(x)
+ *
+ * @example
+ *
+ * // arithmeticType
+ * builder('string|string[]')
+ * // => isString || isArrayOf(isString)
+ *
+ */
+ function builder(fullKey) {
+ if (_function(fullKey)) {
+ /* istanbul ignore next: dev */
+ if (debug) {
+ console.log('functionType', {fullKey: fullKey});
+ }
+ return fullKey
+ }
+ else if (string(fullKey) && includesAndOr(fullKey)) {
+ /* istanbul ignore next: dev */
+ if (debug) {
+ console.log('andOrType', {fullKey: fullKey});
+ }
+ return typeListFactory(fullKey)
+ }
+ else {
+ /* istanbul ignore next: dev */
+ if (debug) {
+ console.log('arithmeticType', {fullKey: fullKey}, arithmeticTypeFactory(fullKey));
+ }
+ return arithmeticTypeFactory(fullKey)
+ }
+ }
+
+ builder.has = has;
+ builder.get = get$2;
+ builder.set = set$4;
+ builder.addTypes = addTypes; // was merge
+ builder.map = validators;
+ var validatorBuilder = builder;
+
+ /* ___filename___: dist/deps/dot/paths.js */
+
+ /* ___filename___: dist/deps/is/stringOrNumber.js */
+
+ /* ___filename___: dist/deps/validators/validatorBuilder.js */
+
+ /* ___filename___: dist/deps/validators/schemaBuilder.js */
+
+
+
+
+
+
+
+
+
+
+ var isNotNested = function (x) { return stringOrNumber(x) ||
+ boolean_1(x) ||
+ !real(x) ||
+ error$1(x) ||
+ regexp(x); };
+
+ var validateType = function (type, value, nestedSchema) {
+ var validator = nestedSchema || validatorBuilder(type);
+ return validator(value)
+ };
+
+ /**
+ * @desc pass the property & schema in, get a nestable typeValidator out
+ * @since 4.0.0-alpha.1
+ * @category types
+ * @category schema
+ *
+ * @param {Primitive} property property name of the currently nested schema
+ * @param {Schema | Type} nestedSchema a nested schema with Type validators, or a Type validator
+ * @return {Function} typeValidator
+ *
+ * @example
+ *
+ * // property name here is `dates`, then `created`, then `at`
+ * nestedSchema = {
+ * dates: {
+ * created: {
+ * at: 'date'
+ * }
+ * }
+ * }
+ *
+ * input = {
+ * dates: {
+ * created: {
+ * at: new Date()
+ * }
+ * }
+ * }
+ *
+ * input = new Date()
+ * input = {
+ * dates: {
+ * mismatch: true
+ * }
+ * }
+ *
+ */
+ var schemaFactory = function (property, nestedSchema) {
+ /**
+ * @desc build a recursive schema for all around runtime type safety
+ * @category types
+ * @category schema
+ * @memberOf schema
+ * @symb 🛂
+ * @since 4.0.0-beta.1
+ *
+ * @param {any} input the input to validate
+ * @return {boolean} valid
+ *
+ * @see is
+ *
+ * @example
+ *
+ * const typeValidator = schemaFactory('eh', x => typeof x === 'string')
+ *
+ * var isValid = typeValidator('stringy')
+ * //=> true
+ *
+ * var isValid = typeValidator(Number)
+ * //=> false
+ *
+ * @example
+ *
+ * const isNumber = x => typeof x === 'number'
+ * const typeValidator = schemaFactory('eh', {canada: 'number'})
+ *
+ * var isValid = typeValidator({canada: 1})
+ * //=> true
+ *
+ * var isValid = typeValidator({})
+ * //=> false
+ *
+ * var isValid = typeValidator({canada: false})
+ * //=> false
+ *
+ * var isValid = typeValidator(1)
+ * //=> false
+ *
+ */
+ function typeValidator(input) {
+ if (isNotNested(input)) {
+ // @@DEBUGGER
+ return validateType(property, input, nestedSchema)
+ }
+ var longestPaths = paths(false, input, true);
+
+ // @@DEBUGGER
+
+ for (var l = 0; l < longestPaths.length; l++) {
+ var fullPath = longestPaths[l] || property;
+ var type = get(nestedSchema, fullPath);
+ var value = get(input, fullPath.split('.'));
+
+ // @@DEBUGGER
+
+ if (!validateType(type, value)) {
+ // @@DEBUGGER
+ return false
+ }
+
+ // @@DEBUGGER
+ }
+ return true
+ }
+
+ /* istanbul ignore next: devs */
+ if (dev) {
+ typeValidator.inspect = function () { return ({property: property, nestedSchema: nestedSchema}); };
+ typeValidator.toString = function () { return JSON.stringify(typeValidator.inspect(), null, 2); };
+ }
+ return typeValidator
+ };
+ var schemaBuilder = schemaFactory;
+
+ /* ___filename___: dist/deps/validators/schemaBuilder.js */
+
+ /* ___filename___: dist/plugins/schema.js */
+ /* eslint complexity: "OFF" */
+
+ // util
+
+
+
+
+
+ var isFunction$1 = _undefined;
+ // logic
+
+
+
+ var SCHEMA_KEY = 'schema';
+
+ var isObjOrArray = function (x) { return (obj(x) && !isFunction$1(x)) || array(x); };
+
+ // const meta = require('../deps/meta')
+ // const or = require('../deps/conditional/or')
+ // const and = require('../deps/conditional/and')
+ // const not = require('../deps/conditional/not')
+ // const condition = Condition(Condition.is(isFunction).and().not(isObj)).or(isArray)
+ // const isObjNotFn = and(not(isFunction), isObj)
+ // const isObjOrArray = or(isObjNotFn, isArray)
+
+ /**
+ * @desc handles:
+ * 1. recursively building nestable schemas,
+ * 2. creating MethodChains for all types
+ * 3. carrying over the inheritable properties
+ * 4. @modifies @injects @decorates .add(customValidators)
+ * @pattern decorator...builder...plugin...
+ *
+ * @param {Schema} obj
+ * @return {MethodFactory} @chainable
+ */
+ var schema = function schema(obj$$2) {
+ var this$1 = this;
+
+ var parent = this.parent;
+ var ref = this.entries();
+ var onValid = ref.onValid;
+ var onInvalid = ref.onInvalid;
+ var define = ref.define;
+ var getSet = ref.getSet;
+ var keys$$2 = keys(obj$$2);
+
+ for (var k = 0; k < keys$$2.length; k++) {
+ var key = keys$$2[k];
+ var value = obj$$2[key];
+
+ // parent.method ? parent.method(key) :
+ var builder = this$1.newThis().name(key); // MethodChain
+
+ // @TODO: PLUCK METHOD FOR USING VALID KEYS
+ // @TODO:
+ // const entryKeys = ObjectKeys(entries)
+ // const entries = this.entries()
+ // for (let e = 0; e < entryKeys.length; e++) {
+ // const entryKey = entryKeys[e]
+ // const entry = entries[entryKey]
+ // builder[entryKey](entry)
+ // }
+ if (onInvalid) { builder.onInvalid(onInvalid); }
+ if (onValid) { builder.onValid(onValid); }
+ if (define) { builder.define(); }
+ if (getSet) { builder.getSet(); }
+
+ var type = value;
+ if (isObjOrArray(value)) {
+ // @@DEBUGGER
+
+ // could just assign to type
+ var traversableValidator = schemaBuilder(key, value);
+
+ if (dev) {
+ traversableValidator.schema = value;
+ }
+
+ type = traversableValidator;
+ }
+
+ // @HACK @FIXME @TODO: this should not happen,
+ // just when using babel and decorating not calling constructor...
+ // likely needs to `return this` on each?
+ // parent.store = parent.store || new Map()
+ // parent.meta = meta(parent)
+ if (parent.meta) {
+ parent.meta(SCHEMA_KEY, key, value);
+ }
+
+ builder.type(type).build();
+ }
+
+ return parent
+ };
+
+ /* ___filename___: dist/deps/encase/withSpecification.js */
+
+
+ /**
+ * @desc a special encased wrapper with no try catch but same api
+ * @name withSpecification
+ * @func
+ * @memberOf encase
+ * @since 4.0.0
+ *
+ * @param {Function} specification match
+ * @param {Function} call cb to determine valid or invalid
+ * @param {Function} onInvalid cb when invalid
+ * @param {Function} onInvalid cb when valid
+ * @return {Function} a lot of functions...
+ *
+ * @see fp/curry
+ *
+ * @example
+ * const onInvalid = console.error
+ * const onValid = console.debug
+ * const onCall = console.log
+ * const encased = withSpecification(x => true)(onCall)(onValid, onInvalid)
+ *
+ * encased(1, 2, 3) //=> onCall (did not throw)
+ */
+ var withSpecification = curry(4, function (specification, call, onInvalid, onValid) { return function (a, b, c) {
+ var result = call(a, b, c);
+ if (specification(result)) { return onInvalid(result) }
+ else { return onValid(result) }
+ }; });
+
+ /* ___filename___: dist/deps/validators/error.js */
+
+
+
+
+ /* istanbul ignore next: dev */
+ var thrower = function (error) { return function () {
+ if (dev) {
+ console.log(error);
+ }
+
+ throw error
+ }; };
+
+ /**
+ * @desc enhance an Error, enable rethrowing & better inspection
+ * @memberOf encase
+ * @category types
+ * @category encase
+ *
+ * @since 4.0.0-alpha.1
+ * @param {Primitive} method method being decorated
+ * @param {Type} type type to validate with
+ * @return {Function} function that returns a decorated TypeError with .inspect & metadata (arg, thrown, meta)
+ *
+ * @TODO js stringify if development
+ *
+ * @see MethodChain
+ * @see validators/schemaBuilder
+ * @see validators/validatorBuilder
+ * @see plugins/encase
+ *
+ * @example
+ * const badValidator = x => {
+ * if (x === 'bad') {
+ * throw new Error('bad!')
+ * }
+ * }
+ * const enhancer = enhanceError('eh', badValidator)
+ *
+ * // called by plugins/encase when throws or invalid
+ * let error
+ * let arg = 'bad'
+ * try {
+ * error = badValidator(arg)
+ * }
+ * catch (e) {
+ * error = enhancer(arg, e, {metadata: true})
+ * }
+ *
+ * console.log(error)
+ * //=> {[eh]: { type: badValidator, arg: 'bad', json, str, rethrow }}
+ * //=> console.log on DEVELOPMENT
+ */
+ var error$3 = function (method, type) { return function (arg, thrown, meta) {
+ var argToString = toS(arg);
+ var data = {
+ [method]: {
+ type: type,
+ arg: {
+ val: arg,
+ str: argToString,
+ json: JSON.stringify(arg),
+ },
+ },
+ };
+
+ var error = assign(
+ new TypeError((argToString + " != " + type)),
+ data,
+ meta
+ );
+
+ // put it back in its place
+ if (thrown && thrown.message) { error.message += thrown.message; }
+ if (thrown && thrown.stack) { error.stack = thrown.stack; }
+
+ /* istanbul ignore next: dev */
+ if (dev) {
+ // since we are just inspecting the metadata on dev
+ error.inspect = function () {
+ var devMsg = 'inspecting on development';
+ var thrownMsg = "thrown: " + thrown;
+ var eMsg = "compare: " + (error.message);
+ var errorName = "name: " + (error.name);
+ var argMsg = "arg: " + arg + ";\nstr: " + (toS(
+ arg
+ )) + " " + (typeof arg) + ";\njson: " + (JSON.stringify(arg));
+ var typeMsg = "type: " + type;
+ var stackMsg = 'stack: ' + error.stack;
+ var dashMsg = "-----";
+ var msg = "\n" + dashMsg + " " + devMsg + " " + dashMsg + "\n";
+ if (meta) { msg += "meta: " + (JSON.stringify(meta)) + "\n"; }
+ msg += thrownMsg + "\n" + eMsg + "\n" + errorName + "\n\n";
+ msg += typeMsg + "\n" + argMsg;
+ msg += "\n\n" + stackMsg + "\n" + dashMsg + "\n";
+ return msg
+ };
+ }
+
+ error.reThrow = thrower(error);
+ return error
+ }; };
+
+ /* ___filename___: dist/deps/encase/tryCatch.js */
+
+
+ /**
+ * @TODO could curry
+ *
+ * @memberOf encase
+ * @see https://github.com/fluture-js/Fluture#encase
+ * @since 4.0.0 <- moved out into a dep
+ * @since 1.0.0
+ *
+ * @param {Function} call
+ * @return {boolean | any} validation/encased function call result
+ */
+ var tryCatch = curry(3, function (call, onValid, onInvalid) { return function (a, b, c) {
+ var result;
+ try {
+ result = call(a, b, c);
+ return onValid ? onValid(result) : result
+ }
+ catch (error) {
+ // error.caught = true
+ // @NOTE: defaults to rethrow... if (isTrue(rethrow)) throw error
+ if (onInvalid) { return onInvalid(error) }
+ else { return error }
+ }
+ }; });
+
+ /* ___filename___: dist/deps/encase/tryCatch.js */
+
+ /* ___filename___: dist/deps/encase/encase.js */
+
+
+ /**
+ * @version 5.0.0 wrapped tryCatch & withSpecification in curry
+ * @version 4.0.1 added custom encaser
+ * @since 4.0.0
+ * @member encase
+ * @symb 🛡
+ *
+ * @param {Function} call function to _encase_
+ * @param {Function | undefined} [encaser=tryCatch] function to encase _with_
+ * @return {Function} -> FunctionObject{onInvalid, onValid, rethrow, call}
+ *
+ * @example
+ *
+ * const throws = x => {
+ * if (x === false) {
+ * throw new Error('invalid - cannot be false')
+ * }
+ * return true
+ * }
+ * const api = encase(throws)
+ *
+ *
+ * api.onValid(console.log)
+ * api.onInvalid(console.error)
+ *
+ * //--- invalid
+ * api.call(false)
+ * //=> 'invalid - cannot be false'
+ *
+ * //--- valid
+ * api.call(true)
+ * //=> 'true'
+ *
+ */
+ var encase = function (call, encaser) {
+ var encased = encaser ? encaser(call) : tryCatch(call);
+
+ // @TODO rethink this scoped approach
+ // left, right, rethrow
+ var onInvalid;
+ var onValid;
+
+ var config = function (a, b, c) { return encased(onValid, onInvalid)(a, b, c); };
+
+ config.then = config.onInvalid = function (fn) {
+ onInvalid = fn;
+ return config
+ };
+ config.catch = config.onValid = function (fn) {
+ onValid = fn;
+ return config
+ };
+
+ return config
+ };
+
+ /* ___filename___: dist/deps/encase/encase.js */
+
+ var index$14 = encase;
+
+ /* ___filename___: dist/deps/validators/error.js */
+
+ /* ___filename___: dist/plugins/encase.js */
+
+
+
+ var ERROR_META = {m: 1};
+
+ /**
+ * 3 steps
+ * 0. enhance error
+ * 1. encase function with a specification
+ * 2. build a function to call onInvalid or onInvalid depending
+ *
+ * @since 4.0.0
+ *
+ * @param {string} name name of the method
+ * @param {Object | Function} parent object being decorated by MethodChain
+ * @param {Object} built the current state of the decoration
+ * @return {Function} curried finisher, for specification
+ *
+ * @name methodEncasingFactory
+ * @func methodEncasingFactory
+ * @symb ⛑🏭
+ * @types encase
+ *
+ * @example
+ *
+ * methodEncasingFactory('eh', {}, {onSet: console.log})
+ * //=> Function
+ *
+ */
+ function methodEncasingFactory(name, parent, built) {
+ /**
+ * @name scopedEncase
+ * @func scopedEncase
+ * @category type
+ * @since 4.0.0-beta.1
+ *
+ * @param {Function} fnToEncase depending on the result of this, call
+ * @param {string | Function | undefined} [type=undefined] Type
+ * @param {Function | undefined} [specification=undefined] Specification
+ * @return {Function} the method...
+ *
+ * @example
+ *
+ * const fnToEncase = arg => arg === true
+ * const onInvalid = (error, key, arg, instance) => console.log(arguments)
+ * const onValid = (key, arg, instance) => console.log(arguments)
+ * const encased = scopedEncase(fnToEncase)
+ * .onValid(onValid)
+ * .onInvalid(onInvalid)
+ * //=> typedOnCall
+ *
+ */
+ return function scopedEncase(fnToEncase, type, specification) {
+ // @@debugger
+ var enhanceError = error$3(name, type, fnToEncase, parent);
+
+ // if specification is not passed in, undefined defaults to tryCatch
+ var encased = index$14(fnToEncase, specification);
+
+ // our configured functions, with fallback defaults
+ var onSet = built.onCall || built.onSet;
+ var onValid = built.onValid || onSet;
+
+ // default to re-throw
+ var onInvalid =
+ built.onInvalid ||
+ (function (arg, error) { return enhanceError(arg, error, ERROR_META).reThrow(); });
+
+ /**
+ * @desc this is the actual built function
+ * @name typedOnCall
+ * @func typedOnCall
+ * @category type
+ * @since 4.0.0-beta.1
+ *
+ * @param {any} arg arg to validate
+ * @return {Function} typedOnCall(argToValidate: any)
+ *
+ * @example
+ *
+ * const encased = encase(fnToEncase)
+ * .onValid()
+ * .onInvalid(function)
+ * .call()
+ *
+ */
+ return function typedOnCall(arg) {
+ var this$1 = this;
+
+ // nodejs way - error first, data second, instance last
+ var callInvalid = function (error) {
+ // @@debugger
+ onInvalid.call(this$1, enhanceError(arg, error), arg, name, this$1);
+ };
+
+ // @TODO: ensure it isn't a syntax error and is a type error
+ // if it is already an error, we should only enhance it
+ // @example `TypeError: Cannot read property 'call' of undefined`
+ encased
+ .onInvalid(callInvalid)
+ // @NOTE: onValid defaults to `this.set(name, arg)`
+ .onValid(function (result) {
+ // @@debugger
+ onValid.call(this$1, arg, name, this$1);
+ })
+ .call(this, arg);
+
+ return this
+ }
+ }
+ }
+
+ var encase_1 = methodEncasingFactory;
+
+ /* ___filename___: dist/deps/encase/withSpecification.js */
+
+ /* ___filename___: dist/plugins/encase.js */
+
+ /* ___filename___: dist/plugins/types.js */
+
+
+
+
+
+
+
+ // we'll be opinionated and say either `false` or `throw`
+ var spec = withSpecification(not(_false));
+
+ /**
+ * @pattern factory plugin
+ * @param {string} name
+ * @param {Object} parent
+ * @param {Object} built
+ * @return {void}
+ */
+ var types = function validatorPlugin(name, parent, built) {
+ // core domain of this fn, used by validators and configured fns
+ var type = built.type;
+
+ if (type) {
+ // if (ENV_DEVELOPMENT) {
+ // this.debugSteps('added built type')
+ // }
+
+ // create our validator in the factory,
+ var validator = validatorBuilder(type);
+
+ // then encase it, prepare a TypeError factory
+ var encase = encase_1(name, parent, built);
+ var validatorMethod = encase(validator, type, spec);
+
+ /* istanbul ignore next: dev */
+ if (dev) {
+ validatorMethod.type = type;
+ }
+
+ this.onCall(validatorMethod).onSet(validatorMethod);
+ }
+ };
+
+ /* ___filename___: dist/plugins/obj.js */
+
+
+ // @TODO optimize size here ez
+ var obj$2 = function(methods, name) {
+ var this$1 = this;
+
+ var obj = methods[name];
+
+ if (_function(obj)) {
+ return function () {
+ // @TODO: IS THIS THE BEST DEFAULT?!
+ this$1.define(false);
+ this$1.onCall(obj);
+ // .onSet(obj).onGet(obj)
+ }
+ }
+ else {
+ return function () {
+ this$1.from(obj);
+ // @NOTE: this is reserved
+ if (obj.set) { this$1.onSet(obj.set); }
+ if (obj.get) { this$1.onGet(obj.get); }
+ if (obj.call) { this$1.onCall(obj.call); }
+ if (obj.set && obj.get) {
+ this$1.define().getSet();
+ }
+ }
+ }
+ };
+
+ /* ___filename___: dist/plugins/decorate.js */
+
+
+
+ /**
+ * decorates a parent when the argument is provided
+ * BUT THE FUNCTIONS WILL STILL BE SCOPED TO CURRENT PARENT
+ * for easy factory chaining
+ *
+ * @since 4.0.0-alpha.1
+ * @memberOf MethodChain
+ * @param {Object} parentToDecorate object to put the method on instead
+ * @return {MethodChain} @chainable
+ *
+ * @see MethodChain
+ *
+ * @TODO this is more like a preset since it *adds* plugins?
+ * more of methodFactory now
+ *
+ * @example
+ *
+ * const chain = new Chain()
+ * const obj = {}
+ * chain.method('ehOh').decorate(obj).build()
+ * typeof obj.ehOh
+ * //=> 'function'
+ *
+ */
+ var decorate = function(parentToDecorate) {
+ // @TODO is objStrict?
+ // if (parentToDecorate) {
+ this.target(parentToDecorate);
+
+ // can use this to "undecorate"
+ // if (!parentToDecorate.meta) <- checks already inside of meta()
+ parentToDecorate.meta = index$8(parentToDecorate);
+
+ // default returns result of calling function,
+ // else .parentToDecorate
+ return this.plugin(function(name, parent) {
+ parentToDecorate.meta(decorated, name);
+
+ // @NOTE: so we can return...
+ /* prettier-ignore */
+ return this
+ .returns(function returnsFunction(result) {
+ return result || parentToDecorate
+ })
+ .callReturns(true)
+ })
+ };
+
+ /* ___filename___: dist/plugins/autoIncrement.js */
+ /**
+ * @plugin
+ * @param {Primitive} name method name
+ * @param {Object} parent Parent
+ * @return {MethodChain} @chainable
+ */
+ var autoIncrement = function(name, parent) {
+ return this.initial(0).onCall(function () { return parent.tap(name, function (num) { return num + 1; }); })
+ };
+
+ /* ___filename___: dist/plugins/autoGetSet.js */
+
+
+ /**
+ * @memberOf MethodChain
+ * @plugin
+ *
+ * @param {Primitive} name method name being built
+ * @param {Object} parent parent containing the method
+ * @return {MethodChain} @chainable
+ *
+ * @see MethodChain
+ *
+ * @example
+ *
+ * const chain = new Chain()
+ * chain.methods('eh').plugin(autoGetSet).build()
+ *
+ * chain.eh(1)
+ * //=> Chain
+ * chain.eh()
+ * //=> 1
+ *
+ */
+ function autoGetSet(name, parent) {
+ var auto = function (arg) { return (_undefined(arg) ? parent.get(name) : parent.set(name, arg)); };
+
+ // so we know if we defaulted them
+ auto.autoGetSet = true;
+ return this.onSet(auto).onGet(auto).onCall(auto)
+ }
+
+ var autoGetSet_1 = autoGetSet;
+
+ /* ___filename___: dist/deps/util/getDescriptor.js */
+ var getDescriptor = Object.getOwnPropertyDescriptor;
+
+ /* ___filename___: dist/deps/argumentor.js */
+ /**
+ * @desc turns arguments into an array, used as a util, for opt
+ *
+ * @since 3.0.0
+ * @return {Array}
+ *
+ * @see https://github.com/aretecode/awesome-deopt
+ * @see https://github.com/petkaantonov/bluebird/wiki/Optimization-killers
+ *
+ * @example
+ *
+ * function eh() {
+ * const args = argumentor.apply(null, arguments).slice(1)
+ *
+ * console.log(args)
+ * //=> [1, 10, 100]
+ * }
+ * eh(0, 1, 10, 100)
+ *
+ */
+ var argumentor = function() {
+ var arguments$1 = arguments;
+
+ var len = arguments.length;
+ var args = new Array(len > 1 ? len - 1 : 0);
+ for (var i = 0; i < len; ++i) { args[i] = arguments$1[i]; }
+ return args
+ };
+
+ /* ___filename___: dist/deps/util/getPrototypeOf.js */
+ var getPrototypeOf = Object.getPrototypeOf;
+
+ /* ___filename___: dist/deps/util/getPrototypeOf.js */
+
+ /* ___filename___: dist/deps/util/props.js */
+
+
+
+ var getOwnPropertyNames = Object.getOwnPropertyNames;
+ var getOwnPropertySymbols = Object.getOwnPropertySymbols;
+
+ // @TODO https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptors
+ // const getOwnPropertyDescriptors = Object.getOwnPropertyDescriptors
+
+ /**
+ * @desc properties, property symbols, object keys
+ * ^ all again for prototype
+ *
+ * @param {Object} obj object to get properties & symbols from
+ * @return {Array} properties
+ *
+ * @example
+ * var obj = {key: true}
+ * allProperties(obj)
+ * //=> ['key']
+ *
+ * @example
+ * class One {
+ * method() {}
+ * }
+ * class Two extends One {
+ * eh() {}
+ * }
+ * allProperties(new Two())
+ * //=> ['eh', 'method']
+ *
+ */
+ function allProperties(obj) {
+ var proto = getPrototypeOf(obj);
+ return [].concat(
+ getOwnPropertyNames(obj),
+ getOwnPropertySymbols(obj),
+ keys(obj),
+ proto ? allProperties(proto) : []
+ )
+ }
+
+ var props = allProperties;
+
+ /* ___filename___: dist/deps/util/props.js */
+
+ /* ___filename___: dist/deps/gc.js */
+
+
+
+
+
+ // function gc() {
+ // if (typeof window !== 'undefined') window.global = window
+ // if (typeof global.gc === 'function') global.gc()
+ // }
+
+ /**
+ * @see https://stackoverflow.com/questions/1947995/when-should-i-use-delete-vs-setting-elements-to-null-in-javascript
+ * @see https://v8project.blogspot.ca/2015/08/getting-garbage-collection-for-free.html
+ * @see https://github.com/natewatson999/js-gc
+ * @see https://github.com/siddMahen/node-gc
+ * @see http://buildnewgames.com/garbage-collector-friendly-code/
+ * @see https://stackoverflow.com/questions/27597335/ensuring-object-can-be-garbage-collected
+ * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_Management
+ *
+ * @TODO blacklist = [] param
+ * @TODO put all GC events into a cached map and debounce the operation
+ *
+ * @since 4.0.0
+ * @desc remove all methods, mark for garbage collection
+ * @param {Object} obj object to traverse and clear
+ * @return {void}
+ *
+ * @example
+ *
+ * var scoped = {}
+ * var ref = () => scoped
+ * var obj = {scoped, ref, eh: true}
+ *
+ * markForGarbageCollection(obj)
+ * //=> void
+ *
+ * obj
+ * //=> undefined|{}
+ *
+ */
+ function markForGarbageCollection(obj$$2) {
+ // @TODO: ArrayOrObj loop... like tons of libs do...
+ var props$$1 = obj(obj$$2) ? props(obj$$2) : obj$$2; //isArray(obj) ? obj
+
+ for (var p = 0; p < props$$1.length; p++) {
+ if (obj(obj$$2[p])) {
+ markForGarbageCollection(obj$$2[p]);
+ }
+ delete obj$$2[p];
+ }
+
+ // traverse(obj).forEach(function(x) {
+ // const {value} = this
+ //
+ // // @NOTE: just delete the main path first, later we can use cleaner
+ // // const shouldIgnore = path
+ // // .map(pathPart => ignore.includes(pathPart))
+ // // .includes(true)
+ // // !shouldIgnore &&
+ //
+ // /* istanbul ignore else: safety for bottom up */
+ // // ensure the longest paths in traverser are used...
+ // if (!isArray(value) && !isObj(value)) {
+ // this.remove()
+ // }
+ // })
+
+ // simple fast easy cleanup
+ // for (let p = 0; p < props.length; p++) {
+ // delete obj[p]
+ // }
+
+ props$$1 = undefined;
+ obj$$2 = undefined;
+ }
+
+ var gc = markForGarbageCollection;
+
+ /* ___filename___: dist/plugins/schema.js */
+
+ /* ___filename___: dist/plugins/types.js */
+
+ /* ___filename___: dist/plugins/obj.js */
+
+ /* ___filename___: dist/plugins/decorate.js */
+
+ /* ___filename___: dist/plugins/autoIncrement.js */
+
+ /* ___filename___: dist/plugins/autoGetSet.js */
+
+ /* ___filename___: dist/deps/util/getDescriptor.js */
+
+ /* ___filename___: dist/deps/argumentor.js */
+
+ /* ___filename___: dist/deps/gc.js */
+
+ /* ___filename___: dist/MethodChain.js */
+ /* eslint complexity: "OFF" */
+ /* eslint import/max-dependencies: "OFF" */
+
+ /**
+ * @TODO clarify .set vs .call
+ * {@link https://github.com/iluwatar/java-design-patterns/tree/master/property property-pattern}
+ * {@link https://github.com/iluwatar/java-design-patterns/tree/master/prototype prototype-pattern}
+ * {@link https://github.com/iluwatar/java-design-patterns/tree/master/step-builder step-builder-pattern}
+ * {@link https://github.com/iluwatar/java-design-patterns/tree/master/builder builder-pattern}
+ * {@link https://github.com/addyosmani/essential-js-design-patterns/blob/master/diagrams/mixins.png mixin-png}
+ * {@link https://sourcemaking.com/design_patterns/creational_patterns creational-patterns}
+ * {@link https://sourcemaking.com/design_patterns/factory_method factory-method}
+ * {@link https://medium.com/javascript-scene/javascript-factory-functions-vs-constructor-functions-vs-classes-2f22ceddf33e constructors}
+ * {@link https://www.sitepoint.com/factory-functions-javascript/ js-factory-functions}
+ */
+
+ // core
+
+
+
+
+ // plugins
+
+
+
+
+
+
+
+ // const validatorBuilder = require('./deps/validators/validatorBuilder')
+ // obj
+
+
+
+
+
+ // utils
+
+
+
+
+ // is
+
+
+
+
+
+
+
+ var DEFAULTED_KEY = 'defaulted';
+ var METHOD_KEYS = [
+ 'onInvalid',
+ 'onValid',
+ 'initial',
+ 'default',
+ 'type',
+ 'callReturns',
+ 'target',
+ 'onSet',
+ 'onCall',
+ 'onGet',
+ ];
+
+ // const SET_KEY = METHOD_KEYS[0]
+
+ function getSetFactory(_this, name, desc) {
+ _this[camelCase(("set-" + name))] = desc.set;
+ _this[camelCase(("get-" + name))] = desc.get;
+ }
+
+ function aliasFactory(name, parent, aliases) {
+ if (!_undefined(aliases)) {
+ for (var a = 0; a < aliases.length; a++) {
+ define(parent, aliases[a], getDescriptor(parent, name));
+ }
+ }
+ }
+
+ // @TODO to use as a function
+ // function _methods() {}
+ // _methods.use(obj) {
+ // this.obj = obj
+ // return _methods
+ // }
+ // _methods.extend = _methods.use
+ // _methods.methods = function(methods) {
+ // return new MethodChain(this.obj)
+ // }
+
+ var methodFactories = {};
+
+ /**
+ * ❗ using `+` will call `.build()` in a shorthand fashion
+ *
+ * @member MethodChain
+ * @inheritdoc
+ * @class
+ * @extends {ChainedMap}
+ * @type {Map}
+ *
+ * @since 4.0.0
+ *
+ * @types MethodChain
+ * @tests MethodChain
+ *
+ * @TODO maybe abstract the most re-usable core as a protected class
+ * so the shorthands could be used, and more functionality made external
+ * @TODO need to separate schema from here as external functionality & add .add
+ * @TODO .prop - for things on the instance, not in the store?
+ * !!! .sponge - absorn properties into the store
+ */
+ var MethodChain = (function (ChainedMap) {
+ function MethodChain(parent) {
+ var this$1 = this;
+
+ // timer.start('methodchain')
+
+ ChainedMap.call(this, parent);
+
+ // ----------------
+ var set = this.set.bind(this);
+
+ this.newThis = function () { return new MethodChain(parent); };
+ this.toNumber = function () { return this$1.build(0); };
+
+ /**
+ * @example
+ *
+ * chain
+ * .method('eh')
+ * .type(`?string`)
+ * .type(`string[]`)
+ * .type(`string|boolean`)
+ * .type(`boolean[]|string[]`)
+ * .type(`!date`)
+ *
+ */
+ this.extend(METHOD_KEYS);
+
+ // shorthand
+ this.method = this.methods = function (name) {
+ if (this$1.length) { return this$1.build().methods(name) }
+ else { return this$1.name(name) }
+ };
+
+ // default argument...
+ this.encase = function (x) {
+ return set('encase', parent[x] || x || true)
+ };
+
+ // alias
+ this.then = this.onValid.bind(this);
+ this.catch = this.onInvalid.bind(this);
+
+ this.returns = function (x, callReturns) { return set('returns', x || parent).callReturns(callReturns); };
+
+ // @NOTE replaces shorthands.chainWrap
+ this.chainable = this.returns;
+
+ /**
+ * @desc alias methods
+ * @since 2.0.0
+ *
+ * @param {string | Array} aliases aliases to remap to the current method being built
+ * @return {MethodChain} @chainable
+ *
+ * @NOTE these would be .transform
+ *
+ * @example
+ *
+ * const chain = new Chain()
+ * chain.methods(['canada']).alias(['eh']).build()
+ * chain.eh('actually...canada o.o')
+ * chain.get('canada')
+ * //=> 'actually...canada o.o')
+ *
+ */
+ this.alias = function (aliases) { return this$1.tap('alias', function (old, merge) { return merge(old, toArr(aliases)); }); };
+ this.plugin = function (plugin) { return this$1.tap('plugins', function (old, merge) { return merge(old, toArr(plugin)); }); };
+
+ this.camelCase = function () { return set('camel', true); };
+
+ // @NOTE: x = true is much prettier, but compiles badly
+ var defaultToTrue = function (x) { return (_undefined(x) ? true : x); };
+ this.define = function (x) { return set('define', defaultToTrue(x)); };
+ this.getSet = function (x) { return set('getSet', defaultToTrue(x)); };
+
+ // @TODO unless these use scoped vars, they should be on proto
+ // @NOTE shorthands.bindMethods
+ this.bind = function (target) { return set('bind', _undefined(target) ? parent : target); };
+ this.autoGetSet = function () { return this$1.plugin(autoGetSet_1); };
+
+ this.plugin(types);
+
+ if (objWithKeys(methodFactories)) {
+ keys(methodFactories).forEach(function (factoryName) {
+ this$1[factoryName] = function (arg) { return methodFactories[factoryName].call(this$1, arg); };
+ if (dev) {
+ this$1[factoryName].methodFactory = true;
+ }
+ });
+ }
+ }
+
+ if ( ChainedMap ) MethodChain.__proto__ = ChainedMap;
+ MethodChain.prototype = Object.create( ChainedMap && ChainedMap.prototype );
+ MethodChain.prototype.constructor = MethodChain;
+
+ /**
+ * @desc setup methods to build
+ * @category builder
+ * @memberOf MethodChain
+ *
+ * @since 4.0.0-beta.1 <- moved to plugin
+ * @since 4.0.0
+ *
+ * @param {string | Object | Array} methods method names to build
+ * @return {MethodChain} @chainable
+ *
+ * @example
+ *
+ * var obj = {}
+ * new MethodChain(obj).name('eh').build()
+ * typeof obj.eh
+ * //=> 'function'
+ *
+ */
+ MethodChain.prototype.name = function name (methods) {
+ var this$1 = this;
+
+ var names = methods;
+
+ /**
+ * @desc this is a plugin for building methods
+ * schema defaults value to `.type`
+ * this defaults values to `.onCall`
+ */
+ if (!array(methods) && obj(methods)) {
+ names = keys(methods);
+ for (var name = 0; name < names.length; name++) {
+ this$1.plugin(obj$2.call(this$1, methods, names[name]));
+ }
+ }
+ return this.set('names', names)
+ };
+
+ /**
+ * an object that contains nestable `.type`s
+ * they are recursively (using an optimized traversal cache) mapped to validators
+ * ❗ this method auto-calls .build, all other method config calls should be done before it
+ *
+ * @TODO link to `deps/is` docs
+ *
+ * @version 4.0.0-beta.1 <- moved to plugin
+ * @since 4.0.0
+ *
+ * @category types
+ * @memberOf MethodChain
+ *
+ * @param {Object} obj schema
+ * @return {MethodChain} @chainable
+ *
+ * @TODO move out into a plugin to show how easy it is to use a plugin
+ * and make it able to be split out for size when needed
+ *
+ * @TODO inherit properties (in plugin, for each key)
+ * from this for say, dotProp, getSet
+ *
+ * @TODO very @important
+ * that we setup schema validation at the highest root for validation
+ * and then have some demo for how to validate on set using say mobx
+ * observables for all the way down...
+ *
+ * @typedef `schema(schema: Obj): ChainAble`
+ *
+ * @example
+ *
+ * chain
+ * .methods()
+ * .define()
+ * .getSet()
+ * .onInvalid((error, arg, instance) => console.log(error))
+ * .schema({
+ * id: '?number',
+ * users: '?object|array',
+ * topic: '?string[]',
+ * roles: '?array',
+ * creator: {
+ * name: 'string',
+ * email: 'email',
+ * id: 'uuid',
+ * },
+ * created_at: 'date',
+ * updated_at: 'date|date[]',
+ * summary: 'string',
+ * })
+ *
+ * //--- valid
+ * chain.created_at = new Date()
+ * chain.setCreatedAt(new Date())
+ *
+ * isDate(chain.created_at) === true
+ *
+ * //--- nestable validation 👍
+ * chain.merge({creator: {name: 'string'}})
+ *
+ * //--- invalid
+ * chain.updated_at = false
+ *
+ */
+ MethodChain.prototype.schema = function schema$$1 (obj$$1) {
+ return schema.call(this, obj$$1)
+ };
+
+ /**
+ * @desc set the actual method, also need .context - use .parent
+ * @memberOf MethodChain
+ * @since 4.0.0
+ *
+ * @param {any} [returnValue=undefined] returned at the end of the function for ease of use
+ * @return {MethodChain} @chainable
+ *
+ * @TODO if passing in a name that already exists, operations are decorations... (partially done)
+ * @see https://github.com/iluwatar/java-design-patterns/tree/master/step-builder
+ *
+ * @example
+ *
+ * var obj = {}
+ * const one = new MethodChain(obj).methods('eh').getSet().build(1)
+ * //=> 1
+ *
+ * typeof obj.getEh
+ * //=> 'function'
+ *
+ */
+ MethodChain.prototype.build = function build (returnValue) {
+ var this$1 = this;
+
+ var parent = this.parent;
+ var names = toArr(this.get('names'));
+ var shouldTapName = this.get('camel');
+
+ for (var name = 0; name < names.length; name++) {
+ this$1._build(shouldTapName ? camelCase(names[name]) : names[name], parent);
+ }
+
+ // timer.stop('methodchain').log('methodchain').start('gc')
+
+ // remove refs to unused
+ this.clear();
+ delete this.parent;
+ gc(this);
+
+ // very fast - timer & ensuring props are cleaned
+ // timer.stop('gc').log('gc')
+ // require('fliplog').quick(this)
+
+ return _undefined(returnValue) ? parent : returnValue
+ };
+
+ /**
+ * @memberOf MethodChain
+ *
+ * @since 4.0.0
+ * @protected
+ * @param {Primitive} name method name
+ * @param {Object} parent being decorated
+ * @param {Object} built method being built
+ * @return {void}
+ *
+ * @TODO optimize the size of this
+ * with some bitwise operators
+ * hashing the things that have been defaulted
+ * also could be plugin
+ *
+ * @example
+ *
+ * ._defaults('', {}, {})
+ *
+ *
+ * @example
+ *
+ * let methodFactories
+ *
+ * ### `onSet`
+ *
+ * > defaults to `this.set(key, value)`
+ *
+ * ```ts
+ * public onSet(fn: Fn): MethodChain
+ * ```
+ *
+ * ### `onCall`
+ *
+ * > defaults to .onSet ^
+ *
+ * ```ts
+ * public onCall(fn: Fn): MethodChain
+ * ```
+ *
+ * ### `onGet`
+ *
+ * > defaults to `this.get(key)`
+ *
+ * ```ts
+ * public onGet(fn: Fn): MethodChain
+ * ```
+ *
+ */
+ MethodChain.prototype._defaults = function _defaults (name, parent, built) {
+ // defaults
+ var defaultOnSet = function (arg) { return parent.set(name, arg); };
+ var defaultOnGet = function () { return parent.get(name); };
+
+ // so we know if we defaulted them
+ defaultOnSet[DEFAULTED_KEY] = true;
+ defaultOnGet[DEFAULTED_KEY] = true;
+
+ // when we've[DEFAULTED_KEY] already for another method,
+ // we need a new function,
+ // else the name will be scoped incorrectly
+ var onCall = built.onCall;
+ var onSet = built.onSet;
+ var onGet = built.onGet;
+ if (!onGet || onGet[DEFAULTED_KEY]) {
+ this.onGet(defaultOnGet);
+ }
+ if (!onCall || onCall[DEFAULTED_KEY]) {
+ this.onCall(defaultOnSet);
+ }
+ if (!onSet || onSet[DEFAULTED_KEY]) {
+ this.onSet(defaultOnSet);
+ }
+ };
+
+ /**
+ * @protected
+ * @since 4.0.0-alpha.1
+ * @memberOf MethodChain
+ *
+ * @param {Primitive} name
+ * @param {Object} parent
+ * @return {void}
+ *
+ * @TODO allow config of method var in plugins since it is scoped...
+ * @TODO add to .meta(shorthands)
+ * @TODO reduce complexity if perf allows
+ * @NOTE scoping here adding default functions have to rescope arguments
+ */
+ MethodChain.prototype._build = function _build (name, parent) {
+ var this$1 = this;
+
+ var method;
+ var existing;
+ var entries = function () { return this$1.entries(); };
+
+ // could ternary `let method =` here
+ if (hasOwnProperty_1(parent, name)) {
+ existing = getDescriptor(parent, name);
+
+ // avoid `TypeError: Cannot redefine property:`
+ if (_false(existing.configurable)) {
+ return
+ }
+
+ // use existing property, when configurable
+ method = existing.value;
+
+ if (dev) {
+ method.decorated = true;
+ }
+
+ this.onCall(method).onSet(method);
+ }
+ else if (parent[name]) {
+ method = parent[name];
+
+ if (dev) {
+ method.decorated = true;
+ }
+
+ this.onCall(method).onSet(method);
+ }
+
+ // scope it once for plugins & type building, then get it again
+ var built = entries();
+
+ this._defaults(name, parent, built);
+
+ // plugins can add methods,
+ // useful as plugins/presets & decorators for multi-name building
+ var instancePlugins = built.plugins;
+ if (instancePlugins) {
+ for (var plugin = 0; plugin < instancePlugins.length; plugin++) {
+ built = entries();
+ instancePlugins[plugin].call(this$1, name, parent, built);
+ }
+ }
+
+ // after last plugin is finished, or defaults
+ built = entries();
+
+ // wrap in encasing when we have a validator or .encase
+ // @NOTE: validator plugin was here, moved into a plugin
+ if (built.encase) {
+ var encased = encase_1.call(this, name, parent, built)(method);
+
+ if (dev) {
+ encased.encased = method;
+ }
+
+ this.onCall(encased).onSet(encased);
+ method = encased;
+ built = entries();
+ }
+
+ // not destructured for better variable names
+ var shouldAddGetterSetter = built.getSet;
+ var shouldDefineGetSet = built.define;
+ var defaultValue = built.default;
+
+ // can only have `call` or `get/set`...
+ var onGet = built.onGet;
+ var onSet = built.onSet;
+ var onCall = built.onCall;
+ var initial = built.initial;
+ var bind = built.bind;
+ var returns = built.returns;
+ var callReturns = built.callReturns;
+ var alias = built.alias;
+
+ // default method, if we do not have one already
+ if (!method) {
+ method = function (arg) {
+ if ( arg === void 0 ) arg = defaultValue;
+
+ return onCall.call(parent, arg);
+ };
+
+ if (dev) {
+ method.created = true;
+ }
+ }
+
+ if (bind) {
+ // bind = bindArgument || parent
+ method = method.bind(bind);
+ }
+ if (returns) {
+ var ref = method;
+ method = function() {
+ var args = argumentor.apply(null, arguments);
+
+ // eslint-disable-next-line prefer-rest-params
+ var result = ref.apply(parent, args);
+
+ return _true(callReturns)
+ ? returns.apply(parent, [result].concat(args))
+ : returns
+ };
+ }
+
+ if (!_undefined(initial)) {
+ parent.set(name, initial);
+ }
+
+ // --------------- stripped -----------
+
+ /**
+ * !!!!! @TODO put in `plugins.post.call`
+ * !!!!! @TODO ensure unique name
+ *
+ * can add .meta on them though for re-decorating
+ * -> but this has issue with .getset so needs to be on .meta[name]
+ */
+
+ /* istanbul ignore next: dev */
+ if (dev) {
+ define(onGet, 'name', {
+ value: camelCase(((onGet.name) + "+get-" + name)),
+ });
+ define(onSet, 'name', {
+ value: camelCase(((onSet.name) + "+set-" + name)),
+ });
+ define(onCall, 'name', {
+ value: camelCase(((onCall.name) + "+call-" + name)),
+ });
+ define(method, 'name', {value: camelCase(("" + name))});
+
+ if (built.type) { method.type = built.type; }
+ if (initial) { method.initial = initial; }
+ if (bind) { method.bound = bind; }
+ if (returns) { method.returns = returns; }
+ if (alias) { method.alias = alias; }
+ if (callReturns) { method.callReturns = callReturns; }
+ if (onGet) { method._get = onGet; }
+ if (onSet) { method._set = onSet; }
+ // eslint-disable-next-line
+ if (onCall != onCall) { method._call = onCall; }
+ }
+
+ /* istanbul ignore next: dev */
+ if (debug) {
+ console.log({
+ name: name,
+ defaultValue: defaultValue,
+ initial: initial,
+ returns: returns,
+ onGet: onGet,
+ onSet: onSet,
+ method: method.toString(),
+ });
+ }
+
+ // ----------------- ;stripped ------------
+
+ // @TODO WOULD ALL BE METHOD.POST
+ // --- could be a method too ---
+ var getterSetter = {get: onGet, set: onSet};
+ var descriptor = shouldDefineGetSet ? getterSetter : {value: method};
+ if (existing) { descriptor = assign(existing, descriptor); }
+
+ // [TypeError: Invalid property descriptor.
+ // Cannot both specify accessors and a value or writable attribute, #]
+ if (descriptor.value && descriptor.get) {
+ delete descriptor.value;
+ }
+ if (!_undefined(descriptor.writable)) {
+ delete descriptor.writable;
+ }
+
+ var target = this.get('target') || parent;
+
+ define(target, name, descriptor);
+
+ if (shouldAddGetterSetter) {
+ if (target.meta) { target.meta(shorthands, name, onSet); }
+ getSetFactory(target, name, getterSetter);
+ }
+
+ aliasFactory(name, target, alias);
+
+ // if (built.metadata) {
+ // target.meta(SHORTHANDS_KEY, name, set)
+ // }
+ // require('fliplog')
+ // .bold('decorate')
+ // .data({
+ // // t: this,
+ // descriptor,
+ // shouldDefineGetSet,
+ // method,
+ // str: method.toString(),
+ // // target,
+ // name,
+ // })
+ // .echo()
+ };
+
+ // ---
+
+ /**
+ * @desc add methods to the parent for easier chaining
+ * @alias extendParent
+ * @memberOf MethodChain
+ *
+ * @since 4.0.0-beta.1 <- moved to plugin
+ * @since 4.0.0 <- moved from Extend
+ * @since 1.0.0
+ *
+ * @param {Object} [parentToDecorate=undefined] decorate a specific parent shorthand
+ * @return {ChainedMap} @chainable
+ *
+ * @see plugins/decorate
+ * @see ChainedMap.parent
+ *
+ * @example
+ *
+ * var obj = {}
+ * new MethodChain({}).name('eh').decorate(obj).build()
+ * typeof obj.eh
+ * //=> 'function'
+ *
+ * @example
+ *
+ * class Decorator extends Chain {
+ * constructor(parent) {
+ * super(parent)
+ * this.methods(['easy']).decorate(parent).build()
+ * this.methods('advanced')
+ * .onCall(this.advanced.bind(this))
+ * .decorate(parent)
+ * .build()
+ * }
+ * advanced(arg) {
+ * this.set('advanced', arg)
+ * return this.parent
+ * }
+ * easy(arg) {
+ * this.parent.set('easy-peasy', arg)
+ * }
+ * }
+ *
+ * class Master extends Chain {
+ * constructor(parent) {
+ * super(parent)
+ * this.eh = new Decorator(this)
+ * }
+ * }
+ *
+ * const master = new Master()
+ *
+ * master.get('easy-peasy')
+ * //=> true
+ *
+ * master.eh.get('advanced')
+ * //=> 'a+'
+ *
+ * @example
+ *
+ * +chain.method('ehOh').decorate(null)
+ * //=> @throws Error('must provide parent argument')
+ *
+ */
+ MethodChain.prototype.decorate = function decorate$$1 (parentToDecorate) {
+ /* istanbul ignore next: devs */
+ if (dev) {
+ if (!(parentToDecorate || this.parent.parent)) {
+ throw new Error('must provide parent argument')
+ }
+ }
+ return decorate.call(this, parentToDecorate || this.parent.parent)
+ };
+
+ /**
+ * @desc adds a plugin to increment the value on every call
+ * @modifies this.initial
+ * @modifies this.onCall
+ *
+ * @memberOf MethodChain
+ * @version 4.0.0-beta.1 <- moved to plugin
+ * @version 4.0.0 <- renamed from .extendIncrement
+ * @since 0.4.0
+ *
+ * @return {MethodChain} @chainable
+ *
+ * @see plugins/autoIncrement
+ *
+ * @example
+ *
+ * chain.methods(['index']).autoIncrement().build().index().index(+1).index()
+ * chain.get('index')
+ * //=> 3
+ *
+ */
+ MethodChain.prototype.autoIncrement = function autoIncrement$$1 () {
+ return this.plugin(autoIncrement)
+ };
+
+ return MethodChain;
+ }(ChainedMapBase));
+
+ /**
+ * @desc add methodFactories easily
+ * @static
+ * @since 4.0.0-beta.2
+ *
+ * @param {Object} methodFactory factories to add
+ * @return {void}
+ *
+ * @example
+ *
+ * function autoGetSet(name, parent) {
+ * const auto = arg =>
+ * (isUndefined(arg) ? parent.get(name) : parent.set(name, arg))
+ *
+ * //so we know if we defaulted them
+ * auto.autoGetSet = true
+ * return this.onSet(auto).onGet(auto).onCall(auto)
+ * }
+ * MethodChain.addPlugin({autoGetSet})
+ *
+ *
+ * const chain = new Chain()
+ * chain.methods('eh').autoGetSet().build()
+ *
+ * chain.eh(1)
+ * //=> chain
+ * chain.eh()
+ * //=> 1 *
+ *
+ */
+ MethodChain.add = function addMethodFactories(methodFactory) {
+ assign(methodFactories, methodFactory);
+ };
+ methodFactories = MethodChain.add;
+
+ var MethodChain_1 = MethodChain;
+
+ /* ___filename___: dist/deps/is/mapish.js */
+
+
+
+ /**
+ * @func isMapish
+ *
+ * @memberOf is
+ * @since 3.0.0
+ * @extends isMap
+ * @variation also checks `instanceof Chainable`
+ *
+ * @param {*} x value to check
+ * @return {boolean} isMapish
+ *
+ * @example
+ *
+ * isMapish(new Map)
+ * //=> true
+ *
+ * isMapish(new Chain)
+ * //=> true
+ *
+ * isMapish({})
+ * //=> false
+ *
+ * isMapish(1)
+ * //=> false
+ *
+ */
+ var mapish = function (x) { return map(x) || x instanceof Chainable; };
+
+ /* ___filename___: dist/MethodChain.js */
+
+ /* ___filename___: dist/deps/is/mapish.js */
+
+ /* ___filename___: dist/MergeChain.js */
+ /* eslint complexity: "OFF" */
+
+
+
+
+
+
+
+
+
+
+
+
+ var ON_EXISTING_KEY = 'onExisting';
+ var ON_VALUE_KEY = 'onValue';
+ var MERGER_KEY = 'merger';
+ var MERGER_OPTIONS_KEY = 'opts';
+ var OBJ_KEY = 'obj';
+
+ /**
+ * @since 1.0.0
+ * @type {Map}
+ * @extends {ChainedMapBase}
+ * @member MergeChain
+ * @memberOf Chainable
+ *
+ * @types MergeChain
+ * @tests MergeChain
+ * @see deps/dopemerge
+ *
+ * {@link https://sourcemaking.com/design_patterns/visitor visitor-pattern}
+ *
+ * @TODO consider just making this a function,
+ * because 80/20 onValue merger & onExisting
+ * are rarely used & are easily overridable with .merge
+ */
+ var MergeChain = (function (ChainedMapBase$$1) {
+ function MergeChain(parent) {
+ ChainedMapBase$$1.call(this, parent);
+
+ /* prettier-ignore */
+ this
+ .extend([ON_EXISTING_KEY, ON_VALUE_KEY, OBJ_KEY])
+ .set(ON_VALUE_KEY, function () { return true; })
+ .set(MERGER_KEY, index$2);
+ }
+
+ if ( ChainedMapBase$$1 ) MergeChain.__proto__ = ChainedMapBase$$1;
+ MergeChain.prototype = Object.create( ChainedMapBase$$1 && ChainedMapBase$$1.prototype );
+ MergeChain.prototype.constructor = MergeChain;
+
+ /**
+ * @desc options for merging with dopemerge
+ * @modifies this.merger | this.opts
+ *
+ * @memberOf MergeChain
+ * @since 1.0.2
+ * @param {Object | Function} opts when object: options for the merger. when function: is the merger
+ * @return {MergeChain} @chainable
+ * @see dopemerge
+ *
+ * @example
+ * {
+ * stringToArray: true,
+ * boolToArray: false,
+ * boolAsRight: true,
+ * ignoreTypes: ['null', 'undefined', 'NaN'],
+ * debug: false,
+ * }
+ *
+ * @example
+ * .merger(require('lodash.mergewith')())
+ */
+ MergeChain.init = function init (parent) {
+ return new MergeChain(parent)
+ };
+
+ MergeChain.prototype.merger = function merger (opts) {
+ if (_function(opts)) { return this.set(MERGER_KEY, opts) }
+ return this.set(MERGER_OPTIONS_KEY, opts)
+ };
+
+ // [v] messes comments on conditional brace style
+ /* prettier-ignore */
+ /**
+ * @desc merges object in, goes through all keys, checks cbs, dopemerges
+ *
+ * @since 1.0.0
+ *
+ * @param {Object} [obj2=undefined] object to merge in, defaults to this.get('obj')
+ * @return {MergeChain} @chainable
+ *
+ * @see ChainedMap
+ * @TODO issue here if we extend without shorthands &
+ * we want to merge existing values... :s
+ *
+ *
+ * @example
+ *
+ * const chain = new Chain()
+ * chain.merge({canada: {eh: true}})
+ * chain.merge({canada: {arr: [0, {'1': 2}], eh: {again: true}}})
+ * chain.entries()
+ * //=> {canada:{ eh: {again: true}, arr: [0, {'1': 2}] }}
+ *
+ */
+ MergeChain.prototype.merge = function merge (obj2) {
+ var this$1 = this;
+
+ // better uglifying
+ var parent = this.parent;
+ var get = function (key) { return this$1.get(key); };
+
+ var onExisting = get(ON_EXISTING_KEY);
+ var onValue = get(ON_VALUE_KEY);
+ var opts = get(MERGER_OPTIONS_KEY);
+ var obj = obj2 || get(OBJ_KEY);
+ var merger = get(MERGER_KEY);
+ var shorthands$$1 = parent.meta ? parent.meta(shorthands) : {};
+ var keys$$1 = keys(obj);
+
+ // @@debugger
+
+ /* istanbul ignore next: devs */
+ if (dev) {
+ if (!obj) {
+ console.log({onExisting: onExisting, opts: opts, obj: obj, merger: merger, shorthands: shorthands$$1, keys: keys$$1, parent: parent});
+ throw new Error('must provide an object to merge')
+ }
+ }
+
+ /**
+ * @private
+ *
+ * since this would be slower
+ * if I want to not have a speedy default when using .onExisting
+ * should @note to use .extend
+ * when using chains without a class & doing .merge (edge-case)
+ *
+ * @param {Primitive} key key (shorthands[key] or just key)
+ * @param {*} value obj[key]
+ * @return {void}
+ *
+ * @TODO could use .eq here
+ * @TODO if (isMapish(obj)) obj = obj.entries()
+ *
+ * @example
+ * var obj = {key: 1}
+ *
+ * MergeChain.init(obj).merge({key: ['value']})
+ *
+ * // goes to this internal scoped function
+ * handleExisting('key', ['value'])
+ * // if there is .onValue or .onExisting, use them, default deepmerge
+ *
+ * obj
+ * //=> {key: [1, 'value']}
+ *
+ */
+ var handleExisting = function (key, value) {
+ /**
+ * @desc when fn is a full method, not an extended shorthand
+ * @since 0.5.0
+ *
+ * @param {Primitive} keyToSet key we chose to set
+ * @param {*} valueToSet value we chose to set (merged, existing, new)
+ * @return {Parent | Chain | *} .set or [keyToSet] return
+ *
+ * @example
+ *
+ * MergeChain.init(new Chain().extend(['eh']))
+ *
+ * //isFunction: true => call parent[keyToSet](valueToSet)
+ * setChosen('eh', 1)
+ * //=> parent
+ * parent.get('eh')
+ * //=> 1
+ *
+ * //=>isFunction: false => parent.set(keyToSet, valueToSet)
+ * setChosen('oh', 1)
+ * //=> parent //<- unless .set is overriden
+ * parent.get('oh')
+ * //=> 1
+ *
+ */
+ var setChosen = function (keyToSet, valueToSet) { return (_function(parent[key])
+ ? parent[keyToSet](valueToSet)
+ : parent.set(keyToSet, valueToSet)); };
+
+ /**
+ * check if it's shorthanded
+ * -> check if it has a value already
+ */
+ if (_true(parent.has(key))) {
+ // get that value
+ var existing = parent.get(key);
+
+ /**
+ * if we have onExisting, call it
+ * else default to dopemerge
+ */
+ if (_undefined(onExisting)) {
+ /* istanbul ignore next: devs */
+ if (debug) {
+ console.log(
+ 'parent has: no onExisting',
+ {existing: existing, [key]: value}
+ );
+ }
+ setChosen(key, merger(existing, value, opts));
+ }
+ else {
+ /* istanbul ignore next: devs */
+ if (debug) {
+ console.log(
+ 'parent has: has onExisting',
+ {existing: existing, onExisting: onExisting, [key]: value}
+ );
+ }
+
+ /**
+ * maybe we should not even have `.onExisting`
+ * since we can just override merge method...
+ * and then client can just use a custom merger...
+ *
+ * could add and remove subscriber but that's overhead and
+ * tricky here, because if we set a value that was just set...
+ */
+ setChosen(key, onExisting(existing, value, opts));
+ }
+ }
+ else {
+ /* istanbul ignore next: devs */
+ if (debug) {
+ console.log('parent does not have', {[key]: value});
+ }
+ setChosen(key, value);
+ }
+ };
+
+ for (var k = 0, len = keys$$1.length; k < len; k++) {
+ // key to the current property in the data being merged
+ var key = keys$$1[k];
+
+ // we have our value, no we can change the key if needed for shorthands
+ var value = obj[key];
+
+ // @NOTE: when shorthands is an object, key is the method it should call
+ if (!_undefined(shorthands$$1[key]) && shorthands$$1[key] !== key) {
+ /* istanbul ignore next: devs */
+ if (debug) {
+ console.log(
+ 'had a shorthand with a diff key than the object (likely @alias)',
+ {shorthandMethod: shorthands$$1[key], key: key, value: value}
+ );
+ }
+ key = shorthands$$1[key];
+ }
+
+ // method for the key
+ var method = parent[key];
+
+ /* istanbul ignore next: sourcemaps trigger istanbul here incorrectly */
+ // use onValue when set
+ if (!onValue(value, key, this$1)) {
+ /* istanbul ignore next: devs */
+ if (debug) {
+ console.log('had onValue, was false, ignored', {onValue: onValue, key: key, value: value});
+ }
+ continue
+ }
+ // when property itself is a Chainable
+ else if (mapish(method)) {
+ /* istanbul ignore next: devs */
+ if (debug) {
+ console.log('has method or shorthand');
+ }
+ parent[key].merge(value);
+ }
+ // we have a method or shorthand
+ else if (method) {
+ /* istanbul ignore next: devs */
+ if (debug) {
+ console.log('has method or shorthand', {method: method, key: key, value: value});
+ }
+ handleExisting(key, value);
+ }
+ // default to .set on the store
+ else {
+ /* istanbul ignore next: devs */
+ if (debug) {
+ console.log('went to default', {method: method, key: key, value: value});
+ }
+ parent.set(key, value);
+ }
+ }
+
+ return parent
+ };
+
+ return MergeChain;
+ }(ChainedMapBase));
+
+ /**
+ * @memberOf MergeChain
+ * @method onExisting
+ * @since 0.9.0
+ * @example
+ *
+ * const {Chain, MergeChain} = require('chain-able')
+ *
+ * const chain = new Chain().set('str', 'stringy')
+ *
+ * MergeChain.init(chain)
+ * .onExisting((a, b) => a + b)
+ * .merge({str: '+'})
+ *
+ * chain.get('str')
+ * //=> 'stringy+'
+ *
+ */
+
+ var MergeChain_1 = MergeChain;
+
+ // @TODO re-enable this later
+ // module.exports = new MethodChain(MergeChain.prototype)
+ // .methods(['onExisting', 'onValue', 'obj'])
+ // .build(MergeChain)
+
+ /* ___filename___: dist/MergeChain.js */
+
+ /* ___filename___: dist/ChainedMap.js */
+
+
+
+
+
+ /**
+ * @desc ChainedMap composer
+ * @category Chainable
+ * @category Map
+ * @memberOf ChainedMapBase
+ * @class ChainedMap
+ * @since 0.0.1
+ * @alias ComposeMap
+ * @extends {ChainedMapBase}
+ *
+ * @param {Class | Object | Composable} [SuperClass=ChainedMapBase] class to extend
+ * @return {Class} ChainedMap
+ *
+ * @see ChainedMapBase
+ * @tests ChainedMap
+ * @types ChainedMap
+ *
+ * @example
+ *
+ * const heh = class {}
+ * const composed = ChainedMap.compose(heh)
+ * const hehchain = new Composed()
+ * hehchain instanceof heh
+ * //=> true
+ *
+ */
+
+ var ComposeChainedMap = function (SuperClass) {
+ var Composed =
+ SuperClass === ChainedMapBase
+ ? SuperClass
+ : ChainedMapBase.compose(SuperClass);
+
+ var ChainedMap = (function (Composed) {
+ function ChainedMap () {
+ Composed.apply(this, arguments);
+ }
+
+ if ( Composed ) ChainedMap.__proto__ = Composed;
+ ChainedMap.prototype = Object.create( Composed && Composed.prototype );
+ ChainedMap.prototype.constructor = ChainedMap;
+
+ ChainedMap.prototype.methods = function methods (names) { return this.method(names) };
+
+ /**
+ * @desc the way to easily start building methods when using chainable instances
+ *
+ * @since 4.0.0
+ * @category methods
+ * @alias methods
+ *
+ * @param {string | Array | Primitive} names method names to add to the object
+ * @return {MethodChain} @chainable
+ *
+ * @see MethodChain
+ *
+ * @example
+ *
+ * const chain = new Chain()
+ * chain.method('eh').build()
+ * chain.eh(true)
+ * chain.get('eh')
+ * // => true
+ *
+ */
+ ChainedMap.prototype.method = function method (names) {
+ return new MethodChain_1(this).name(names)
+ };
+
+ /**
+ * @desc merges an object with the current store
+ * @since 0.4.0
+ * @category merge
+ *
+ * @param {Object} obj object to merge
+ * @param {Function | null} [handleMergeFn=undefined] return the merger to the callback
+ * @return {ChainedMap} @chainable
+ *
+ * @TODO needs to pass in additional opts somehow...
+ * @see deps/dopemerge
+ * @see MergeChain
+ *
+ * @example
+ *
+ * const chain = new Chain()
+ * chain.set('eh', [1])
+ * chain.merge({eh: [2]})
+ * chain.get('eh')
+ * // => [1, 2]
+ *
+ * @example
+ *
+ * const chain = new Chain()
+ * chain.set('emptyArr', [])
+ * chain.merge({emptyArr: []}, mergeChain =>
+ * mergeChain.onExisting((a, b) => []).merger((a, b) => []).merge()
+ * )
+ * chain.get('emptyArr').length)
+ * //=> 0
+ *
+ */
+ ChainedMap.prototype.merge = function merge (obj, handleMergeFn) {
+ var merger = MergeChain_1.init(this);
+
+ if (_undefined(handleMergeFn)) {
+ merger.merge(obj);
+ }
+ else {
+ handleMergeFn(merger.obj(obj));
+ }
+
+ return this
+ };
+
+ return ChainedMap;
+ }(Composed));
+
+ return ChainedMap
+ };
+
+ var composed = ComposeChainedMap(ChainedMapBase);
+ composed.compose = ComposeChainedMap;
+
+ var ChainedMap = composed;
+
+ /* ___filename___: dist/ChainedSet.js */
+
+
+
+ /**
+ * @class
+ * @category Chainable
+ * @category Set
+ * @memberOf Chainable
+ * @member ChainedSet
+ *
+ * @TODO could add .first .last ?
+ * @NOTE had Symbol.isConcatSpreadable but it was not useful
+ *
+ * @tutorial https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set
+ * @see http://2ality.com/2015/09/well-known-symbols-es6.html
+ * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/isConcatSpreadable
+ * @see Chainable
+ * @tests ChainedSet
+ * @types ChainedSet
+ *
+ * @extends {Chainable}
+ * @prop {Set} store
+ * @type {Set}
+ */
+ var ChainedSet = (function (Chainable$$2) {
+ function ChainedSet(parent) {
+ Chainable$$2.call(this, parent);
+ this.store = new Set();
+ }
+
+ if ( Chainable$$2 ) ChainedSet.__proto__ = Chainable$$2;
+ ChainedSet.prototype = Object.create( Chainable$$2 && Chainable$$2.prototype );
+ ChainedSet.prototype.constructor = ChainedSet;
+
+ /**
+ * @desc appends a new element with a specified value to the end of the .store
+ * @memberOf ChainedSet
+ * @since 0.4.0
+ *
+ * @param {any} value any value to add to **end** of the store
+ * @return {ChainedSet} @chainable
+ *
+ * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/add mozilla-set-add}
+ * {@link https://github.com/lodash/lodash/blob/master/.internal/addSetEntry.js#L9 lodash-add-set-entry}
+ * @see {@link mozilla-set-add}
+ * @see {@link lodash-add-set-entry}
+ *
+ * @example
+ *
+ * const people = new ChainedSet()
+ * people
+ * .add('sam')
+ * .add('sue')
+ *
+ * for (let name of people) console.log(name)
+ * //=> sam, sue
+ *
+ */
+ ChainedSet.prototype.add = function add (value) {
+ this.store.add(value);
+ return this
+ };
+
+ /**
+ * @desc inserts the value at the **beginning** of the Set
+ * @memberOf ChainedSet
+ * @since 0.4.0
+ *
+ * @param {any} value any value to add to **beginning** the store
+ * @return {ChainedSet} @chainable
+ *
+ * @example
+ *
+ * const people = new ChainedSet()
+ * people
+ * .add('sue')
+ * .prepend('first')
+ *
+ * for (let name of people) console.log(name)
+ * //=> first, sue
+ *
+ */
+ ChainedSet.prototype.prepend = function prepend (value) {
+ this.store = new Set([value].concat(Chainable$$2.prototype.values.call(this)));
+ return this
+ };
+
+ /**
+ * @desc merge any Array/Set/Iteratable/Concatables into the array, at the end
+ * @since 0.4.0
+ * @memberOf ChainedSet
+ *
+ * @param {Array | Set | Concatable} arr values to merge in and append
+ * @return {ChainedSet} @chainable
+ *
+ * @example
+ *
+ * const people = new ChainedSet()
+ * people
+ * .add('sam')
+ * .add('sue')
+ * .prepend('first')
+ * .merge(['merged'])
+ *
+ * for (let name of people) console.log(name)
+ * //=> first, sam, sue, merged
+ *
+ */
+ ChainedSet.prototype.merge = function merge (arr) {
+ var this$1 = this;
+
+ var mergeable = toArr(arr);
+ for (var i = 0; i < mergeable.length; i++) {
+ this$1.store.add(mergeable[i]);
+ }
+ return this
+ };
+
+ return ChainedSet;
+ }(Chainable));
+
+ var ChainedSet_1 = ChainedSet;
+
+ /* ___filename___: dist/ChainedMap.js */
+
+ /* ___filename___: dist/FactoryChain.js */
+
+
+
+
+
+ var ON_CHAIN_UP_DOWN_KEY = 'onChainUpDown';
+ var ON_DONE_KEY = 'onDone';
+
+ /**
+ * @extends {ChainedMapBase}
+ * @inheritdoc
+ * @prop {Object} data
+ * @prop {Set} _calls
+ * @type {Map}
+ *
+ * {@link http://robdodson.me/javascript-design-patterns-factory/ abstract-factory-pattern}
+ *
+ * @member FactoryChain
+ * @category Chainable
+ * @tests FactoryChain
+ * @types FactoryChain
+ */
+ var FactoryChain = (function (ChainedMap$$1) {
+ function FactoryChain(parent) {
+ ChainedMap$$1.call(this, parent);
+
+ this.data = {};
+ this._calls = new Set();
+
+ this.factory()
+ .extend(['optional', 'required', ON_CHAIN_UP_DOWN_KEY, ON_DONE_KEY])
+ .set('len', 0);
+ }
+
+ if ( ChainedMap$$1 ) FactoryChain.__proto__ = ChainedMap$$1;
+ FactoryChain.prototype = Object.create( ChainedMap$$1 && ChainedMap$$1.prototype );
+ FactoryChain.prototype.constructor = FactoryChain;
+
+ /**
+ * @desc chain back up to parent for any of these
+ * @since 2.0.0
+ *
+ * @param {Array} methods methods to trigger `onChainUpDown` on
+ * @return {FactoryChain} @chainable
+ *
+ * @memberOf FactoryChain
+ * @emits onChainUpDown
+ * @TODO should have a debug log for this
+ *
+ * @example
+ *
+ * const {Chain, FactoryChain, ChainedSet} = require('chain-able')
+ *
+ * class Things extends Chain {
+ * constructor(parent) {
+ * super(parent)
+ * this.people = new ChainedSet(this)
+ * }
+ * person() {
+ * const person = new FactoryChain(this)
+ * person
+ * .props(['name', 'age', 'email'])
+ * .onChainUpDown(this.person)
+ * .chainUpDowns(['person'])
+ * .onDone(personChain => {
+ * this.people.add(personChain)
+ * return this
+ * })
+ *
+ * return person
+ * }
+ * }
+ *
+ * const things = new Things()
+ * const returned = things
+ * .person()
+ * .name('sue')
+ * .person()
+ * .age(100)
+ * .name('john')
+ * .email('@')
+ *
+ */
+ FactoryChain.prototype.chainUpDowns = function chainUpDowns (methods) {
+ var arguments$1 = arguments;
+ var this$1 = this;
+
+ methods.forEach(function (m) {
+ this$1[m] = function () {
+ // @@debugger
+ this$1.end();
+ return this$1.parent[m].apply(this$1.parent, arguments$1)
+ };
+ });
+ return this
+ };
+
+ /**
+ * @desc adds an *array* of properties, using FactoryChain.prop
+ * @since 2.0.0
+ *
+ * @memberOf FactoryChain
+ * @param {Array} names property names
+ * @return {FactoryChain} @chainable
+ *
+ * @see FactoryChain.prop
+ *
+ * @example
+ *
+ * person.props(['name', 'age', 'email'])
+ *
+ * typeof person.name
+ * //=> 'function'
+ *
+ * person.name().age()
+ * //=> FactoryChain
+ *
+ * person.name().age().email()
+ * //=> ParentChain
+ *
+ * // person.name().age().person()
+ * //=> FactoryChain
+ * //^ because .person is `chainUpDowns`
+ * //^ so it finishes the old chain, and begins a new one
+ *
+ */
+ FactoryChain.prototype.props = function props (names) {
+ var this$1 = this;
+
+ names.forEach(function (name) { return this$1.prop(name); });
+ return this
+ };
+
+ /* istanbul ignore next: sourcemaps trigger istanbul here incorrectly */
+ /**
+ * @desc add property that are counted towards the call count for easy auto-ending chaining
+ * @since 2.0.0
+ *
+ * @param {Primitive} name property name
+ * @param {Function | null | undefined} [onCall=undefined] callback for the property
+ * @return {FactoryChain} @chainable
+ *
+ * @memberOf FactoryChain
+ *
+ * @example
+ *
+ * person
+ * //.prop also accepts an optional callback,
+ * //for nestable nestable chains
+ * .prop('name')
+ * .prop('age')
+ * .prop('email')
+ *
+ */
+ FactoryChain.prototype.prop = function prop (name, onCall) {
+ var this$1 = this;
+
+ this.tap('len', function (len) { return len + 1; });
+
+ // so if we call a property twice,
+ // chain back up to parent,
+ // add a new chain
+ if (!_undefined(this[name]) && _true(this.has(ON_CHAIN_UP_DOWN_KEY))) {
+ this.end();
+ return this.get(ON_CHAIN_UP_DOWN_KEY)()[name](onCall)
+ }
+
+ // @TODO need to spread as needed
+ this[name] = function (args) {
+ // @@debugger
+ /* istanbul ignore next: devs */
+ if (debug) {
+ console.log(
+ ("called " + name + " with:"),
+ args,
+ "calls length is now:",
+ this$1._calls.size
+ );
+ }
+ if (_undefined(onCall)) { this$1.data[name] = args; }
+ else { onCall(args); }
+
+ this$1._calls.add(name);
+
+ // aka magicReturn
+ return this$1._calls.size === this$1.get('len') ? this$1.end() : this$1
+ };
+ return this
+ };
+
+ /**
+ * @desc access data being built when stepping through a factory
+ * @since 2.0.0
+ *
+ * @param {Primitive} [prop=undefined] key of the data, or returns all data
+ * @return {any} this.data
+ *
+ * @memberOf FactoryChain
+ *
+ * @example
+ *
+ * .data['prop'] = 'eh'
+ * .getData('prop')
+ * //=> 'eh'
+ * .getData()
+ * //=> {prop: 'eh'}
+ *
+ * @example
+ *
+ * const person = new FactoryChain(this)
+ * const age = person.props(['name', 'age']).age(10).getData('age')
+ * expect(age).toBe(10)
+ *
+ */
+ FactoryChain.prototype.getData = function getData (prop) {
+ /* istanbul ignore next: sourcemaps trigger istanbul here incorrectly */
+ return _undefined(prop) ? this.data : this.data[prop]
+ };
+
+ /* istanbul ignore next: sourcemaps trigger istanbul here incorrectly */
+ /**
+ * @desc creates/add the `.end` method,
+ * which checks how many methods have been called,
+ * and decides whether to return parent or not
+ * @modifies this.end
+ *
+ * @since 2.0.0
+ *
+ * @param {Object} [obj={}] optional object to use for creating .end
+ * @return {FactoryChain} @chainable
+ *
+ * @memberOf FactoryChain
+ */
+ FactoryChain.prototype.factory = function factory (obj) {
+ var this$1 = this;
+
+ this.end = function (arg) {
+ // @@debugger
+ var ended;
+
+ if (obj && !_undefined(obj.end)) { ended = obj.end; }
+ else if (this$1.has(ON_DONE_KEY)) { ended = this$1.get(ON_DONE_KEY); }
+
+ if (ended) { ended = ended.call(this$1, this$1.data, this$1.parent, this$1, arg); }
+
+ if (ended && ended !== this$1) { return ended }
+ else { return this$1.parent }
+ };
+
+ return this
+ };
+
+ return FactoryChain;
+ }(ChainedMap));
+
+ var FactoryChain_1 = FactoryChain;
+
+ /* ___filename___: dist/deps/fp/pipe.js */
+ /**
+ * Performs left-to-right function composition. The leftmost function may have
+ * any arity; the remaining functions must be unary.
+ *
+ * In some libraries this function is named `sequence`.
+ *
+ * @NOTE The result of pipe is not automatically curried.
+ * @NOTE This is a variation, is the internal version with only 2 functions, for now
+ *
+ * @func
+ * @memberOf fp
+ * @since v5.0.0
+ * @category Function
+ * @sig (((a, b, ..., n) -> o), (o -> p), ..., (x -> y), (y -> z)) -> ((a, b, ..., n) -> z)
+ * @symb R.pipe(f, g, h)(a, b) = h(g(f(a, b)))
+ *
+ * @param {...Function} f function first
+ * @param {...Function} g function next
+ * @return {Function}
+ *
+ * @see R.compose
+ * @see https://github.com/ramda/ramda/blob/master/src/pipe.js
+ *
+ * @example
+ *
+ * var f = R.pipe(Math.pow, R.negate, R.inc);
+ * f(3, 4); // -(3^4) + 1
+ *
+ */
+ var pipe = function _pipe(f, g) {
+ return function() {
+ return g.call(this, f.apply(this, arguments))
+ }
+ };
+
+ /* ___filename___: dist/deps/matcher/escape-string-regex.js */
+
+
+ /**
+ * @func escapeStringRegExp
+ * @module escape-string-regexp
+ * @memberOf matcher
+ * @since 3.0.0
+ *
+ * @param {string} str string to escape
+ * @return {string} escaped string
+ *
+ * {@link https://github.com/sindresorhus/escape-string-regexp escape-string-regexp}
+ * @see {@link escape-string-regexp *} 🍴
+ * @see fp/replace
+ *
+ * @NOTE also as const escapeStringRegexp = require('escape-string-regexp');
+ *
+ * @example
+ *
+ * const escaped = escapeStringRegexp('how much $ for a unicorn?');
+ * //=> 'how much \$ for a unicorn\?'
+ * new RegExp(escaped);
+ *
+ */
+ var escapeStringRegex = replace(/[|\\{}()[\]^$+*?.]/g, '\\$&');
+
+ /* ___filename___: dist/deps/fp/pipe.js */
+
+ /* ___filename___: dist/deps/matcher/escape-string-regex.js */
+
+ /* ___filename___: dist/deps/matcher/to-regexp.js */
+
+
+
+
+ /**
+ * @func toRegExp
+ * @memberOf matcher
+ * @module to-regexp
+ * @extends escapeStringRegExp
+ *
+ * @param {string} str string to escape
+ * @return {string} escaped str
+ *
+ * @example
+ *
+ * toRegExp('*')
+ * => '.*'
+ *
+ * toRegExp('eh')
+ * => 'eh'
+ *
+ */
+ var toRegexp = pipe(escapeStringRegex, replace(/\\\*/g, '.*'));
+
+ /* ___filename___: dist/deps/matcher/to-regexp.js */
+
+ /* ___filename___: dist/deps/matcher/matcher.js */
+ /**
+ * @name matcher
+ * @member matcher
+ * @see https://github.com/sindresorhus/matcher/blob/master/index.js
+ * @symb 🎯
+ * @types matcher
+ * @tests deps/matcher
+ */
+
+
+
+
+
+
+ var m = {};
+
+ /**
+ * @desc turn any string[], function[], or RegExp[] into a matcher
+ * @memberOf matcher
+ * @since 3.0.0
+ * @func make
+ *
+ * @param {Array | string | Function | RegExp} pattern a matchable pattern
+ * @param {boolean | undefined} shouldNegate turn into a negated regex
+ * @param {boolean | undefined} alphaOmega should have regex start at the beginning and the end
+ * @return {Array | string | Function | RegExp} matchable
+ *
+ * @example
+ *
+ * matcher.make('*')
+ * //=> RegExp('.*', 'i')
+ *
+ * @example
+ *
+ * var any = new RgExp('.*', 'i')
+ * matcher.make(any)
+ * //=> any
+ *
+ * @example
+ *
+ * var strings = x => typeof x === 'string'
+ * matcher.make(strings)
+ * // {test: strings}
+ *
+ * @example
+ *
+ * var tester = {test: x => x === true}
+ * matcher.make(tester)
+ * // tester
+ *
+ * @example
+ *
+ * var noName = '!name'
+ * matcher.make(noName, true)
+ * // new RegExp('(?:name)', 'i')
+ *
+ * @example
+ *
+ * var noName = '!name'
+ * matcher.make(noName, true, true)
+ * // new RegExp('^(?:name)$', 'i')
+ *
+ */
+ m.make = function (pattern, shouldNegate, alphaOmega) {
+ if (index$10.has(pattern)) { return index$10.get(pattern) }
+
+ var matchable = pattern;
+ if (matcher(matchable) && !matchable.test) { matchable.test = matchable; }
+ if (matcher(matchable)) { return matchable }
+
+ // if (!matchable) {
+ // console.log({pattern, shouldNegate, alphaOmega})
+ // throw new Error('eh')
+ // }
+ var negated = matchable[0] === '!';
+ if (negated) { matchable = matchable.slice(1); }
+ matchable = toRegexp(matchable);
+
+ if (negated && shouldNegate) { matchable = "(?!" + matchable + ")"; }
+ if (alphaOmega) { matchable = "^" + matchable + "$"; }
+
+ matchable = new RegExp(("" + matchable), 'i');
+ matchable.negated = negated;
+
+ index$10.set(pattern, matchable);
+ return matchable
+ };
+
+ /**
+ * @desc same as .make but also accepts inputs, and returns an array
+ * @memberOf matcher
+ * @func match
+ * @since 3.0.0
+ *
+ * @param {Array | string} inputs input to use patterns as predicates on
+ * @param {Array | string | Function | RegExp} patterns predicates to match with, transformed to Matcher
+ * @param {boolean | undefined} shouldNegate should negate, passed to matcher.make
+ * @param {boolean | undefined} alphaOmega should enforce regex @beginning and end, passed to .matcher
+ * @return {Array}
+ *
+ * @see Matcher.make
+ * @see compose/Observe
+ *
+ * @example
+ *
+ *
+ * matcher(['foo', 'bar', 'moo'], ['*oo', '!foo']);
+ * //=> ['moo']
+ *
+ * matcher(['foo', 'bar', 'moo'], ['!*oo']);
+ *
+ *
+ * @example
+ *
+ *
+ * matcher('kinga', 'kinga')
+ * //=> ['kinga']
+ * matcher('k*nga', 'kinga')
+ * //=> ['kinga']
+ * matcher('kinga', 'nope')
+ * //=> []
+ *
+ * matcher(new RegExp(/kinga/), 'kinga')
+ * //=> ['kinga']
+ * matcher(new RegExp(/kinga/), 'nope')
+ * //=> ['nope']
+ *
+ * matcher(x => x === 'kinga', 'kinga')
+ * //=> ['kinga']
+ * matcher(x => x === 'kinga', 'nope')
+ * //=> []
+ *
+ * matcher({test: x => x === 'kinga'}, 'kinga')
+ * //=> ['kinga']
+ * matcher({test: x => x === 'kinga'}, 'nope')
+ * //=> []
+ *
+ *
+ */
+ m.matcher = function (inputs, patterns, shouldNegate, alphaOmega) {
+ patterns = toArr(patterns).map(function (p) { return m.make(p, shouldNegate, alphaOmega); });
+ inputs = toArr(inputs);
+
+ var firstNegated = patterns[0].negated;
+ var matchesToReturn = [];
+
+ for (var i = 0; i < inputs.length; i++) {
+ var input = inputs[i];
+ // If first pattern is negated we include everything to match user expectation
+ var matches = firstNegated;
+ for (var j = 0; j < patterns.length; j++) {
+ if (patterns[j].test(input)) {
+ matches = !patterns[j].negated;
+ }
+ }
+
+ if (matches) { matchesToReturn.push(input); }
+ }
+
+ return matchesToReturn
+ };
+
+ /**
+ * @TODO replace to-test
+ */
+ // m.test = (inputs, patterns) => m.matcher(inputs, patterns).length !== 0
+
+ var matcher$2 = assign(m.matcher, m);
+
+ /* ___filename___: dist/deps/matcher/matcher.js */
+
+ var index$18 = matcher$2;
+
+ /* ___filename___: dist/deps/dot/has.js */
+
+
+
+
+ /**
+ * @name dot.has
+ * @memberOf dot
+ * @func
+ * @since 3.0.0
+ * @extends dot/getPathSegments
+ *
+ * @param {Object} obj the object to retrieve the nested property from.
+ * @param {Dottable | string | Array} path dot-prop-path to use
+ * @return {boolean} has at path
+ *
+ * @example
+ *
+ * dot.has({a: {b: 2}}, 'a.b'); //=> true
+ * dot.has({a: {b: 2}}, ['a', 'b']); //=> true
+ * dot.has({c: {b: 2}}, ['a', 'b']); //=> undefined
+ *
+ */
+ var has$1 = function dotHas(obj$$2, path) {
+ if (!dottable(obj$$2, path)) {
+ return false
+ }
+
+ var pathArr = segments(path);
+
+ for (var i = 0; i < pathArr.length; i++) {
+ if (obj(obj$$2)) {
+ if (!(pathArr[i] in obj$$2)) {
+ return false
+ }
+
+ obj$$2 = obj$$2[pathArr[i]];
+ }
+ else {
+ return false
+ }
+ }
+
+ return true
+ };
+
+ /* ___filename___: dist/deps/dot/delete.js */
+
+
+
+
+
+ /**
+ * @desc delete a path on an object
+ * @name dot.delete
+ * @memberOf dot
+ * @func
+ * @since 3.0.0
+ * @extends dot/getPathSegments
+ *
+ * @param {Object} obj the object to DELETE the nested property from.
+ * @param {Dottable | string | Array} path dot-prop-path to use
+ * @return {void}
+ *
+ *
+ * @example
+ *
+ * dot.get({a: {b: 2}}, 'a.b'); //=> 2
+ * dot.get({a: {b: 2}}, ['a', 'b']); //=> 2
+ * dot.get({c: {b: 2}}, ['a', 'b']); //=> undefined
+ *
+ */
+ var _delete = function dotdelete(obj$$2, path) {
+ if (!dottable(obj$$2, path)) {
+ return
+ }
+
+ var pathArr = segments(path);
+
+ for (var i = 0; i < pathArr.length; i++) {
+ var p = pathArr[i];
+
+ if (i === lengthMinusOne(pathArr)) {
+ delete obj$$2[p];
+ return
+ }
+
+ obj$$2 = obj$$2[p];
+
+ if (!obj(obj$$2)) {
+ return
+ }
+ }
+ };
+
+ /* ___filename___: dist/deps/dot/has.js */
+
+ /* ___filename___: dist/deps/dot/delete.js */
+
+ /* ___filename___: dist/deps/dot/dot-prop.js */
+
+
+
+
+
+ var dotProp = {
+ has: has$1,
+ get: get,
+ set: set$2,
+ delete: _delete,
+ };
+
+ /* ___filename___: dist/deps/dot/dot-prop.js */
+
+ var index$20 = dotProp;
+
+ /* ___filename___: dist/compose/Observe.js */
+
+
+ // const eq = require('../deps/traversers/eq')
+
+
+
+
+
+ var eq$1 = traverse_1.eq;
+
+ /**
+ * scoped clones
+ * @private
+ * @type {Map}
+ */
+ var objs = new Map();
+
+ /**
+ * @desc > subscribe to changes
+ * ❗ called only on **change**
+ * observers are only called when data they subscribe to changes
+ *
+ * @since 3.0.1
+ * @class Observe
+ * @member Observe
+ * @extends {ChainedMap}
+ * @extends {DotProp}
+ * @memberOf compose
+ * @category Chainable
+ *
+ * @param {Class | Composable} Target composable class
+ * @return {Observe} class
+ *
+ * @tests Observe
+ * @types Observe
+ *
+ * @see ChainedMap
+ * @see DotProp
+ * @see deps/matcher
+ * @see deps/traversers/eq
+ * @see deps/traverse
+ * @see DotProp
+ *
+ * {@link https://github.com/iluwatar/java-design-patterns/tree/master/observer observer-pattern}
+ * {@link https://github.com/ReactiveX/rxjs/blob/master/src/Subscriber.ts reactivex}
+ * {@link https://github.com/sindresorhus/awesome-observables awesome-observables}
+ * {@link https://medium.com/@benlesh/learning-observable-by-building-observable-d5da57405d87 building-observables}
+ * {@link https://github.com/addyosmani/essential-js-design-patterns/blob/master/diagrams/observer.png js-observer-png}
+ * {@link https://github.com/addyosmani/essential-js-design-patterns/blob/master/diagrams/publishsubscribe.png pubsub-png}
+ * {@link https://github.com/tusharmath/observable-air observable-air}
+ *
+ * @see {@link reactivex}
+ * @see {@link awesome-observables}
+ * @see {@link building-observables}
+ * @see {@link observer-pattern}
+ * @see {@link observable-air}
+ *
+ * @example
+ *
+ * const {compose} = require('chain-able')
+ * const {DotProp} = compose
+ * new DotProp()
+ * //=> DotProp
+ *
+ */
+ var Observe = function (Target) {
+ // return class Observe extends Target {
+ /**
+ * @desc observe properties when they change
+ *
+ * @method
+ * @memberOf Observe
+ * @since 4.0.0 <- refactored with dot-prop
+ * @since 1.0.0
+ *
+ * @param {Matchable} properties Matchable properties to observe
+ * @param {Function} fn onChanged
+ * @return {Target} @chainable
+ *
+ * @see traversers/eq
+ * @see toarr
+ * @see matcher
+ *
+ * {@link https://jsfiddle.net/wqxuags2/28/ for a Demo Clock with observable}
+ *
+ * @see {@link for a Demo Clock with observable}
+ * @see examples/playground/TodoStore
+ *
+ * @TODO gotta update `data` if `deleting` too...
+ * @TODO un-observe
+ * @TODO should hash these callback properties
+ * @TODO just throttle the `.set` to allow easier version of .commit
+ *
+ * @example
+ *
+ * const Target = require('chain-able')
+ *
+ * const chain = new Target()
+ * const log = arg => console.log(arg)
+ *
+ * chain
+ * .extend(['eh'])
+ * .observe('eh', data => log(data))
+ * .eh(true)
+ * //=> {eh: true}
+ *
+ * @example
+ *
+ * chain
+ * .extend(['canada', 'timbuck'])
+ * .observe(['canad*'], data => console.log(data.canada))
+ * .canada(true)
+ * .canada(true)
+ * .timbuck(false)
+ *
+ * //=> true
+ * //=> false
+ *
+ * // only called when changed,
+ * // otherwise it would be 2 `true` & 1 `false`
+ *
+ */
+ Target.prototype.observe = function chainObserve(properties, fn) {
+ var this$1 = this;
+
+ var props = toArr(properties);
+ var hashKey = props.join('_');
+ var data = {};
+
+ /* prettier-ignore */
+ return this.meta(observers, function (changed) {
+ /**
+ * match the keys, make the data out of it
+ */
+ var m = index$18(changed.key, props);
+
+ // @@debugger
+
+ for (var i = 0; i < m.length; i++) {
+ var segments$$2 = segments(m[i]);
+ index$20.set(data, segments$$2, this$1.get(segments$$2));
+ }
+
+ /**
+ * if we have called it at least once...
+ * and it has not changed, leave it
+ * else
+ * clone it
+ * call the observer
+ */
+ if (objs.has(hashKey) && eq$1(objs.get(hashKey), data)) {
+ // @@debugger
+ return
+ }
+
+ // @@debugger
+
+ /**
+ * it did change - clone it for next deepEquals check
+ */
+ objs.set(hashKey, traverse_1(data).clone());
+
+ /**
+ * call the observer - it matched & data changed
+ */
+ fn.call(this$1, data, this$1);
+ })
+ };
+ return Target
+ };
+
+ /* ___filename___: dist/compose/Shorthands.js */
+ /**
+ * @since 2.0.0
+ */
+
+
+
+
+ /**
+ * @class Shorthands
+ * @member Shorthands
+ * @extends {ChainedMap}
+ * @extends {DotProp}
+ * @memberOf compose
+ * @category Chainable
+ *
+ * @param {Class | Composable} Target composable class
+ * @return {Shorthands} class
+ *
+ * @tests Shorthands
+ * @types Shorthands
+ *
+ * @see ChainedMap
+ * @see DotProp
+ * @see deps/matcher
+ * @see deps/traversers/eq
+ * @see deps/traverse
+ * @see DotProp
+ *
+ * {@link https://github.com/ReactiveX/rxjs/blob/master/src/Subscriber.ts reactivex}
+ * {@link https://github.com/sindresorhus/awesome-observables awesome-observables}
+ * {@link https://medium.com/@benlesh/learning-observable-by-building-observable-d5da57405d87 building-observables}
+ * @see {@link reactivex}
+ * @see {@link awesome-observables}
+ * @see {@link building-observables}
+ *
+ * @example
+ *
+ * const {compose} = require('chain-able')
+ * const {DotProp} = compose
+ * new DotProp()
+ * //=> DotProp
+ *
+ */
+ var Shorthands = function (Target) {
+ return (function (Target) {
+ function Shorthands(parent) {
+ Target.call(this, parent);
+
+ if (parent && parent.meta) {
+ this.meta.debug = parent.meta.debug;
+ }
+ else {
+ this.debug(false);
+ }
+ }
+
+ if ( Target ) Shorthands.__proto__ = Target;
+ Shorthands.prototype = Object.create( Target && Target.prototype );
+ Shorthands.prototype.constructor = Shorthands;
+
+ // https://github.com/fluents/chain-able/issues/32
+ // find(key, data = this.entries(true)) {
+ // let val = null
+ // const matcher = new RegExp(key.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&'))
+ // // console.debug(`key: ${key} `)
+ // const cb = (x, traverser) => {
+ // if (matcher.test(traverser.key) || traverser.path.includes(key)) {
+ // val = x
+ // traverser.stop()
+ // // console.error({x})
+ // }
+ // // console.debug(`path: ${traverser.path.join('.')} prop: ${traverser.key}`)
+ // // console.dir({x, path: traverser.path, key: traverser.key})
+ // }
+ //
+ // traverse(data).forEach(function(x) {
+ // cb(x, this)
+ // })
+ // return val
+ // }
+
+ /**
+ * @desc sets on store not this.set for easier extension
+ *
+ * @since 4.0.0 <- moved from Extend to Shorthands
+ * @since 0.2.0
+ *
+ * @param {boolean} [should=true] shouldDebug
+ * @return {Chainable} @chainable
+ *
+ * @NOTE is inherited by any chain with a parent with .meta.debug
+ *
+ * @example
+ *
+ * const Chain = require('chain-able')
+ * const chain = new Chain()
+ * chain.debug()
+ *
+ * chain.get('debug')
+ * //=> true
+ *
+ * // not in entries
+ * chain.entries()
+ * //=> {}
+ *
+ */
+ Shorthands.prototype.debug = function debug (should) {
+ this.meta.debug = _undefined(should) ? true : should;
+ return this
+ };
+
+ /**
+ * @desc sets a value **only** when .has is false
+ * aka set if the value has not been set
+ *
+ * @memberOf ShorthandChain
+ * @since 1.0.2
+ *
+ * @param {Primitive} name key to set if it has not been done so already
+ * @param {any} value value to set when key has not been already set
+ * @return {ShorthandChain} @chainable
+ *
+ * @see ChainedMapBase.set
+ *
+ * @example
+ *
+ * const chain = new Chain()
+ *
+ * chain.set('eh', true)
+ *
+ * // eh is already set ^, ignored
+ * chain.setIfEmpty('eh', false)
+ *
+ * chain.get('eh')
+ * //=> true
+ *
+ * @example
+ *
+ * new Chain().setIfEmpty('canada', true).entries()
+ * //=> {canada: true}
+ *
+ * @example
+ *
+ * // longhand way to do the same thing
+ * if (chain.has('eh') === false) {
+ * chain.set('eh', false)
+ * }
+ *
+ * // or using .when
+ * chain.when(!chain.has('eh'), instance => instance.set('eh', false))
+ *
+ */
+ Shorthands.prototype.setIfEmpty = function setIfEmpty (name, value) {
+ if (_false(this.has(name))) { return this.set(name, value) }
+ else { return this }
+ };
+
+ /**
+ * @desc returns any value passed in
+ * return a value at the end of a chain regardless
+ *
+ * @memberOf ShorthandChain
+ * @since 3.0.0
+ *
+ * @param {any} value value to return at the end of a chain
+ * @return {any} value
+ *
+ * @example
+ *
+ * const chain = new Chain()
+ *
+ * const saveAndDebug = env => chain
+ * .from({env: env.NODE_ENV})
+ * .return(JSON.stringify(env))
+ *
+ * console.log(saveAndDebug(process.env))
+ * //=> value of process.env
+ */
+ Shorthands.prototype.return = function return$1 (value) {
+ return value
+ };
+
+ /**
+ * @desc wrap a value, if it's a Function call it, return this
+ * aka execute something and return this
+ *
+ * @memberOf ShorthandChain
+ * @since 2.0.0
+ * @param {Function | any} fn function to call, or just any value
+ * @return {ShorthandChain} @chainable
+ *
+ * @example
+ *
+ * const {eh} = chain.wrap(chain => chain.eh = true)
+ * //=> true
+ *
+ * @example
+ *
+ * new Chain()
+ * .wrap(encased => encased.fn = arg => {
+ * throw new Error('encased yo')
+ * })
+ * .method('fn')
+ * .encase()
+ * .catch(error => {
+ * //=> Error('encasedYo')
+ * })
+ * .build()
+ * .fn(true)
+ *
+ */
+ Shorthands.prototype.wrap = function wrap (fn) {
+ if (_function(fn)) { fn.call(this, this); }
+ return this
+ };
+
+ return Shorthands;
+ }(Target))
+ };
+
+ /* ___filename___: dist/deps/matcher/to-test.js */
+
+
+
+
+ /**
+ * @desc like matcher, but .isMatch
+ * @since 3.0.0
+ *
+ * @param {Matchable} matchable any matchable
+ * @param {any} [arg1=undefined] arg to match with
+ * @param {any} [arg2=undefined] optional second arg to pass into tester
+ * @return {boolean} is a match, passes the test
+ *
+ * @NOTE as else-if for easier ternary uglification
+ *
+ * @example
+ *
+ * matcher('kinga', 'kinga')
+ * //=> true
+ * matcher('k*nga', 'kinga')
+ * //=> true
+ * matcher('kinga', 'nope')
+ * //=> false
+ *
+ * matcher(new RegExp(/kinga/), 'kinga')
+ * //=> true
+ * matcher(new RegExp(/kinga/), 'nope')
+ * //=> false
+ *
+ * matcher(x => x === 'kinga', 'kinga')
+ * //=> true
+ * matcher(x => x === 'kinga', 'nope')
+ * //=> false
+ *
+ * matcher({test: x => x === 'kinga'}, 'kinga')
+ * //=> true
+ * matcher({test: x => x === 'kinga'}, 'nope')
+ * //=> false
+ *
+ */
+ var toTest = function (matchable, arg1, arg2) {
+ if (string(matchable)) { return !!new RegExp(escapeStringRegex(matchable)).test(arg1) }
+ else if (_function(matchable) && !matchable.test) { return !!matchable(arg1) }
+ else { return !!matchable.test(arg1, arg2) }
+ };
+
+ /* ___filename___: dist/deps/matcher/to-test.js */
+
+ /* ___filename___: dist/deps/matcher/any-key-val.js */
+
+
+ /**
+ * the original simple to-test matcher for traversable,
+ * will be merged into, or simplified as simplified into matcher
+ *
+ * @since 2.0.0
+ *
+ * @TODO should use matcher,
+ * @TODO should inprove the callback data...
+ *
+ * @types matcher
+ *
+ * @param {Matchable[]} keys matchable keys
+ * @param {Matchable[]} vals matchable values
+ * @return {boolean} matched or not
+ *
+ * @example
+ *
+ * anyKeyVal([], [])(0, 0)
+ * //=> false
+ *
+ * anyKeyVal([() => true], [])(0, 0)
+ * //=> true
+ *
+ */
+ var anyKeyVal = function (keys, vals) { return function (prop, val) {
+ for (var i = 0; i < keys.length; i++) {
+ if (toTest(keys[i], prop, val)) { return true }
+ }
+ for (var i$1 = 0; i$1 < vals.length; i$1++) {
+ if (toTest(vals[i$1], val, prop)) { return true }
+ }
+ return false
+ }; };
+
+ /* ___filename___: dist/deps/matcher/any-key-val.js */
+
+ /* ___filename___: dist/TraverseChain.js */
+
+
+
+
+
+
+ var TRAVERSED_KEY = 1;
+ var EXTENSION_KEYS = ['obj', 'keys', 'vals', 'onNonMatch', 'onMatch', 'clone'];
+
+ /**
+ * @since 1.0.0
+ * @type {Map}
+ * @extends {ChainedMapBase}
+ *
+ * @memberOf Chainable
+ * @member Traverse
+ * @see deps/traverse
+ * @category traverse
+ * @types TraverseChain
+ * @tests TraverseChain
+ * @symb 👣
+ *
+ * @prop {Object} obj
+ * @prop {Array} [keys]
+ * @prop {Array} [vals]
+ * @prop {Function} [onMatch]
+ * @prop {Function} [onNonMatch]
+ * @prop {boolean} [clone]
+ */
+ var TraverseChain = (function (ChainedMapBase$$2) {
+ function Traverser(parent) {
+ ChainedMapBase$$2.call(this, parent);
+ this.call = this.traverse.bind(this);
+
+ /* prettier-ignore */
+ this
+ .extend(EXTENSION_KEYS)
+ .keys([])
+ .vals([])
+ .onMatch(function (arg, traverser) { return traverser.remove(); });
+ }
+
+ if ( ChainedMapBase$$2 ) Traverser.__proto__ = ChainedMapBase$$2;
+ Traverser.prototype = Object.create( ChainedMapBase$$2 && ChainedMapBase$$2.prototype );
+ Traverser.prototype.constructor = Traverser;
+
+ /**
+ * @desc runs traverser, checks the tests, calls the onMatch
+ * @modifies this.cleaned
+ *
+ * @alias call
+ * @since 1.0.0
+ * @param {boolean} [shouldReturn=false] returns traversed object
+ * @return {any} this.obj/data cleaned
+ *
+ * @memberOf TraverseChain
+ *
+ * @example
+ *
+ * const traversed = new Chain()
+ * .merge({flat: 0, one: {two: true}})
+ * .traverse(false)
+ * .vals([/true/])
+ * .onMatch((current, traverser) => {
+ * traverser.path.join('.')
+ * //=> 'one.two'
+ *
+ * current
+ * //=> true
+ *
+ * typeof traverser.update === typeof traverser.remove
+ * typeof traverser.update === 'function'
+ * //=> true
+ *
+ * traverser.remove()
+ * //=> void
+ * })
+ * .onNonMatch(val => {
+ * // ignore
+ * })
+ * .call(true)
+ *
+ * traversed
+ * //=> {flat: 0}
+ *
+ */
+ Traverser.prototype.traverse = function traverse$1 (shouldReturn) {
+ var ref = this.entries();
+ var obj = ref.obj;
+ var keys = ref.keys;
+ var vals = ref.vals;
+ var onMatch = ref.onMatch;
+ var onNonMatch = ref.onNonMatch;
+ var clone = ref.clone;
+ var result = clone ? traverse_1(obj).clone() : obj;
+
+ // diff between keys and val is order of arg in ^ tester
+ var matcher = anyKeyVal(keys, vals);
+
+ /* istanbul ignore next: debug */
+ if (debug) {
+ console.log('matcher for traverse...', keys, vals);
+ }
+
+ // bound to the traverser
+ traverse_1(result).forEach(function(key, x, traverser) {
+ if (traverser.isRoot) {
+ // nothing
+ }
+ else if (matcher(key, x)) {
+ /* istanbul ignore next: debug */
+ if (debug) {
+ console.log('------- match ------- ', key, x);
+ }
+
+ onMatch(x, traverser);
+ }
+ else if (onNonMatch) {
+ /* istanbul ignore next: debug */
+ if (debug) {
+ console.log('------- NONmatch ------- ', key, x);
+ }
+
+ onNonMatch(x, traverser);
+ }
+ });
+
+ this.set(TRAVERSED_KEY, result);
+ return _true(shouldReturn) ? result : this
+ };
+
+ /**
+ * value traversed in traverse
+ * @since 1.0.0
+ * @see TraverseChain.traverse
+ * @return {Object | Array | any} traversed
+ *
+ * @example
+ *
+ * const traverser = new Traverser()
+ * traverser.obj(['duck', 'duck', 'goose'])
+ * traverser.vals(['g**se'])
+ * traverser.traverse()
+ *
+ * traverser.traversed()
+ * //=> ['goose']
+ *
+ * @example
+ *
+ * const eh = {
+ * me: true,
+ * nested: {
+ * really: {
+ * deep: {
+ * super: false,
+ * not: 'eh',
+ * canada: true,
+ * modules: [{parser: 'hi'}],
+ * },
+ * matchme: 'minime',
+ * notme: 'eh',
+ * },
+ * },
+ * }
+ *
+ * const chain = new Chain()
+ * Object.assign(chain, eh)
+ *
+ * const traverser = chain
+ * .merge(eh)
+ * .traverse(true)
+ * .keys([/super/, /parser/, /store/, /meta/])
+ * .vals([/minime/])
+ * .call(false)
+ *
+ * traverser.traversed()
+ * //=> {
+ * className: 'DotProp',
+ * me: true,
+ * nested: {
+ * really: {
+ * deep: {
+ * not: 'eh',
+ * canada: true,
+ * modules: [{}],
+ * },
+ * notme: 'eh',
+ * },
+ * },
+ * }
+ *
+ */
+ Traverser.prototype.traversed = function traversed () {
+ return this.get(TRAVERSED_KEY)
+ };
+
+ return Traverser;
+ }(ChainedMapBase));
+
+ /* ___filename___: dist/TraverseChain.js */
+
+ /* ___filename___: dist/compose/Transform.js */
+
+
+
+
+
+
+
+
+
+
+ /**
+ * @param {Class | Composable} Target composable class
+ * @return {TransformChain} class
+ * @example
+ * compose(class {})
+ * //=> TransformChain
+ */
+ var Transform = function (Target) {
+ var set = Target.prototype.set;
+
+ /**
+ * @class TransformChain
+ * @member TransformChain
+ * @extends {ChainedMap}
+ * @memberOf compose
+ * @category Chainable
+ *
+ * @tests TransformChain
+ * @types TransformChain
+ *
+ * @symb 🤖
+ * @type {Map}
+ *
+ * @see deps/traverse
+ * @see TraverseChain
+ *
+ * {@link https://github.com/iluwatar/java-design-patterns/tree/master/state state-pattern}
+ * {@link https://github.com/iluwatar/java-design-patterns/tree/master/strategy strategy-pattern}
+ */
+ // return class Transform extends Target {
+ // -------------------------------------------
+
+ /**
+ * @desc traverse `this`, or `this.entries`
+ * @since 1.0.2
+ *
+ * @param {boolean | traversable} [useThis=false] use the instance properties that are `mapish` as well
+ * @return {TraverseChain} @chainable
+ *
+ * @see TraverseChain
+ * @see js-traverse
+ *
+ * @example
+ * TAKE FROM TRAVERSECHAIN
+ */
+ Target.prototype.traverse = function traverseChain(useThis) {
+ if ( useThis === void 0 ) useThis = false;
+
+ /* prettier-ignore */
+ return new TraverseChain(this)
+ .obj(_false(useThis)
+ ? this.entries(true)
+ : _true(useThis)
+ ? this
+ : useThis
+ )
+ };
+
+ /**
+ * @since 1.0.2
+ * @memberOf TransformChain
+ *
+ * @param {string | Function} key currently just string
+ * @param {Function} value callback accepting the value as only arg to transform with
+ * @return {TransformChain} @chainable
+ *
+ * @TODO dot-prop here
+ *
+ * @example
+ *
+ * // coerce values with .id into the value they hold
+ * chain
+ * .transform('dis', val => (typeof val === 'string' ? val : val.id))
+ *
+ * chain.set('dis', 'eh')
+ * chain.get('dis')
+ * //=> 'eh'
+ *
+ * chain.set('dis', {id: 'eh'})
+ * chain.get('dis')
+ * //=> 'eh'
+ *
+ *
+ * @example
+ *
+ * import {format} from 'date-fns/esm'
+ * import {Chain} from 'chain-able'
+ *
+ * const chain = new Chain()
+ * chain.transform('created_at', date => format(date, 'MM/DD/YYYY'))
+ * chain.set('created_at', new Date())
+ *
+ * // is formatted human-readable pretty!
+ * const {created_at} = chain.entries()
+ * //=> '02/11/2014'
+ *
+ */
+ Target.prototype.transform = function transform(key, value) {
+ return this.meta(transformers, key, value)
+ };
+
+ /**
+ * @memberOf TransformChain
+ *
+ * @override
+ * @inheritdoc
+ * @since 1.0.0
+ *
+ * @param {Primitive} key key to set with
+ * @param {any} val value to set for key
+ * @param {undefined | string | Array} dotPropKey special key used for initializing dot prop values in an optimized way to keep reference
+ * @return {Chainable} @chainable
+ *
+ * @see this.observe, this.transform
+ */
+ Target.prototype.set = function transformSet(key, val, dotPropKey) {
+ var this$1 = this;
+
+ var value = val;
+
+ // get
+ var transformers$$2 = this.meta(transformers, key);
+ for (var t = 0; t < transformers$$2.length; t++) {
+ value = transformers$$2[t].call(this$1, value, this$1);
+ }
+
+ // super.set(key, value)
+ set.call(this, key, value);
+
+ // get
+ var observers$$2 = this.meta(observers);
+
+ // skip the below if we have no observers
+ if (!observers$$2.length) {
+ return this
+ }
+
+ var data = {key: dotPropKey, value: value};
+ if (_undefined(dotPropKey)) {
+ data.key = obj(value) ? paths(key, value) : key;
+ }
+
+ for (var o = 0; o < observers$$2.length; o++) {
+ observers$$2[o](data);
+ }
+
+ return this
+ };
+
+ // @TODO
+ // // https://stackoverflow.com/questions/31158902/is-it-possible-to-sort-a-es6-map-object
+ // ordered(comperator = null) {
+ // // this.set = this.before(this.set)
+ // this.set = (key, value) => {
+ // // have to iterate over the keys before setting
+ // // and then after merging in values, update
+ // if (this.store.has(key)) {
+ // // first
+ // let keys = this.store.keys()
+ // if (isFunction(comperator)) keys = keys.sort(comperator)
+ //
+ // // after
+ // const store = this.store
+ // this.store = new Map()
+ // keys.forEach(keyInOrder => this.store.set(key, store.get(key)))
+ // store.clear()
+ // }
+ // }
+ // }
+
+ // --- remap ---
+ /**
+ * @desc remap properties from 1 to another, for example, apis with inconsistent naming
+ * @memberOf TransformChain
+ * @since 1.0.0
+ * @symb 🗺
+ *
+ * @param {string | Object} from property name string, or {[from]: to}
+ * @param {string} [to=undefined] property name to change key to
+ * @return {Chain} @chainable
+ *
+ * @see TransformChain.transform
+ * @IDEA could also be a function, but then might as well use .transform
+ *
+ * @example
+ *
+ * chain
+ * .remap('dis', 'dat')
+ * .from({dis: true})
+ *
+ * chain.entries()
+ * //=> {dat: true}
+ *
+ * @example
+ *
+ * chain
+ * .remap({dis: 'dat'})
+ * .from({dis: 1, other: true}}
+ *
+ * chain.entries()
+ * //=> {dist: 1, other: true}
+ *
+ */
+ Target.prototype.remap = function chainRemap(from, to) {
+ var this$1 = this;
+
+ var remap = from;
+ if (!obj(from)) { remap = {[from]: to}; }
+
+ /* prettier-ignore */
+ keys(remap).forEach(function (key) { return this$1.transform(key, function (val) {
+ this$1.set(remap[key], val);
+ return val
+ }); });
+
+ return this
+ };
+
+ return Target
+ };
+
+ /* ___filename___: dist/deps/is/dot.js */
+
+
+
+ var dot$1 = function isDot(x) {
+ return array(x) || (string(x) && x.includes('.'))
+ };
+
+ /* ___filename___: dist/deps/is/dot.js */
+
+ /* ___filename___: dist/compose/DotProp.js */
+ /**
+ * @since 2.0.0
+ */
+
+
+
+ /**
+ * @desc checks if this.meta.dot != false & isDot(key) - scoped
+ *
+ * @private
+ * @since 3.0.1
+ *
+ * @param {string} key key in .get/.has/.delete/set
+ * @param {DotProp} thisArg Chain
+ * @return {boolean} shouldDot
+ *
+ * @see DotProp.dot
+ * @see deps/is/dot
+ * @see deps/meta
+ * @see https://lodash.com/docs/#get
+ * @see https://github.com/sindresorhus/dot-prop
+ *
+ * @example
+ *
+ * const chain = new DotProp()
+ * shouldDot('me.me', chain)
+ * //=> true
+ *
+ * const chain = new DotProp()
+ * shouldDot('me', chain)
+ * //=> false
+ *
+ * const chain = new DotProp()
+ * chain.dot(false)
+ * shouldDot('me.me', chain)
+ * //=> false
+ *
+ */
+ var shouldDot = function (key, thisArg) { return thisArg.meta.dot !== false && dot$1(key); };
+
+ /**
+ * @class DotProp
+ * @member Observe
+ * @extends {ChainedMap}
+ * @memberOf compose
+ * @category Chainable
+ *
+ * @param {Class | Composable} Target composable class
+ * @return {DotProp} class
+ *
+ * @tests DotProp
+ * @types DotProp
+ *
+ * @see deps/dot
+ *
+ * @example
+ *
+ * const {compose} = require('chain-able')
+ * const {DotProp} = compose
+ * new DotProp()
+ * //=> DotProp
+ *
+ * @example
+ *
+ * const chain = new Chain()
+ *
+ * chain.set('moose.simple', 1)
+ * //=> Chain
+ *
+ * chain.get('moose.simple')
+ * //=>1
+ *
+ * chain.get('moose')
+ * //=> {simple: 1}
+ *
+ * chain.set('moose.canada.eh', true).set('moose.canada.igloo', true)
+ * //=> Chain
+ *
+ * //set, has, get, delete :-)
+ * chain.delete('moose.canada.eh')
+ * //=> Chain
+ *
+ * //also works with an array (moose.canada.igloo)
+ * chain.get(['moose', 'canada', 'igloo'])
+ * //=> true
+ *
+ */
+ var DotProp = function (Target) {
+ // is this any better?
+ var entries = Target.prototype.entries;
+ var set = Target.prototype.set;
+ var has = Target.prototype.has;
+ var get = Target.prototype.get;
+ var del = Target.prototype.delete;
+
+ /**
+ * @method dot
+ * @methodTarget DotProp
+ * @since 3.0.1
+ *
+ * @param {boolean} [useDot=undefined] use dot prop or not
+ * @return {DotProp} @chainable
+ *
+ * @see deps/meta
+ *
+ * @example
+ *
+ * const chain = new Target()
+ * chain.dot(false)
+ * chain.set('moose.simple', 1)
+ *
+ * toArr(chain.store.keys())
+ * //=> ['moose.simple']
+ *
+ */
+ Target.prototype.dot = function enableDisableDot(useDot) {
+ this.meta.dot = useDot;
+ return this
+ };
+
+ /**
+ * @desc since we have a map,
+ * we need to ensure the first property is available
+ * otherwise we have an empty map.entries obj
+ * which does nothing by reference
+ * @since 3.0.1
+ * @memberOf DotProp
+ *
+ * @override
+ * @inheritdoc
+ *
+ * @see TargetedMap.set
+ * @see .dot
+ *
+ * @example
+ * const chain = new Target()
+ *
+ * chain.set('moose.simple', 1)
+ * //=> Target store:Map: { moose: { simple: 1 } }
+ */
+ Target.prototype.set = function dotSet(key, val) {
+ if (shouldDot(key, this)) {
+ // first accessor
+ // @example: `canada` in `canada.eh`
+ var prop = key.split('.').shift();
+
+ // we already know it is .dot, call super instead
+ // if (!super.has(prop)) super.set(prop, {})
+
+ // spread
+ var data = entries.call(this);
+
+ // set on the spread data
+ index$20.set(data, key, val);
+
+ // is already by ref, but be extra safe, + observables
+ return set.call(this, prop, data[prop], key)
+ }
+ return set.call(this, key, val)
+ };
+
+ /**
+ * @desc dot-prop enabled get
+ * @method get
+ * @memberOf DotProp
+ *
+ * @since 3.0.1
+ * @override
+ * @inheritdoc
+ *
+ * @param {Primitive} key dot prop key, or any primitive key
+ * @param {any} [fallback=undefined] fallback value, if it cannot find value with key path
+ * @return {any} value for path, or fallback value if provided
+ *
+ * @see ChainedMap.get
+ * @see deps/dot
+ * @see deps/is/dot
+ *
+ * @TODO dot-prop on non-store instance.property when using nested chains...
+ *
+ * @example
+ *
+ * chain.set('moose.simple', 1)
+ * //=> Chain
+ *
+ * chain.get('moose.simple')
+ * //=>1
+ *
+ * chain.get('moose')
+ * //=> {simple: 1}
+ *
+ * @example
+ *
+ * //also works with an array (moose.simple)
+ * chain.get(['moose', 'simple'])
+ * //=> 1
+ *
+ */
+ Target.prototype.get = function dotGet(key, fallback) {
+ return shouldDot(key, this)
+ ? index$20.get(entries.call(this), key, fallback)
+ : get.call(this, key)
+ };
+
+ /**
+ * @method has
+ * @methodOf DotProp
+ * @since 3.0.1
+ * @override
+ * @inheritdoc
+ *
+ * @see deps/dot
+ * @see deps/is/dot
+ *
+ * @example
+ *
+ * chain.set('one.two', 3)
+ * chain.has('one.two')
+ * //=> true
+ *
+ */
+ Target.prototype.has = function dotHas(key) {
+ return shouldDot(key, this)
+ ? index$20.has(entries.call(this), key)
+ : has.call(this, key)
+ };
+
+ /**
+ * @method delete
+ * @methodOf DotProp
+ * @since 3.0.1
+ *
+ * @override
+ * @inheritdoc
+ * @see deps/dot
+ * @see deps/is/dot
+ *
+ * @example
+ *
+ * chain.set('moose.canada.eh', true)
+ * chain.set('moose.canada.igloo', true)
+ * //=> Chain
+ *
+ * chain.delete('moose.canada.eh')
+ * //=> Chain
+ *
+ * chain.has('moose.canada.eh')
+ * //=> true
+ *
+ * //still has moose.canada.igloo
+ * chain.has('moose.canada')
+ * //=> true
+ *
+ */
+ Target.prototype.delete = function dotDelete(key) {
+ return shouldDot(key, this)
+ ? index$20.delete(entries.call(this), key)
+ : del.call(this, key)
+ };
+
+ return Target
+ };
+
+ /* ___filename___: dist/compose/Observe.js */
+
+ /* ___filename___: dist/compose/Shorthands.js */
+
+ /* ___filename___: dist/compose/Transform.js */
+
+ /* ___filename___: dist/compose/DotProp.js */
+
+ /* ___filename___: dist/compose/compose.js */
+
+
+
+
+
+
+
+
+ var ComposableExtensions = [Observe, Shorthands, Transform, DotProp];
+
+ /**
+ * @desc compose chains all the way up from Chainable
+ * @since 3.0.0
+ *
+ * @param {Class | Function | undefined} [target=ChainedMap] class or function to extend
+ * @param {Array | undefined} [extensions=[Observe, Shorthands, Transform, DotProp]] Array of extensions to compose together left to right
+ * @return {Class | Function} composed
+ *
+ * @tutorial examples/playground/compose
+ * @tutorial examples/babel/decorators
+ *
+ * @name compose
+ * @func compose
+ * @member compose
+ * @tests compose
+ * @types compose
+ * @symb 🎼
+ *
+ * @see https://formidable.com/blog/2017/infinite-state-composition-with-freactal/
+ * @see https://blog.javascripting.com/2016/02/02/encapsulation-in-redux/
+ * @see https://www.barbarianmeetscoding.com/blog/2016/01/04/safer-javascript-object-composition-with-traits-and-traits-dot-js/
+ * @see https://medium.com/javascript-scene/why-learn-functional-programming-in-javascript-composing-software-ea13afc7a257
+ * @see https://hackernoon.com/javascript-functional-composition-for-every-day-use-22421ef65a10
+ * @see https://github.com/stoeffel/awesome-fp-js
+ *
+ * @example
+ *
+ * class Eh extends compose() {}
+ * new Eh() instanceof Chainable
+ * //=> true
+ *
+ * @example
+ *
+ * class Target {}
+ * class Eh extends compose(Target) {}
+ * new Eh() instanceof Target
+ * //=> true
+ *
+ * @example
+ *
+ * class Target {}
+ * const mixin = SuperClass => class extends SuperClass {}
+ * class Eh extends compose(Target, ) {}
+ * new Eh() instanceof Chainable
+ * //=> true
+ *
+ * @example
+ *
+ * class Winning {}
+ * class Yes extends compose(Winning) {
+ * get winning() {
+ * return true
+ * }
+ * }
+ * const yes = new Yes()
+ * yes instanceof Winning && yes.winning
+ * //=> true
+ *
+ */
+ function compose(target, extensions) {
+ var extend = _undefined(extensions) ? ComposableExtensions : extensions;
+ var composed = target;
+
+ if (target && target instanceof Object) {
+ composed = ChainedMap.compose(Chainable.compose(target));
+ }
+ else {
+ composed = ChainedMap;
+ }
+
+ for (var index = 0; index < extend.length; index++) {
+ composed = extend[index](composed) || composed || ChainedMap;
+ }
+
+ return composed
+ }
+
+ compose.Observe = Observe;
+ compose.Shorthands = Shorthands;
+ compose.Transform = Transform;
+ compose.DotProp = DotProp;
+
+ var compose_1 = compose;
+
+ /* ___filename___: dist/compose/compose.js */
+
+ var index$16 = compose_1;
+
+ /* ___filename___: dist/deps/fp/mapWhere.js */
+
+
+
+
+ /**
+ * Creates an array of values by running each property of `object` thru
+ * `iteratee`. The iteratee is invoked with three arguments: (value, key, object).
+ *
+ * @memberOf fp
+ * @since 5.0.0
+ * @category Object
+ *
+ * @param {Object} obj The object to iterate over.
+ * @param {Function} predicate The function invoked per iteration.
+ * @return {Array} Returns the new mapped array.
+ *
+ * @see https://github.com/lodash/lodash/blob/master/map.js
+ *
+ * @example
+ *
+ * const square = n => n * n
+ * map({ 'a': 4, 'b': 8 }, square)
+ * // => [16, 64] (iteration order is not guaranteed)
+ *
+ */
+ function mapWhere(obj, predicate) {
+ var output = {};
+ var isArrayObj = array(obj);
+ var keys = keysObjOrArray(obj);
+
+ for (var index = 0; index < keys.length; index++) {
+ var key = isArrayObj ? index : keys[index];
+ var value = obj[key];
+
+ if (predicate(value, key, obj)) {
+ output[key] = value;
+ }
+ }
+
+ return output
+ }
+
+ var mapWhere_1 = curry(2, mapWhere);
+
+ /* ___filename___: dist/deps/reduce/toObj.js */
+ var toObj = function reduceObj(array, iterator) {
+ return array.reduce(function(reduced, next) {
+ iterator(reduced, next);
+ return reduced
+ }, {})
+ };
+
+ /* ___filename___: dist/deps/fp/mapWhere.js */
+
+ /* ___filename___: dist/deps/reduce/toObj.js */
+
+ /* ___filename___: dist/deps/reduce/clean.js */
+
+
+
+
+
+
+ // const [isNotReal, isNotEmpty] = [isReal, isEmpty].map(not)
+ // const isNotEmptyOrNotReal = or(isNotReal, isNotEmpty)
+ var mapNotEmpty = mapWhere_1('_', function (x) { return real(x) && !empty(x); });
+
+ /**
+ * @desc goes through the maps,
+ * and the map values,
+ * reduces them to array
+ * then to an object using the reduced values
+ *
+ * @memberOf reduce
+ * @since 4.0.0 <- moved as a dep function
+ * @since 0.4.0
+ *
+ * @param {Object} obj object to clean, usually .entries()
+ * @return {Object} reduced object, without `notReal` values
+ *
+ * @TODO seems to be overkill with reducing mapping just copy & ignore or delete?
+ *
+ * @see reduce
+ * @see isObjWithKeys
+ * @see isNotEmptyArray
+ * @see isReal
+ * @see http://underscorejs.org/#reduce
+ *
+ * @example
+ *
+ * const map = new ChainedMap()
+ *
+ * map
+ * .set('emptyArr', [])
+ * .set('arr', [1])
+ * .set('nill', null)
+ * .set('emptyObj', {})
+ * .set('obj', {keys: true})
+ *
+ * clean(map.entries())
+ * //=> {arr: [1], obj: {keys: true}}
+ *
+ */
+ var clean = function clean(obj) {
+ var mapped = mapNotEmpty(obj);
+ var keys$$2 = keys(mapped);
+ var iterator = function (reduced, key) { return (reduced[key] = mapped[key]); };
+
+ return toObj(keys$$2, iterator)
+ };
+
+ /* ___filename___: dist/deps/traversers/eq.js */
+ var eq$2 = traverse_1.eq;
+
+ var index$22 = validatorBuilder;
+
+ /* ___filename___: dist/ChainedSet.js */
+
+ /* ___filename___: dist/FactoryChain.js */
+
+ /* ___filename___: dist/deps/reduce/clean.js */
+
+ /* ___filename___: dist/deps/traversers/eq.js */
+
+ var index = createCommonjsModule(function (module) {
+ // dep
+
+ // core
+
+
+
+ // merge
+
+
+
+ // easy
+
+
+ // composer
+
+
+ // export
+ var exp = index$16();
+ exp.chainable = function (parent) { return new exp(parent); };
+ exp.builder = function (obj) { return new MethodChain_1(obj); };
+ exp.Chain = exp;
+ exp.compose = index$16;
+
+ // deps
+ exp.traverse = traverse_1;
+ exp.addMethodFactories = MethodChain_1.add;
+
+ exp.toArr = toArr; // exp.toarr =
+ exp.camelCase = camelCase;
+ exp.dot = index$20;
+ exp.matcher = index$18;
+ exp.reduce = index$6;
+ exp.clean = clean;
+ exp.meta = index$8;
+ exp.eq = eq$2;
+ exp.types = index$22;
+ exp.encase = index$14;
+
+ exp.addTypes = exp.types.addTypes;
+
+ // core
+ exp.Chainable = Chainable;
+ exp.ChainedSet = ChainedSet_1;
+ exp.ChainedMap = ChainedMap;
+ exp.FactoryChain = FactoryChain_1;
+ exp.MethodChain = MethodChain_1;
+
+ // merge
+ exp.MergeChain = MergeChain_1;
+ exp.merge = index$2;
+
+ exp.is = index$12;
+
+ assign(exp, exp.is);
+
+ // @NOTE: no need for exporting as an __esModule,
+ // it adds additional checking wrapper
+ module.exports = exp;
+
+
+ });
+
+ var index$1 = unwrapExports(index);
+
+ return index$1;
+
+})));
+//# sourceMappingURL=index.js.map
diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md
index d494751..c30d1b4 100644
--- a/docs/CHANGELOG.md
+++ b/docs/CHANGELOG.md
@@ -1,3 +1,174 @@
+# v5.0.0-beta.1-5
+
+https://lh3.googleusercontent.com/-G9TxkDCz4No/WBnw5HgDhaI/AAAAAAAANTE/grSmWeThmJYJkbMs0QunPnj9GtRK5-hQwCJoC/w1060-h798-p-rw/map-filter-reduce-in-emoji-1.png
+
+### 5
+- 🔩 /native/ folder
+ - 🕴 for exporting native/built-in prototype methods and such
+
+- 🆙 conditional/
+ - ℹ️ more docs to `all` & `and` & `not` & `some`
+ - 🐏 curry `not`
+ - /includes
+ - 🐏 curry
+ - ❔ use isString > isArray as first check
+
+- ⚖️ `eq` 🛁 minor clean + ℹ️🔗 doclinks 👕 lint tweaks
+- 🆕 add expressions/
+- 🚚 move ignored to meta/
+- 🚚🔬 move dopemerge map & set example into skipped test
+- 🚚 move concat to /array
+
+- 🐏 🎁 add fp/
+ - 🐏 🎁 fp: ⬅️ reverse 👷 construct 📞 invoke ℹ️️ docs
+ - ℹ️️ more docs to arity, always, curry, replace, prop
+ - 🛅 shorten firstIndex, lastIndex
+ - ⬅️🆕 reverse
+ - 👷🆕 construct (used in index when exporting .build & .init/.chainable)
+ - ❔🆕 includesCount (RESEARCH BETTER NAME) (occurs?)
+ - ❔🆕 hasInMatching
+ - 📞🆕 invoke
+ - 🕴 export more in the index
+ - 🤸`|` pipe split into pipeTwo + pipe (for dynamic length args & 2 args)
+
+- 🐏 🎁 fp/ ...again
+ - ℹ️ more docs 👷 construct/ 🆕🙃 flip 🆕 invoker
+ - ℹ️️ more docs to first, firstIndex, includesCount, last, lastIndex, reverse
+ - 🔬 more adapted tests
+ - 🆕 invoker
+ - 🆕🙃 flip
+ - 🙃🙃 flip2 (just first2 args)
+- 👷 construct/
+ - map, set, regexp
+
+- ❔ is/
+ - ❔ is/ ℹ️ℹ️ℹ️️ docs 🆕🆕🆕 🔬🔩
+ - ℹ️️ docs: arguments, array, boolean, buffer, hasIn, objNotNull, prototypeOf, string, undefined, arrayOf, asyncish, async, dot, enumerable, function, generator, json, toS/getTag
+ - ⚒ fix ℹ️ docs ⌨️ typo in primitive
+ - 🔬 tests for 🆕
+ - ❔🆕 isMatch
+ - ❔🆕 isInstanceOf
+ - ❔🆕 isUndefinedLike
+ - ❔🆕 isWeakMap
+ - ❔🆕 isWeakSet
+ - ❔🆕 isIteratable (moved from traverse)
+ - ❔🆕 isCircular
+ - ❔🆕 isBooleanPrimitive (split from isBoolean)
+ - ❔🆕 isMatch (not exported boolean version of matcher)
+ - ❔🆕 isBrowser (using util/localGlobal & isUndefinedLike)
+ - 🔩 use native/ in isNative
+ - 🆙 use `or` in isAsyncish
+
+- 🆕 add expressions/
+- to/
+ - array
+ - string
+ - boolean
+ - number
+ - object
+ - integer
+ - map
+ - set
+ - setToArray
+ - coerce
+
+- 🖇 util/
+ - 🆙 utils/ 🕴 exports
+ - 🆕🌏 localGlobal (window || global)
+ - 🔢 lengthFromZero
+ - ℹ️️ docs
+ - 😡 use lengthFromZero in `argumentor`
+ - ⛑ hasOwnProperty add `isNill` safety
+ - assign - added commented out polyfil when needed for future reference
+- build/
+ - remap all to export
+
+
+- 🔎🌎 WEBSITE!
+ - https://github.com/js-org/dns.js.org/pull/1364#issuecomment-316629304
+ - https://chain-able.js.org
+
+- ❗ BREAKING:
+ - rename is objLoose & objPure & objStrict -> into understandable names that convey what they do
+
+- 🤖📖 docgen
+ - 🛅 built dev version for links from docgen site until upgraded
+ - 📜📒 makefile scripts to make docgen & site
+ - make website
+ - docgen metadata for fuzzy search content
+ - fix doc html links
+ - ℹ️️ℹ️️ℹ️️ a ton of docblocks in src for outputting better docs
+- 📘⛓ examples:
+ - 📘⛓ example: SwitchChain
+ - 📘⛓ example: RegExp chain
+ - 📘⛓ example: ObjectDefineChain
+ - ⚪️ Frisbee 🆙 with updates
+- misc
+ - ternary in transform.remap
+ - 🌊〰️ update typings
+- 🖇 utils
+ - ❔🆕 isEmpty
+ - ❔🆕 isJSON
+ - ❔🆕 isArguments
+ - ❔🆕 isBuffer
+ - ❔🆕 move reusable `is` functions from validator builder into files
+ - ❔🆕 isNotNested
+ - ❔🆕 isPrimitive
+ - ❔🆕 isIn
+ - ❔🆕 isArrayOf
+ - ❔ isStringOrNumber 🆓 use `conditional/or`
+ - 🤸 split isNumber
+ - + isNumberPrimitive
+ - 🗝️ keys for objOrArray
+ - 🆓 use some curry in izzez
+ - 🆓 reduce: use 🆓 fp on 🛁 clean
+ - 🆓 conditionals utils wrap with curry + ℹ️️
+ - 🐫 add camelCase 🔬 tests + 🚚 move to string/ folder
+
+- 🆓🎁 FP
+ - start them, update,️dℹ️️ docblock, 🔬 test, (ramda lodash thanks for some parts of some)
+ - prop
+ - pipe
+ - path,
+ - map,
+ - curry
+ - first
+ - firstIndex
+ - last
+ - lastIndex
+ - arity
+ - replace
+ - mapWhere
+ - always
+ - remove
+ - arity
+
+- 👣 Traverse
+ - 🏰 ground up refactor for deopt
+ - 🎱 add InstancePooler with tests
+ - add reset, adjust delete (needs a better .remove for array .splice)
+ - 🤸🛁 split & clean
+ - ℹ️️ re-document
+ - 👾 variable name clarity
+ - 📝 todos
+ - 🤸🎯 split dopemerge emptyTarget to a reusable file
+ - refactor equals
+ - 👾 simplify `isArrayOrObj && isObjWithKeys` -> isEmpty
+ - rename .iteratee to .node,
+
+- 🛡 encase
+ - 🆓 wrap encase: tryCatch & withSpec with curry
+ - ℹ️️ docblocks for dot-prop
+ - 🆓 use fp/replace on escape
+
+- 🏗 build & 📇 metadata
+ - lego-cli for later
+ - 📇 metadata for docgen
+ - 📇 metadata yarn lock pkg json stuff
+ - 🏗🔌 comment plugin to add filenames to output
+ - 🏸 cdn server hosting in installations in readme for site
+ - ⚒ minor eq path require fix
+
# 🏷 v4.1.0
- 🏰 refactoring to add prototype methods, instead of many multi-inherit
- 📜📒 Makefile
@@ -148,7 +319,7 @@
- removed .extendsGetSet, .defineGetSet, .extendIncrement, .extendWith, .extendAlias, .decorateParent, .typed
- replaced ^ with .alias(), .getSet(), .decorate(obj), .define(), .autoIncrement(), .default(), .initial(), .bind(), .encase(), .call(), .get(), .set(), .returns(), .camelCase(), .factory(for extending), .build with + support
- removed compose/Extend, compose/Child, compose/immutable, compose/Extend, compose/Types, compose/Symbols, compose/Debug, compose/define
- - .schema feature
+ - 🎁 .schema feature
- optional types, array types, or types
- 📐🛂🏭 refactor out schema factory
- integrated histories from deepmerge, dot-prop, traverse-js, webpack-chain (all commit hashes change, extremely likely they are not used anywhere, even so there is a branch backup so hardly 100% breaking)
diff --git a/docs/docdown/Chainable.md b/docs/docdown/Chainable.md
index a68d8c7..e652cf8 100644
--- a/docs/docdown/Chainable.md
+++ b/docs/docdown/Chainable.md
@@ -5,30 +5,24 @@
## `Chainable`
-* ``
+* ``
+* `Chainable.`
+* `Chainable.[Iterator]`
+* `Chainable.[Primitive]`
+* `Chainable.clear`
+* `Chainable.delete`
+* `Chainable.end`
+* `Chainable.has`
+* `Chainable.length`
+* `Chainable.values`
+* `Chainable.when`
## `Chainable.constructor`
-* `Chainable.constructor`
-
-
-
-
-
-## `Chainable.prototype`
-* `Chainable.prototype.`
-* `Chainable.prototype.[Iterator]`
-* `Chainable.prototype.[Primitive]`
-* `Chainable.prototype.clear`
-* `Chainable.prototype.delete`
-* `Chainable.prototype.end`
-* `Chainable.prototype.has`
-* `Chainable.prototype.length`
-* `Chainable.prototype.values`
-* `Chainable.prototype.when`
+* `Chainable.constructor`
@@ -42,12 +36,15 @@
-# compose
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/Chainable.js#L445 "View in source") [Ⓣ][1]
+compose
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/Chainable.js#L444 "View in source") [Ⓣ][1]
unknown
-#### Since
+
+#### @Since
3.0.0
#### Example
@@ -63,56 +60,27 @@ chain instanceof Target
-
-
-
-
-## `Chainable.constructor`
-
-
-
-# Chainable.constructor(parent=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/Chainable.js#L65 "View in source") [Ⓣ][1]
-
-Function
-
-#### Since
-0.0.1
-
-#### Arguments
-1. `parent=undefined` *(Chainable|ParentType|any)*: ParentType
-
-#### Example
-```js
-class ChainedMap extends Chainable {}
-const map = new ChainedMap()
-map.className
-//=> ChainedMap
-
-```
----
-
-
-
-
-
-
-
-## `Chainable.prototype`
-
🌊 Types: Chainable.d
🔬 Tests: Chainable
-# Chainable.prototype.
+Chainable.
+
+
[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/Chainable.js#L10 "View in source") [Ⓣ][1]
(Chainable): Trait class that can inherit any class passed into compose, extended by ChainedMap & ChainedSet
-### @classProps
+#### @see
+
+* chain-pattern
+* ChainedMap
+* ChainedSet
+
+#### @classProps
* {parent}
* {className}
@@ -125,17 +93,27 @@ map.className
🔬 Tests: iteration
-# Chainable.prototype.[Iterator]()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/Chainable.js#L117 "View in source") [Ⓣ][1]
+Chainable.[Iterator]()
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/Chainable.js#L122 "View in source") [Ⓣ][1]
(generator): Iterator for looping values in the store
-### @notes
+#### @see
+
+* https://github.com/sindresorhus/quick-lru/blob/master/index.js
+* https://stackoverflow.com/questions/36976832/what-is-the-meaning-of-symbol-iterator-in-this-context
+* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/iterator
+* this.store
+
+#### @notes
* assigned to a variable so buble ignores it
-#### Since
+
+#### @Since
0.5.0
#### Returns
@@ -178,12 +156,19 @@ for (const arr of set) {
-# Chainable.prototype.[Primitive](hint=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/Chainable.js#L382 "View in source") [Ⓣ][1]
+Chainable.[Primitive](hint=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/Chainable.js#L13 "View in source") [Ⓣ][1]
-Function
+(Function): symbol method for toString, toJSON, toNumber
+
+
+#### @see
+
+* well-known-symbols-es6
-#### Since
+#### @Since
1.0.2
#### Arguments
@@ -215,11 +200,20 @@ chain + ''
-# Chainable.prototype.clear([clearPropertiesThatAreChainLike=true])
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/Chainable.js#L236 "View in source") [Ⓣ][1]
+Chainable.clear([clearPropertiesThatAreChainLike=true])
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/Chainable.js#L23 "View in source") [Ⓣ][1]
(Function): clears the map, goes through this properties, calls .clear if they are instanceof Chainable or Map
+
+#### @see
+
+* https://github.com/fliphub/flipchain/issues/2
+* ChainedSet
+* ChainedMap
+* map-clear
#### Arguments
1. `[clearPropertiesThatAreChainLike=true]` *(|boolean)*: checks properties on the object, if they are `chain-like`, clears them as well
@@ -243,12 +237,22 @@ chain.entries()
-# Chainable.prototype.delete(key=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/Chainable.js#L275 "View in source") [Ⓣ][1]
+Chainable.delete(key=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/Chainable.js#L283 "View in source") [Ⓣ][1]
(Function): calls .delete on this.store.map
-#### Since
+
+#### @see
+
+* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/has
+* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/has
+* ChainedSet
+* ChainedMap
+
+#### @Since
0.3.0
#### Arguments
@@ -274,12 +278,20 @@ chain.get('eh')
-# Chainable.prototype.end()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/Chainable.js#L162 "View in source") [Ⓣ][1]
+Chainable.end()
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/Chainable.js#L167 "View in source") [Ⓣ][1]
(Function): for ending nested chains
-#### Since
+
+#### @see
+
+* Chainable.parent
+* FactoryChain
+
+#### @Since
0.4.0
#### Returns
@@ -299,12 +311,19 @@ child.end()
-# Chainable.prototype.has(keyOrValue=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/Chainable.js#L298 "View in source") [Ⓣ][1]
+Chainable.has(keyOrValue=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/Chainable.js#L10 "View in source") [Ⓣ][1]
+
+(Function): checks whether the store has a value for a given key
-Function
-#### Since
+#### @see
+
+* map-has
+
+#### @Since
0.3.0
#### Arguments
@@ -328,12 +347,19 @@ chain.has('canada')
-# Chainable.prototype.length()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/Chainable.js#L416 "View in source") [Ⓣ][1]
+Chainable.length()
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/Chainable.js#L414 "View in source") [Ⓣ][1]
Function
-#### Since
+
+#### @see
+
+* ChainedMap.store
+
+#### @Since
0.5.0
#### Returns
@@ -349,19 +375,29 @@ for (var i = 0; i < chain.length; i++)
-# Chainable.prototype.values()
+Chainable.values()
+
+
[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/Chainable.js#L20 "View in source") [Ⓣ][1]
(Function): spreads the entries from ChainedMap.store.values allocates a new array, adds the values from the iterator
-### @notes
+#### @see
+
+* mozilla-map-values
+* mozilla-set-values
+* compat-array-static-methods
+* set-to-array
+
+#### @notes
* look at Chainable.constructor to ensure not to use `new Array...`
* moved from ChainedMap and ChainedSet to Chainable @2.0.2
* this was [...] & Array.from(this.store.values())
-#### Since
+
+#### @Since
0.4.0
#### Returns
@@ -381,8 +417,10 @@ chain.values()
-# Chainable.prototype.when(condition=undefined, [trueBrancher=Function], [falseBrancher=Function])
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/Chainable.js#L188 "View in source") [Ⓣ][1]
+Chainable.when(condition=undefined, [trueBrancher=Function], [falseBrancher=Function])
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/Chainable.js#L193 "View in source") [Ⓣ][1]
(Function): when the condition is true, trueBrancher is called, else, falseBrancher is called
@@ -406,6 +444,40 @@ chains.when(prod, c => c.set('prod', true), c => c.set('prod', false))
+
+
+## `Chainable.constructor`
+
+
+
+Chainable.constructor(parent=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/Chainable.js#L68 "View in source") [Ⓣ][1]
+
+Function
+
+
+#### @Since
+0.0.1
+
+#### Arguments
+1. `parent=undefined` *(Chainable|ParentType|any)*: ParentType
+
+#### Example
+```js
+class ChainedMap extends Chainable {}
+const map = new ChainedMap()
+map.className
+//=> ChainedMap
+
+```
+---
+
+
+
+
+
[1]: #chainable "Jump back to the TOC."
diff --git a/docs/docdown/ChainedMap.md b/docs/docdown/ChainedMap.md
index 16e67fd..80040f6 100644
--- a/docs/docdown/ChainedMap.md
+++ b/docs/docdown/ChainedMap.md
@@ -4,22 +4,22 @@
-## `CM`
-* `CM`
+## `ChainedMapBase`
+* `ChainedMapBase.ComposeChainedMap`
## `merge`
-* `merge`
+* `merge`
## `method`
-* `method`
+* `method`
@@ -29,7 +29,7 @@
-## `CM`
+## `ChainedMapBase`
@@ -38,22 +38,24 @@
🔬 Tests: ChainedMap
-# CM([SuperClass=ChainedMapBase])
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/ChainedMap.js#L31 "View in source") [Ⓣ][1]
+ChainedMapBase.ComposeChainedMap([SuperClass=ChainedMapBase])
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/ChainedMap.js#L33 "View in source") [Ⓣ][1]
(Function): ChainedMap composer
-### @see
+#### @see
-* fluents/chain able/blob/master/src/deps/dopemerge/dopemerge.js
-* fluents/chain able/blob/master/src/merge chain.js
+* ChainedMapBase
-### @extends
+#### @extends
ChainedMapBase
-#### Since
+
+#### @Since
0.0.1
#### Arguments
@@ -83,22 +85,25 @@ hehchain instanceof heh
-# merge(obj=undefined, [handleMergeFn=undefined])
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/ChainedMap.js#L99 "View in source") [Ⓣ][1]
+merge(obj=undefined, [handleMergeFn=undefined])
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/ChainedMap.js#L101 "View in source") [Ⓣ][1]
(Function): merges an object with the current store
-### @see
+#### @see
-* fluents/chain able/blob/master/src/deps/dopemerge/dopemerge.js
-* fluents/chain able/blob/master/src/merge chain.js
+* deps/dopemerge
+* MergeChain
-### @todos
+#### @todos
- [ ] needs to pass in additional opts somehow...
-#### Since
+
+#### @Since
0.4.0
#### Arguments
@@ -139,17 +144,19 @@ const chain = new Chain()
-# method(names=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/ChainedMap.js#L63 "View in source") [Ⓣ][1]
+method(names=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/ChainedMap.js#L65 "View in source") [Ⓣ][1]
(Function): the way to easily start building methods when using chainable instances
-### @see
+#### @see
+
+* MethodChain
-* fluents/chain able/blob/master/src/deps/dopemerge/dopemerge.js
-* fluents/chain able/blob/master/src/merge chain.js
-#### Since
+#### @Since
4.0.0
#### Arguments
@@ -175,4 +182,4 @@ chain.get('eh')
- [1]: #cm "Jump back to the TOC."
+ [1]: #chainedmapbase "Jump back to the TOC."
diff --git a/docs/docdown/ChainedMapBase.md b/docs/docdown/ChainedMapBase.md
index 63d6e8e..9b1323f 100644
--- a/docs/docdown/ChainedMapBase.md
+++ b/docs/docdown/ChainedMapBase.md
@@ -4,15 +4,15 @@
-## `ChainedMapBase.prototype`
-* `ChainedMapBase.prototype.CMC`
-* `ChainedMapBase.prototype.compose`
-* `ChainedMapBase.prototype.entries`
-* `ChainedMapBase.prototype.extend`
-* `ChainedMapBase.prototype.from`
-* `ChainedMapBase.prototype.get`
-* `ChainedMapBase.prototype.set`
-* `ChainedMapBase.prototype.tap`
+## `ChainedMapBase`
+* `ChainedMapBase.ComposeChainedMapBase`
+* `ChainedMapBase.compose`
+* `ChainedMapBase.entries`
+* `ChainedMapBase.extend`
+* `ChainedMapBase.from`
+* `ChainedMapBase.get`
+* `ChainedMapBase.set`
+* `ChainedMapBase.tap`
@@ -22,7 +22,7 @@
-## `ChainedMapBase.prototype`
+## `ChainedMapBase`
@@ -30,25 +30,40 @@
🔬 Tests: ChainedMap
-# ChainedMapBase.prototype.CMC
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/ChainedMapBase.js#L18 "View in source") [Ⓣ][1]
+ChainedMapBase.ComposeChainedMapBase
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/ChainedMapBase.js#L23 "View in source") [Ⓣ][1]
(Chainable): this is to avoid circular requires
because MergeChain & MethodChain extend this
yet .method & .merge use those chains
+...also, it serves as a non-references creator for extending new instances of Chainable, where it splits into *(Map | Set)* -> composed prototype decorators
+
+
+#### @see
+* pony-map
+* mozilla-map
+* emca-map
+* ChainedMap
+* Chainable
+* MergeChain
+* MethodChain
+* ChainedMap
-### @classProps
+#### @classProps
* {meta} meta fn
* {store} main store
-### @extends
+#### @extends
Chainable
-#### Since
+
+#### @Since
4.0.0-alpha.1
---
@@ -57,13 +72,15 @@ Chainable
-# ChainedMapBase.prototype.cmc([SuperClass=Chainable])
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/ChainedMapBase.js#L291 "View in source") [Ⓣ][1]
+ChainedMapBase.cmc([Target=Chainable])
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/ChainedMapBase.js#L296 "View in source") [Ⓣ][1]
(Composer): ChainedMapBase composer
#### Arguments
-1. `[SuperClass=Chainable]` *(Class|Composable|Object)*: class to extend
+1. `[Target=Chainable]` *(Class|Composable|Object)*: class to extend
#### Returns
*(Class)*: ChainedMapBase
@@ -83,12 +100,19 @@ hehchain instanceof heh
-# ChainedMapBase.prototype.entries([chains=false])
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/ChainedMapBase.js#L23 "View in source") [Ⓣ][1]
+ChainedMapBase.entries([chains=false])
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/ChainedMapBase.js#L17 "View in source") [Ⓣ][1]
(Function): spreads the entries from ChainedMapBase.store *(Map)* return store.entries, plus all chain properties if they exist
-#### Since
+
+#### @see
+
+* mozilla-map-entries
+
+#### @Since
0.4.0
#### Arguments
@@ -112,12 +136,15 @@ map.set('a', 'alpha').set('b', 'beta').entries()
-# ChainedMapBase.prototype.extend(methods=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/ChainedMapBase.js#L170 "View in source") [Ⓣ][1]
+ChainedMapBase.extend(methods=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/ChainedMapBase.js#L175 "View in source") [Ⓣ][1]
(Function): shorthand methods, from strings to functions that call .set
-#### Since
+
+#### @Since
0.4.0
#### Arguments
@@ -144,17 +171,20 @@ eq(chain2.eh, chain1.eh)
-# ChainedMapBase.prototype.from(obj=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/ChainedMapBase.js#L128 "View in source") [Ⓣ][1]
+ChainedMapBase.from(obj=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/ChainedMapBase.js#L133 "View in source") [Ⓣ][1]
(Function): checks each property of the object calls the chains accordingly
-### @todos
+#### @todos
- [ ] could also add parsing stringified
-#### Since
+
+#### @Since
0.5.0
#### Arguments
@@ -177,12 +207,19 @@ eq(from, eh)
-# ChainedMapBase.prototype.get(key=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/ChainedMapBase.js#L22 "View in source") [Ⓣ][1]
+ChainedMapBase.get(key=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/ChainedMapBase.js#L16 "View in source") [Ⓣ][1]
(Function): get value for key path in the Map store ❗ `debug` is a special key and is *not* included into .store it goes onto .meta
-#### Since
+
+#### @see
+
+* mozilla-map-get
+
+#### @Since
0.4.0
#### Arguments
@@ -208,12 +245,20 @@ chain.get('nope')
-# ChainedMapBase.prototype.set(key=undefined, value=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/ChainedMapBase.js#L18 "View in source") [Ⓣ][1]
+ChainedMapBase.set(key=undefined, value=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/ChainedMapBase.js#L15 "View in source") [Ⓣ][1]
(Function): sets the value using the key on store adds or updates an element with a specified key and value
-#### Since
+
+#### @see
+
+* mozilla-map-set
+* ChainedMapBase.store
+
+#### @Since
0.4.0
#### Arguments
@@ -237,12 +282,21 @@ chain.get('eh')
-# ChainedMapBase.prototype.tap(name=undefined, fn=undefined)
+ChainedMapBase.tap(name=undefined, fn=undefined)
+
+
[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/ChainedMapBase.js#L32 "View in source") [Ⓣ][1]
(Function): tap a value with a function
-#### Since
+
+#### @see
+
+* tapable
+* ChainedMapBase.set
+* ChainedMapBase.get
+
+#### @Since
4.0.0-alpha.1 <- moved from transform & shorthands
#### Arguments
@@ -285,4 +339,4 @@ const entries = new Chain()
- [1]: #chainedmapbase.prototype "Jump back to the TOC."
+ [1]: #chainedmapbase "Jump back to the TOC."
diff --git a/docs/docdown/ChainedSet.md b/docs/docdown/ChainedSet.md
index fae56e5..80d7c49 100644
--- a/docs/docdown/ChainedSet.md
+++ b/docs/docdown/ChainedSet.md
@@ -5,28 +5,10 @@
## `ChainedSet`
-* ``
-
-
-
-
-
-## `add`
-* `add`
-
-
-
-
-
-## `merge`
-* `merge`
-
-
-
-
-
-## `prepend`
-* `prepend`
+* `ChainedSet.`
+* `ChainedSet.add`
+* `ChainedSet.merge`
+* `ChainedSet.prepend`
@@ -44,28 +26,36 @@
🔬 Tests: ChainedSet
-
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/ChainedSet.js#L23 "View in source") [Ⓣ][1]
+ChainedSet.
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/ChainedSet.js#L25 "View in source") [Ⓣ][1]
Set
-### @notes
+#### @see
+
+* http://2ality.com/2015/09/well-known-symbols-es6.html
+* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/isConcatSpreadable
+* Chainable
+
+#### @notes
* had Symbol.isConcatSpreadable but it was not useful
-### @todos
+#### @todos
- [ ] could add .first .last ?
-### @classProps
+#### @classProps
* {store}
-### @extends
+#### @extends
Chainable
@@ -73,20 +63,22 @@ Chainable
-
-
-## `add`
+ChainedSet.add(value=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/ChainedSet.js#L16 "View in source") [Ⓣ][1]
-
+(Function): appends a new element with a specified value to the end of the .store
-# add(value=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/ChainedSet.js#L55 "View in source") [Ⓣ][1]
-(Function): appends a new element with a specified value to the end of the .store
+#### @see
+
+* mozilla-set-add
+* lodash-add-set-entry
-#### Since
+#### @Since
0.4.0
#### Arguments
@@ -108,20 +100,17 @@ for (let name of people) console.log(name)
-
-
-## `merge`
-
-
-
-# merge(arr=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/ChainedSet.js#L100 "View in source") [Ⓣ][1]
+ChainedSet.merge(arr=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/ChainedSet.js#L114 "View in source") [Ⓣ][1]
(Function): merge any Array/Set/Iteratable/Concatables into the array, at the end
-#### Since
+
+#### @Since
0.4.0
#### Arguments
@@ -143,20 +132,17 @@ for (let name of people) console.log(name)
-
-
-## `prepend`
-
-
-
-# prepend(value=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/ChainedSet.js#L76 "View in source") [Ⓣ][1]
+ChainedSet.prepend(value=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/ChainedSet.js#L88 "View in source") [Ⓣ][1]
(Function): inserts the value at the **beginning** of the Set
-#### Since
+
+#### @Since
0.4.0
#### Arguments
diff --git a/docs/docdown/FactoryChain.md b/docs/docdown/FactoryChain.md
index 8ed54a1..c7f9dee 100644
--- a/docs/docdown/FactoryChain.md
+++ b/docs/docdown/FactoryChain.md
@@ -4,13 +4,13 @@
-## `FactoryChain.prototype`
-* `FactoryChain.prototype.`
-* `FactoryChain.prototype.chainUpDowns`
-* `FactoryChain.prototype.factory`
-* `FactoryChain.prototype.getData`
-* `FactoryChain.prototype.prop`
-* `FactoryChain.prototype.props`
+## `FactoryChain`
+* `FactoryChain.`
+* `FactoryChain.chainUpDowns`
+* `FactoryChain.factory`
+* `FactoryChain.getData`
+* `FactoryChain.prop`
+* `FactoryChain.props`
@@ -20,7 +20,7 @@
-## `FactoryChain.prototype`
+## `FactoryChain`
@@ -28,19 +28,21 @@
🔬 Tests: FactoryChain
-# FactoryChain.prototype.
+FactoryChain.
+
+
[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/FactoryChain.js#L7 "View in source") [Ⓣ][1]
Map
-### @classProps
+#### @classProps
* {data}
* {_calls}
-### @extends
+#### @extends
ChainedMapBase
@@ -50,17 +52,20 @@ ChainedMapBase
-# FactoryChain.prototype.chainUpDowns(methods=undefined)
+FactoryChain.chainUpDowns(methods=undefined)
+
+
[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/FactoryChain.js#L80 "View in source") [Ⓣ][1]
(Function): chain back up to parent for any of these
-### @todos
+#### @todos
- [ ] should have a debug log for this
-#### Since
+
+#### @Since
2.0.0
#### Arguments
@@ -109,12 +114,15 @@ const returned = things
-# FactoryChain.prototype.factory([obj={}])
+FactoryChain.factory([obj={}])
+
+
[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/FactoryChain.js#L223 "View in source") [Ⓣ][1]
(Function): creates/add the `.end` method, which checks how many methods have been called, and decides whether to return parent or not
-#### Since
+
+#### @Since
2.0.0
#### Arguments
@@ -129,12 +137,15 @@ const returned = things
-# FactoryChain.prototype.getData([prop=undefined])
+FactoryChain.getData([prop=undefined])
+
+
[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/FactoryChain.js#L204 "View in source") [Ⓣ][1]
(Function): access data being built when stepping through a factory
-#### Since
+
+#### @Since
2.0.0
#### Arguments
@@ -164,12 +175,15 @@ expect(age).toBe(10)
-# FactoryChain.prototype.prop(name=undefined, [onCall=undefined])
+FactoryChain.prop(name=undefined, [onCall=undefined])
+
+
[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/FactoryChain.js#L146 "View in source") [Ⓣ][1]
(Function): add property that are counted towards the call count for easy auto-ending chaining
-#### Since
+
+#### @Since
2.0.0
#### Arguments
@@ -195,12 +209,19 @@ person
-# FactoryChain.prototype.props(names=undefined)
+FactoryChain.props(names=undefined)
+
+
[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/FactoryChain.js#L120 "View in source") [Ⓣ][1]
(Function): adds an *array* of properties, using FactoryChain.prop
-#### Since
+
+#### @see
+
+* FactoryChain.prop
+
+#### @Since
2.0.0
#### Arguments
@@ -236,4 +257,4 @@ person.name().age().email()
- [1]: #factorychain.prototype "Jump back to the TOC."
+ [1]: #factorychain "Jump back to the TOC."
diff --git a/docs/docdown/MergeChain.md b/docs/docdown/MergeChain.md
index 0e7f2f8..32a922f 100644
--- a/docs/docdown/MergeChain.md
+++ b/docs/docdown/MergeChain.md
@@ -5,30 +5,24 @@
## `MergeChain`
-* ``
-
-
-
-
-
-## `MergeChain.prototype`
-* `MergeChain.prototype.`
-* `MergeChain.prototype.merger`
-* `MergeChain.prototype.onExisting`
+* ``
+* `MergeChain.`
+* `MergeChain.merger`
+* `MergeChain.onExisting`
## `merge`
-* `merge`
+* `merge`
## `setChosen`
-* `setChosen`
+* `setChosen`
@@ -42,7 +36,9 @@
-# (parent=undefined)
+(parent=undefined)
+
+
[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/MergeChain.js#L54 "View in source") [Ⓣ][1]
Function
@@ -68,34 +64,35 @@ console.dir(map)
-
-
-
-
-## `MergeChain.prototype`
-
🔬 Tests: MergeChain
-# MergeChain.prototype.
+MergeChain.
+
+
[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/MergeChain.js#L9 "View in source") [Ⓣ][1]
Map
-### @todos
+#### @see
+
+* deps/dopemerge
+
+#### @todos
- [ ] consider just making this a function,
because 80/20 onValue merger & onExisting
are rarely used & are easily overridable with .merge
-### @extends
+#### @extends
ChainedMapBase
-#### Since
+
+#### @Since
1.0.0
---
@@ -104,12 +101,19 @@ ChainedMapBase
-# MergeChain.prototype.merger(opts=undefined)
+MergeChain.merger(opts=undefined)
+
+
[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/MergeChain.js#L93 "View in source") [Ⓣ][1]
(Function): options for merging with dopemerge
-#### Since
+
+#### @see
+
+* dopemerge
+
+#### @Since
1.0.2
#### Arguments
@@ -138,12 +142,15 @@ ChainedMapBase
-# MergeChain.prototype.exports
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/MergeChain.js#L334 "View in source") [Ⓣ][1]
+MergeChain.exports
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/MergeChain.js#L335 "View in source") [Ⓣ][1]
unknown
-#### Since
+
+#### @Since
0.9.0
#### Example
@@ -170,18 +177,25 @@ chain.get('str')
-# merge([obj2=undefined])
+merge([obj2=undefined])
+
+
[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/MergeChain.js#L122 "View in source") [Ⓣ][1]
(Function): merges object in, goes through all keys, checks cbs, dopemerges
-### @todos
+#### @see
+
+* ChainedMap
+
+#### @todos
- [ ] issue here if we extend without shorthands &
we want to merge existing values... :s
-#### Since
+
+#### @Since
1.0.0
#### Arguments
@@ -211,12 +225,15 @@ chain.entries()
-# setChosen(keyToSet=undefined, valueToSet=undefined)
+setChosen(keyToSet=undefined, valueToSet=undefined)
+
+
[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/MergeChain.js#L199 "View in source") [Ⓣ][1]
(Function): when fn is a full method, not an extended shorthand
-#### Since
+
+#### @Since
0.5.0
#### Arguments
diff --git a/docs/docdown/MethodChain.md b/docs/docdown/MethodChain.md
index 8922ce9..512975e 100644
--- a/docs/docdown/MethodChain.md
+++ b/docs/docdown/MethodChain.md
@@ -5,49 +5,43 @@
## `MethodChain`
-* ``
-
-
-
-
-
-## `MethodChain.prototype`
-* `MethodChain.prototype.`
-* `MethodChain.prototype._build`
-* `MethodChain.prototype._defaults`
-* `MethodChain.prototype.autoIncrement`
-* `MethodChain.prototype.build`
-* `MethodChain.prototype.decorate`
-* `MethodChain.prototype.name`
-* `MethodChain.prototype.schema`
+* ``
+* `MethodChain.`
+* `MethodChain._build`
+* `MethodChain._defaults`
+* `MethodChain.autoIncrement`
+* `MethodChain.build`
+* `MethodChain.decorate`
+* `MethodChain.name`
+* `MethodChain.schema`
## `add`
-* `add`
+* `add`
## `alias`
-* `alias`
+* `alias`
## `if`
-* `if`
+* `if`
## `this.extend`
-* `this.extend`
+* `this.extend`
@@ -61,13 +55,15 @@
-
+
+
+
[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/MethodChain.js#L2 "View in source") [Ⓣ][1]
unknown
-### @todos
+#### @todos
- [ ] clarify .set vs .call
@@ -75,25 +71,21 @@ unknown
-
-
-
-
-## `MethodChain.prototype`
-
🌊 Types: MethodChain.d
🔬 Tests: MethodChain
-# MethodChain.prototype.
+MethodChain.
+
+
[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/MethodChain.js#L112 "View in source") [Ⓣ][1]
(Map): ❗ using `+` will call `.build()` in a shorthand fashion
-### @todos
+#### @todos
- [ ] maybe abstract the most re-usable core as a protected class
so the shorthands could be used, and more functionality made external
@@ -102,11 +94,12 @@ unknown
!!! .sponge - absorn properties into the store
-### @extends
+#### @extends
ChainedMap
-#### Since
+
+#### @Since
4.0.0
---
@@ -115,24 +108,27 @@ ChainedMap
-# MethodChain.prototype._build(name=undefined, parent=undefined)
+MethodChain._build(name=undefined, parent=undefined)
+
+
[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/MethodChain.js#L441 "View in source") [Ⓣ][1]
Function
-### @notes
+#### @notes
* scoping here adding default functions have to rescope arguments
-### @todos
+#### @todos
- [ ] allow config of method var in plugins since it is scoped...
- [ ] add to .meta(shorthands)
- [ ] reduce complexity if perf allows
-#### Since
+
+#### @Since
4.0.0-alpha.1
#### Arguments
@@ -148,20 +144,23 @@ Function
-# MethodChain.prototype._defaults(name=undefined, parent=undefined, built=undefined)
+MethodChain._defaults(name=undefined, parent=undefined, built=undefined)
+
+
[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/MethodChain.js#L403 "View in source") [Ⓣ][1]
Function
-### @todos
+#### @todos
- [ ] optimize the size of this
with some bitwise operators
hashing the things that have been defaulted
also could be plugin
-#### Since
+
+#### @Since
4.0.0
#### Arguments
@@ -210,12 +209,19 @@ let methodFactories
-# MethodChain.prototype.autoIncrement()
+MethodChain.autoIncrement()
+
+
[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/MethodChain.js#L743 "View in source") [Ⓣ][1]
(Function): adds a plugin to increment the value on every call
-#### Since
+
+#### @see
+
+* plugins/autoIncrement
+
+#### @Since
0.4.0
#### Returns
@@ -234,17 +240,24 @@ chain.get('index')
-# MethodChain.prototype.build([returnValue=undefined])
+MethodChain.build([returnValue=undefined])
+
+
[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/MethodChain.js#L331 "View in source") [Ⓣ][1]
(Function): set the actual method, also need .context - use .parent
-### @todos
+#### @see
+
+* https://github.com/iluwatar/java-design-patterns/tree/master/step-builder
+
+#### @todos
- [ ] if passing in a name that already exists, operations are decorations... (partially done)
-#### Since
+
+#### @Since
4.0.0
#### Arguments
@@ -269,11 +282,18 @@ typeof obj.getEh
-# MethodChain.prototype.decorate([parentToDecorate=undefined])
+MethodChain.decorate([parentToDecorate=undefined])
+
+
[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/MethodChain.js#L712 "View in source") [Ⓣ][1]
(Function): add methods to the parent for easier chaining
+
+#### @see
+
+* plugins/decorate
+* ChainedMap.parent
#### Arguments
1. `[parentToDecorate=undefined]` *(Object)*: decorate a specific parent shorthand
@@ -336,7 +356,9 @@ master.eh.get('advanced')
-# MethodChain.prototype.name(methods=undefined)
+MethodChain.name(methods=undefined)
+
+
[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/MethodChain.js#L225 "View in source") [Ⓣ][1]
(Function): setup methods to build
@@ -361,7 +383,9 @@ typeof obj.eh
-# MethodChain.prototype.schema(obj=undefined)
+MethodChain.schema(obj=undefined)
+
+
[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/MethodChain.js#L306 "View in source") [Ⓣ][1]
(Function): an object that contains nestable `.type`s
@@ -369,7 +393,7 @@ they are recursively *(using an optimized traversal cache)* mapped to validators
❗ this method auto-calls .build, all other method config calls should be done before it
-### @todos
+#### @todos
- [ ] link to `deps/is` docs
- [ ] move out into a plugin to show how easy it is to use a plugin
@@ -381,7 +405,8 @@ they are recursively *(using an optimized traversal cache)* mapped to validators
and then have some demo for how to validate on set using say mobx
observables for all the way down...
-#### Since
+
+#### @Since
4.0.0
#### Arguments
@@ -437,12 +462,15 @@ chain.updated_at = false
-# add(methodFactory=undefined)
+add(methodFactory=undefined)
+
+
[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/MethodChain.js#L778 "View in source") [Ⓣ][1]
(Function): add methodFactories easily
-#### Since
+
+#### @Since
4.0.0-beta.2
#### Arguments
@@ -484,17 +512,20 @@ chain.eh()
-# alias(aliases=undefined)
+alias(aliases=undefined)
+
+
[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/MethodChain.js#L177 "View in source") [Ⓣ][1]
(Function): alias methods
-### @notes
+#### @notes
* these would be .transform
-#### Since
+
+#### @Since
2.0.0
#### Arguments
@@ -524,7 +555,9 @@ chain.get('canada')
-# if()
+if()
+
+
[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/MethodChain.js#L233 "View in source") [Ⓣ][1]
(Function): this is a plugin for building methods schema defaults value to `.type` this defaults values to `.onCall`
@@ -541,7 +574,9 @@ chain.get('canada')
-# this.extend()
+this.extend()
+
+
[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/MethodChain.js#L136 "View in source") [Ⓣ][1]
Function
diff --git a/docs/docdown/README.md b/docs/docdown/README.md
index 10f8e38..b2c919c 100644
--- a/docs/docdown/README.md
+++ b/docs/docdown/README.md
@@ -6,8 +6,7 @@
- `├` `─` [MergeChain](https://github.com/fluents/chain-able/blob/master/docs/docdown/MergeChain.js)
- `├` `─` [MethodChain](https://github.com/fluents/chain-able/blob/master/docs/docdown/MethodChain.js)
- `├` `─` [TraverseChain](https://github.com/fluents/chain-able/blob/master/docs/docdown/TraverseChain.js)
-- `├` `─` [_Playground](https://github.com/fluents/chain-able/blob/master/docs/docdown/_Playground.js)
-- `├` `─` [compose](https://github.com/fluents/chain-able/blob/master/docs/docdown/src/compose/)
+- `├` `─` [compose](compose)
- `│` `├` `─` [DotProp](https://github.com/fluents/chain-able/blob/master/docs/docdown/compose/DotProp.js)
- `│` `├` `─` [Observe](https://github.com/fluents/chain-able/blob/master/docs/docdown/compose/Observe.js)
- `│` `├` `─` [Shorthands](https://github.com/fluents/chain-able/blob/master/docs/docdown/compose/Shorthands.js)
@@ -15,34 +14,42 @@
- `│` `├` `─` [compose](https://github.com/fluents/chain-able/blob/master/docs/docdown/compose/compose.js)
- `│` `├` `─` [decorators](https://github.com/fluents/chain-able/blob/master/docs/docdown/compose/decorators.js)
- `│` `└` `─` [index](https://github.com/fluents/chain-able/blob/master/docs/docdown/compose/index.js)
-- `├` `─` [deps](https://github.com/fluents/chain-able/blob/master/docs/docdown/src/deps/)
+- `├` `─` [deps](deps)
- `│` `├` `─` [argumentor](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/argumentor.js)
-- `│` `├` `─` [array](https://github.com/fluents/chain-able/blob/master/docs/docdown/src/deps/array/)
-- `│` `│` `├` `─` [insert-at-index](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/array/insert-at-index.js)
+- `│` `├` `─` [array](array)
+- `│` `│` `├` `─` [concat](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/array/concat.js)
+- `│` `│` `├` `─` [insertAtIndex](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/array/insertAtIndex.js)
- `│` `│` `└` `─` [uniq](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/array/uniq.js)
-- `│` `├` `─` [cache](https://github.com/fluents/chain-able/blob/master/docs/docdown/src/deps/cache/)
+- `│` `├` `─` [cache](cache)
- `│` `│` `├` `─` [index](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/cache/index.js)
+- `│` `│` `├` `─` [pooler](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/cache/pooler.js)
- `│` `│` `└` `─` [scoped](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/cache/scoped.js)
-- `│` `├` `─` [camel-case](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/camel-case.js)
-- `│` `├` `─` [concat](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/concat.js)
-- `│` `├` `─` [conditional](https://github.com/fluents/chain-able/blob/master/docs/docdown/src/deps/conditional/)
+- `│` `├` `─` [conditional](conditional)
- `│` `│` `├` `─` [all](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/conditional/all.js)
- `│` `│` `├` `─` [and](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/conditional/and.js)
- `│` `│` `├` `─` [eq](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/conditional/eq.js)
-- `│` `│` `├` `─` [includes](https://github.com/fluents/chain-able/blob/master/docs/docdown/src/deps/conditional/includes/)
+- `│` `│` `├` `─` [eqeq](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/conditional/eqeq.js)
+- `│` `│` `├` `─` [includes](includes)
- `│` `│` `│` `├` `─` [all](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/conditional/includes/all.js)
- `│` `│` `│` `├` `─` [any](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/conditional/includes/any.js)
+- `│` `│` `│` `├` `─` [flipped](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/conditional/includes/flipped.js)
- `│` `│` `│` `├` `─` [includes](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/conditional/includes/includes.js)
- `│` `│` `│` `└` `─` [index](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/conditional/includes/index.js)
+- `│` `│` `├` `─` [index](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/conditional/index.js)
- `│` `│` `├` `─` [not](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/conditional/not.js)
- `│` `│` `├` `─` [or](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/conditional/or.js)
- `│` `│` `└` `─` [some](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/conditional/some.js)
+- `│` `├` `─` [construct](construct)
+- `│` `│` `├` `─` [map](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/construct/map.js)
+- `│` `│` `├` `─` [regexp](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/construct/regexp.js)
+- `│` `│` `└` `─` [set](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/construct/set.js)
- `│` `├` `─` [define](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/define.js)
-- `│` `├` `─` [dopemerge](https://github.com/fluents/chain-able/blob/master/docs/docdown/src/deps/dopemerge/)
+- `│` `├` `─` [dopemerge](dopemerge)
- `│` `│` `├` `─` [dopemerge](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/dopemerge/dopemerge.js)
+- `│` `│` `├` `─` [emptyTarget](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/dopemerge/emptyTarget.js)
- `│` `│` `├` `─` [index](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/dopemerge/index.js)
- `│` `│` `└` `─` [map](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/dopemerge/map.js)
-- `│` `├` `─` [dot](https://github.com/fluents/chain-able/blob/master/docs/docdown/src/deps/dot/)
+- `│` `├` `─` [dot](dot)
- `│` `│` `├` `─` [delete](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/dot/delete.js)
- `│` `│` `├` `─` [dot-prop](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/dot/dot-prop.js)
- `│` `│` `├` `─` [dottable](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/dot/dottable.js)
@@ -53,27 +60,70 @@
- `│` `│` `├` `─` [paths](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/dot/paths.js)
- `│` `│` `├` `─` [segments](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/dot/segments.js)
- `│` `│` `└` `─` [set](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/dot/set.js)
-- `│` `├` `─` [encase](https://github.com/fluents/chain-able/blob/master/docs/docdown/src/deps/encase/)
+- `│` `├` `─` [encase](encase)
- `│` `│` `├` `─` [encase](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/encase/encase.js)
- `│` `│` `├` `─` [index](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/encase/index.js)
- `│` `│` `├` `─` [tryCatch](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/encase/tryCatch.js)
- `│` `│` `└` `─` [withSpecification](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/encase/withSpecification.js)
-- `│` `├` `─` [env](https://github.com/fluents/chain-able/blob/master/docs/docdown/src/deps/env/)
+- `│` `├` `─` [env](env)
- `│` `│` `├` `─` [debug](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/env/debug.js)
- `│` `│` `└` `─` [dev](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/env/dev.js)
+- `│` `├` `─` [expressions](expressions)
+- `│` `│` `├` `─` [above](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/expressions/above.js)
+- `│` `│` `├` `─` [below](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/expressions/below.js)
+- `│` `│` `├` `─` [between](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/expressions/between.js)
+- `│` `│` `├` `─` [bitwiseMathOperator](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/expressions/bitwiseMathOperator.js)
+- `│` `│` `├` `─` [even](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/expressions/even.js)
+- `│` `│` `├` `─` [expressions](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/expressions/expressions.js)
+- `│` `│` `├` `─` [increment](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/expressions/increment.js)
+- `│` `│` `├` `─` [index](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/expressions/index.js)
+- `│` `│` `└` `─` [odd](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/expressions/odd.js)
+- `│` `├` `─` [fp](fp)
+- `│` `│` `├` `─` [always](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/fp/always.js)
+- `│` `│` `├` `─` [arity](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/fp/arity.js)
+- `│` `│` `├` `─` [callDestructure](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/fp/callDestructure.js)
+- `│` `│` `├` `─` [construct](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/fp/construct.js)
+- `│` `│` `├` `─` [constructInit](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/fp/constructInit.js)
+- `│` `│` `├` `─` [curry](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/fp/curry.js)
+- `│` `│` `├` `─` [first](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/fp/first.js)
+- `│` `│` `├` `─` [firstIndex](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/fp/firstIndex.js)
+- `│` `│` `├` `─` [flip](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/fp/flip.js)
+- `│` `│` `├` `─` [flip2](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/fp/flip2.js)
+- `│` `│` `├` `─` [fp](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/fp/fp.js)
+- `│` `│` `├` `─` [hasInMatching](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/fp/hasInMatching.js)
+- `│` `│` `├` `─` [includesCount](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/fp/includesCount.js)
+- `│` `│` `├` `─` [index](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/fp/index.js)
+- `│` `│` `├` `─` [invoke](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/fp/invoke.js)
+- `│` `│` `├` `─` [isPlaceholder](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/fp/isPlaceholder.js)
+- `│` `│` `├` `─` [last](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/fp/last.js)
+- `│` `│` `├` `─` [lastIndex](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/fp/lastIndex.js)
+- `│` `│` `├` `─` [mapWhere](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/fp/mapWhere.js)
+- `│` `│` `├` `─` [path](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/fp/path.js)
+- `│` `│` `├` `─` [pipe](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/fp/pipe.js)
+- `│` `│` `├` `─` [pipeTwo](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/fp/pipeTwo.js)
+- `│` `│` `├` `─` [prop](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/fp/prop.js)
+- `│` `│` `├` `─` [remove](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/fp/remove.js)
+- `│` `│` `├` `─` [replace](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/fp/replace.js)
+- `│` `│` `└` `─` [reverse](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/fp/reverse.js)
- `│` `├` `─` [gc](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/gc.js)
-- `│` `├` `─` [ignored](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/ignored.js)
- `│` `├` `─` [index](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/index.js)
-- `│` `├` `─` [is](https://github.com/fluents/chain-able/blob/master/docs/docdown/src/deps/is/)
+- `│` `├` `─` [is](is)
+- `│` `│` `├` `─` [JSON](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/is/JSON.js)
+- `│` `│` `├` `─` [arguments](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/is/arguments.js)
- `│` `│` `├` `─` [array](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/is/array.js)
+- `│` `│` `├` `─` [arrayOf](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/is/arrayOf.js)
- `│` `│` `├` `─` [async](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/is/async.js)
- `│` `│` `├` `─` [asyncish](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/is/asyncish.js)
- `│` `│` `├` `─` [boolean](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/is/boolean.js)
+- `│` `│` `├` `─` [booleanPrimitive](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/is/booleanPrimitive.js)
+- `│` `│` `├` `─` [browser](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/is/browser.js)
+- `│` `│` `├` `─` [buffer](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/is/buffer.js)
+- `│` `│` `├` `─` [circular](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/is/circular.js)
- `│` `│` `├` `─` [class](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/is/class.js)
- `│` `│` `├` `─` [date](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/is/date.js)
- `│` `│` `├` `─` [dot](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/is/dot.js)
+- `│` `│` `├` `─` [empty](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/is/empty.js)
- `│` `│` `├` `─` [enumerable](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/is/enumerable.js)
-- `│` `│` `├` `─` [eqeq](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/is/eqeq.js)
- `│` `│` `├` `─` [error](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/is/error.js)
- `│` `│` `├` `─` [false](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/is/false.js)
- `│` `│` `├` `─` [function](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/is/function.js)
@@ -81,21 +131,28 @@
- `│` `│` `├` `─` [hasIn](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/is/hasIn.js)
- `│` `│` `├` `─` [in](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/is/in.js)
- `│` `│` `├` `─` [index](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/is/index.js)
+- `│` `│` `├` `─` [instanceOf](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/is/instanceOf.js)
+- `│` `│` `├` `─` [iteratable](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/is/iteratable.js)
- `│` `│` `├` `─` [iterator](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/is/iterator.js)
- `│` `│` `├` `─` [map](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/is/map.js)
- `│` `│` `├` `─` [mapish](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/is/mapish.js)
+- `│` `│` `├` `─` [match](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/is/match.js)
- `│` `│` `├` `─` [matcher](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/is/matcher.js)
- `│` `│` `├` `─` [native](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/is/native.js)
- `│` `│` `├` `─` [nodejs](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/is/nodejs.js)
- `│` `│` `├` `─` [notEmptyArray](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/is/notEmptyArray.js)
+- `│` `│` `├` `─` [notNested](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/is/notNested.js)
+- `│` `│` `├` `─` [notRealOrIsEmpty](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/is/notRealOrIsEmpty.js)
- `│` `│` `├` `─` [null](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/is/null.js)
- `│` `│` `├` `─` [nullOrUndefined](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/is/nullOrUndefined.js)
- `│` `│` `├` `─` [number](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/is/number.js)
+- `│` `│` `├` `─` [numberPrimitive](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/is/numberPrimitive.js)
- `│` `│` `├` `─` [obj](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/is/obj.js)
-- `│` `│` `├` `─` [objLoose](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/is/objLoose.js)
+- `│` `│` `├` `─` [objNotNull](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/is/objNotNull.js)
- `│` `│` `├` `─` [objPure](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/is/objPure.js)
-- `│` `│` `├` `─` [objStrict](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/is/objStrict.js)
+- `│` `│` `├` `─` [objTypeof](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/is/objTypeof.js)
- `│` `│` `├` `─` [objWithKeys](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/is/objWithKeys.js)
+- `│` `│` `├` `─` [primitive](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/is/primitive.js)
- `│` `│` `├` `─` [promise](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/is/promise.js)
- `│` `│` `├` `─` [prototypeOf](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/is/prototypeOf.js)
- `│` `│` `├` `─` [real](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/is/real.js)
@@ -107,44 +164,74 @@
- `│` `│` `├` `─` [symbol](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/is/symbol.js)
- `│` `│` `├` `─` [toS](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/is/toS.js)
- `│` `│` `├` `─` [true](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/is/true.js)
-- `│` `│` `└` `─` [undefined](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/is/undefined.js)
-- `│` `├` `─` [matcher](https://github.com/fluents/chain-able/blob/master/docs/docdown/src/deps/matcher/)
+- `│` `│` `├` `─` [undefined](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/is/undefined.js)
+- `│` `│` `├` `─` [undefinedLike](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/is/undefinedLike.js)
+- `│` `│` `├` `─` [weakMap](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/is/weakMap.js)
+- `│` `│` `└` `─` [weakSet](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/is/weakSet.js)
+- `│` `├` `─` [matcher](matcher)
- `│` `│` `├` `─` [any-key-val](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/matcher/any-key-val.js)
- `│` `│` `├` `─` [escape-string-regex](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/matcher/escape-string-regex.js)
- `│` `│` `├` `─` [index](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/matcher/index.js)
- `│` `│` `├` `─` [matcher](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/matcher/matcher.js)
- `│` `│` `├` `─` [to-regexp](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/matcher/to-regexp.js)
- `│` `│` `└` `─` [to-test](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/matcher/to-test.js)
-- `│` `├` `─` [meta](https://github.com/fluents/chain-able/blob/master/docs/docdown/src/deps/meta/)
+- `│` `├` `─` [meta](meta)
- `│` `│` `├` `─` [decorated](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/meta/decorated.js)
- `│` `│` `├` `─` [enums](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/meta/enums.js)
+- `│` `│` `├` `─` [ignored](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/meta/ignored.js)
- `│` `│` `├` `─` [index](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/meta/index.js)
- `│` `│` `├` `─` [keymap](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/meta/keymap.js)
- `│` `│` `├` `─` [meta](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/meta/meta.js)
- `│` `│` `├` `─` [observers](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/meta/observers.js)
- `│` `│` `├` `─` [shorthands](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/meta/shorthands.js)
- `│` `│` `└` `─` [transformers](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/meta/transformers.js)
-- `│` `├` `─` [reduce](https://github.com/fluents/chain-able/blob/master/docs/docdown/src/deps/reduce/)
+- `│` `├` `─` [native](native)
+- `│` `│` `├` `─` [arraySlice](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/native/arraySlice.js)
+- `│` `│` `├` `─` [functionToString](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/native/functionToString.js)
+- `│` `│` `├` `─` [hasOwnProperty](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/native/hasOwnProperty.js)
+- `│` `│` `├` `─` [objectToString](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/native/objectToString.js)
+- `│` `│` `└` `─` [propertyIsEnumerable](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/native/propertyIsEnumerable.js)
+- `│` `├` `─` [reduce](reduce)
- `│` `│` `├` `─` [clean](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/reduce/clean.js)
- `│` `│` `├` `─` [entries](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/reduce/entries.js)
- `│` `│` `├` `─` [index](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/reduce/index.js)
-- `│` `│` `├` `─` [objects](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/reduce/objects.js)
-- `│` `│` `└` `─` [reduce](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/reduce/reduce.js)
-- `│` `├` `─` [string](https://github.com/fluents/chain-able/blob/master/docs/docdown/src/deps/string/)
+- `│` `│` `├` `─` [reduce](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/reduce/reduce.js)
+- `│` `│` `└` `─` [toObj](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/reduce/toObj.js)
+- `│` `├` `─` [string](string)
+- `│` `│` `├` `─` [camelCase](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/string/camelCase.js)
- `│` `│` `├` `─` [class-names](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/string/class-names.js)
+- `│` `│` `├` `─` [firstToUpperCase](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/string/firstToUpperCase.js)
- `│` `│` `└` `─` [prefix](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/string/prefix.js)
-- `│` `├` `─` [symbols](https://github.com/fluents/chain-able/blob/master/docs/docdown/src/deps/symbols/)
+- `│` `├` `─` [symbols](symbols)
- `│` `│` `├` `─` [index](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/symbols/index.js)
- `│` `│` `├` `─` [instance](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/symbols/instance.js)
- `│` `│` `├` `─` [iterator](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/symbols/iterator.js)
- `│` `│` `├` `─` [primitive](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/symbols/primitive.js)
- `│` `│` `├` `─` [species](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/symbols/species.js)
- `│` `│` `└` `─` [spreadable](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/symbols/spreadable.js)
+- `│` `├` `─` [to](to)
+- `│` `│` `├` `─` [array](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/to/array.js)
+- `│` `│` `├` `─` [boolean](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/to/boolean.js)
+- `│` `│` `├` `─` [coerce](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/to/coerce.js)
+- `│` `│` `├` `─` [index](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/to/index.js)
+- `│` `│` `├` `─` [integer](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/to/integer.js)
+- `│` `│` `├` `─` [map](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/to/map.js)
+- `│` `│` `├` `─` [number](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/to/number.js)
+- `│` `│` `├` `─` [object](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/to/object.js)
+- `│` `│` `├` `─` [set](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/to/set.js)
+- `│` `│` `├` `─` [setToArray](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/to/setToArray.js)
+- `│` `│` `├` `─` [string](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/to/string.js)
+- `│` `│` `└` `─` [to](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/to/to.js)
- `│` `├` `─` [to-arr](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/to-arr.js)
- `│` `├` `─` [traverse](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/traverse.js)
-- `│` `├` `─` [traversers](https://github.com/fluents/chain-able/blob/master/docs/docdown/src/deps/traversers/)
-- `│` `│` `└` `─` [eq](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/traversers/eq.js)
-- `│` `├` `─` [util](https://github.com/fluents/chain-able/blob/master/docs/docdown/src/deps/util/)
+- `│` `├` `─` [traversers](traversers)
+- `│` `│` `├` `─` [_eq](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/traversers/_eq.js)
+- `│` `│` `├` `─` [copy](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/traversers/copy.js)
+- `│` `│` `├` `─` [eq](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/traversers/eq.js)
+- `│` `│` `├` `─` [eqValue](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/traversers/eqValue.js)
+- `│` `│` `├` `─` [stringify](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/traversers/stringify.js)
+- `│` `│` `└` `─` [traverse-comments](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/traversers/traverse-comments.js)
+- `│` `├` `─` [util](util)
- `│` `│` `├` `─` [assign](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/util/assign.js)
- `│` `│` `├` `─` [charCodeAtZero](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/util/charCodeAtZero.js)
- `│` `│` `├` `─` [flatten](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/util/flatten.js)
@@ -152,14 +239,21 @@
- `│` `│` `├` `─` [getDescriptor](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/util/getDescriptor.js)
- `│` `│` `├` `─` [getPrototypeOf](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/util/getPrototypeOf.js)
- `│` `│` `├` `─` [hasOwnProperty](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/util/hasOwnProperty.js)
+- `│` `│` `├` `─` [index](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/util/index.js)
- `│` `│` `├` `─` [keys](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/util/keys.js)
+- `│` `│` `├` `─` [keysObjOrArray](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/util/keysObjOrArray.js)
+- `│` `│` `├` `─` [keywords](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/util/keywords.js)
- `│` `│` `├` `─` [length](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/util/length.js)
+- `│` `│` `├` `─` [lengthFromZero](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/util/lengthFromZero.js)
- `│` `│` `├` `─` [lengthMinusOne](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/util/lengthMinusOne.js)
+- `│` `│` `├` `─` [localGlobal](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/util/localGlobal.js)
- `│` `│` `├` `─` [nonEnumerableTypes](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/util/nonEnumerableTypes.js)
+- `│` `│` `├` `─` [noop](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/util/noop.js)
- `│` `│` `├` `─` [props](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/util/props.js)
- `│` `│` `├` `─` [simpleKindOf](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/util/simpleKindOf.js)
-- `│` `│` `└` `─` [typeof](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/util/typeof.js)
-- `│` `└` `─` [validators](https://github.com/fluents/chain-able/blob/master/docs/docdown/src/deps/validators/)
+- `│` `│` `├` `─` [typeof](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/util/typeof.js)
+- `│` `│` `└` `─` [util](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/util/util.js)
+- `│` `└` `─` [validators](validators)
- `│` `├` `─` [error](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/validators/error.js)
- `│` `├` `─` [index](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/validators/index.js)
- `│` `├` `─` [schemaBuilder](https://github.com/fluents/chain-able/blob/master/docs/docdown/deps/validators/schemaBuilder.js)
@@ -167,11 +261,12 @@
- `├` `─` [index](https://github.com/fluents/chain-able/blob/master/docs/docdown/index.js)
- `├` `─` [index](index)
- `│` `└` `─` [index.js](https://github.com/fluents/chain-able/blob/master/docs/docdown/index.web.js)
-- `├` `─` [plugins](https://github.com/fluents/chain-able/blob/master/docs/docdown/src/plugins/)
+- `├` `─` [plugins](plugins)
- `│` `├` `─` [autoGetSet](https://github.com/fluents/chain-able/blob/master/docs/docdown/plugins/autoGetSet.js)
- `│` `├` `─` [autoIncrement](https://github.com/fluents/chain-able/blob/master/docs/docdown/plugins/autoIncrement.js)
- `│` `├` `─` [decorate](https://github.com/fluents/chain-able/blob/master/docs/docdown/plugins/decorate.js)
- `│` `├` `─` [encase](https://github.com/fluents/chain-able/blob/master/docs/docdown/plugins/encase.js)
+- `│` `├` `─` [getterOnSet](https://github.com/fluents/chain-able/blob/master/docs/docdown/plugins/getterOnSet.js)
- `│` `├` `─` [index](https://github.com/fluents/chain-able/blob/master/docs/docdown/plugins/index.js)
- `│` `├` `─` [merge](https://github.com/fluents/chain-able/blob/master/docs/docdown/plugins/merge.js)
- `│` `├` `─` [obj](https://github.com/fluents/chain-able/blob/master/docs/docdown/plugins/obj.js)
diff --git a/docs/docdown/TraverseChain.md b/docs/docdown/TraverseChain.md
index 2d2d49a..dfcc81c 100644
--- a/docs/docdown/TraverseChain.md
+++ b/docs/docdown/TraverseChain.md
@@ -4,22 +4,22 @@
-## `Traverse.prototype`
-* `Traverse.prototype.exports`
+## `Traverse`
+* `Traverse.exports`
-## `TraverseChain.prototype`
-* `TraverseChain.prototype.traverse`
+## `TraverseChain`
+* `TraverseChain.traverse`
## `traversed`
-* `traversed`
+* `traversed`
@@ -29,7 +29,7 @@
-## `Traverse.prototype`
+## `Traverse`
@@ -37,17 +37,23 @@
🔬 Tests: TraverseChain
-# Traverse.prototype.exports
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/TraverseChain.js#L29 "View in source") [Ⓣ][1]
+Traverse.exports
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/TraverseChain.js#L30 "View in source") [Ⓣ][1]
Map
-### @symb
+#### @see
+
+* deps/traverse
+
+#### @symb
👣
-### @classProps
+#### @classProps
* {obj}
* {keys}
@@ -57,11 +63,12 @@ Map
* {clone}
-### @extends
+#### @extends
ChainedMapBase
-#### Since
+
+#### @Since
1.0.0
---
@@ -72,16 +79,19 @@ ChainedMapBase
-## `TraverseChain.prototype`
+## `TraverseChain`
-# TraverseChain.prototype.traverse([shouldReturn=false])
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/TraverseChain.js#L90 "View in source") [Ⓣ][1]
+TraverseChain.traverse([shouldReturn=false])
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/TraverseChain.js#L92 "View in source") [Ⓣ][1]
(Function): runs traverser, checks the tests, calls the onMatch
-#### Since
+
+#### @Since
1.0.0
#### Arguments
@@ -131,12 +141,19 @@ traversed
-# traversed()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/TraverseChain.js#L172 "View in source") [Ⓣ][1]
+traversed()
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/TraverseChain.js#L192 "View in source") [Ⓣ][1]
(Function): value traversed in traverse
-#### Since
+
+#### @see
+
+* TraverseChain.traverse
+
+#### @Since
1.0.0
#### Returns
@@ -205,4 +222,4 @@ const eh = {
- [1]: #traverse.prototype "Jump back to the TOC."
+ [1]: #traverse "Jump back to the TOC."
diff --git a/docs/docdown/_Playground.md b/docs/docdown/_Playground.md
deleted file mode 100644
index f8d5ff5..0000000
--- a/docs/docdown/_Playground.md
+++ /dev/null
@@ -1,62 +0,0 @@
-# _Playground.js API documentation
-
-
-
-
-
-## `ChainedMapBase.prototype`
-* `ChainedMapBase.prototype.playground`
-
-
-
-
-
-
-
-
-
-## `ChainedMapBase.prototype`
-
-
-
-🌊 Types: ChainedMapBase.d
-
-🔬 Tests: ChainedMap
-
-# ChainedMapBase.prototype.playground
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/_Playground.js#L31 "View in source") [Ⓣ][1]
-
-(Chainable): 3 steps 0. enhance error 1. encase function with a specification 2. build a function to call onInvalid or onInvalid depending
-
-
-### @see
-
-* articles/es6 maps in depth
-* Developer.mozilla.org/en/docs/web/java script/reference/global objects/map
-* fluents/chain able/blob/master/src/chainable.js
-* fluents/chain able/blob/master/src/merge chain.js
-* fluents/chain able/blob/master/src/method chain.js
-* fluents/chain able/blob/master/src/chained map.js
-
-### @classProps
-
-* {meta} meta fn
-* {store} main store
-
-
-### @extends
-Chainable
-
-
-#### Since
-4.0.0-alpha.1
-
----
-
-
-
-
-
-
-
- [1]: #chainedmapbase.prototype "Jump back to the TOC."
diff --git a/docs/docdown/aio.md b/docs/docdown/aio.md
index c371dfa..ad4b527 100644
--- a/docs/docdown/aio.md
+++ b/docs/docdown/aio.md
@@ -4,939 +4,868 @@
-## `CM`
-* `CM`
+## `Chainable`
+* `Chainable.Chainable`
+* `Chainable.clear`
+* `Chainable.delete`
+* `Chainable.end`
+* `Chainable.has`
+* `Chainable.length`
+* `Chainable.prototype[iterator]`
+* `Chainable.prototype[primitive]`
+* `Chainable.values`
+* `Chainable.when`
-## `Chainable.prototype`
-* `Chainable.prototype.Chainable`
-
-
-
-
-
-## `ChainedMapBase.prototype`
-* `ChainedMapBase.prototype.CMC`
-* `ChainedMapBase.prototype.compose`
-* `ChainedMapBase.prototype.entries`
-* `ChainedMapBase.prototype.extend`
-* `ChainedMapBase.prototype.from`
-* `ChainedMapBase.prototype.get`
-* `ChainedMapBase.prototype.set`
-* `ChainedMapBase.prototype.tap`
+## `ChainedMapBase`
+* `ChainedMapBase.ComposeChainedMap`
+* `ChainedMapBase.ComposeChainedMapBase`
+* `ChainedMapBase.compose`
+* `ChainedMapBase.entries`
+* `ChainedMapBase.extend`
+* `ChainedMapBase.from`
+* `ChainedMapBase.get`
+* `ChainedMapBase.set`
+* `ChainedMapBase.tap`
## `ChainedSet`
-* `ChainedSet`
+* `ChainedSet.ChainedSet`
+* `ChainedSet.add`
+* `ChainedSet.merge`
+* `ChainedSet.prepend`
-## `DotProp.prototype`
-* `DotProp.prototype.get`
-* `DotProp.prototype.set`
+## `DotProp`
+* `DotProp.get`
+* `DotProp.set`
-## `FactoryChain.prototype`
-* `FactoryChain.prototype.FactoryChain`
-* `FactoryChain.prototype.chainUpDowns`
-* `FactoryChain.prototype.factory`
-* `FactoryChain.prototype.getData`
-* `FactoryChain.prototype.prop`
-* `FactoryChain.prototype.props`
+## `FactoryChain`
+* `FactoryChain.FactoryChain`
+* `FactoryChain.chainUpDowns`
+* `FactoryChain.factory`
+* `FactoryChain.getData`
+* `FactoryChain.prop`
+* `FactoryChain.props`
-## `MergeChain.prototype`
-* `MergeChain.prototype.MergeChain`
-* `MergeChain.prototype.init`
-* `MergeChain.prototype.onExisting`
+## `MergeChain`
+* `MergeChain.MergeChain`
+* `MergeChain.init`
+* `MergeChain.onExisting`
-## `MethodChain.prototype`
-* `MethodChain.prototype.MethodChain`
-* `MethodChain.prototype._build`
-* `MethodChain.prototype._defaults`
-* `MethodChain.prototype.autoGetSet`
-* `MethodChain.prototype.autoIncrement`
-* `MethodChain.prototype.build`
-* `MethodChain.prototype.decorate`
-* `MethodChain.prototype.decorate`
-* `MethodChain.prototype.name`
-* `MethodChain.prototype.schema`
+## `MethodChain`
+* `MethodChain.MethodChain`
+* `MethodChain._build`
+* `MethodChain._defaults`
+* `MethodChain.autoGetSet`
+* `MethodChain.autoIncrement`
+* `MethodChain.build`
+* `MethodChain.decorate`
+* `MethodChain.decorate`
+* `MethodChain.name`
+* `MethodChain.schema`
-## `Observe.prototype`
-* `Observe.prototype.`
-* `Observe.prototype.DotProp`
-* `Observe.prototype.Observe`
+## `Observe`
+* `Observe.`
+* `Observe.DotProp`
+* `Observe.Observe`
-## `ShorthandChain.prototype`
-* `ShorthandChain.prototype.return`
-* `ShorthandChain.prototype.setIfEmpty`
-* `ShorthandChain.prototype.wrap`
+## `ShorthandChain`
+* `ShorthandChain.return`
+* `ShorthandChain.setIfEmpty`
+* `ShorthandChain.wrap`
## `Transform`
-* `Transform`
+* `Transform`
-## `TransformChain.prototype`
-* `TransformChain.prototype.`
-* `TransformChain.prototype.remap`
-* `TransformChain.prototype.set`
-* `TransformChain.prototype.transform`
+## `TransformChain`
+* `TransformChain.`
+* `TransformChain.remap`
+* `TransformChain.set`
+* `TransformChain.transform`
-## `Traverse.prototype`
-* `Traverse.prototype.`
-* `Traverse.prototype.`
-* `Traverse.prototype.TraverseChain`
-* `Traverse.prototype.clone`
-* `Traverse.prototype.forEach`
-* `Traverse.prototype.get`
-* `Traverse.prototype.has`
-* `Traverse.prototype.nodes`
-* `Traverse.prototype.paths`
-* `Traverse.prototype.reduce`
-* `Traverse.prototype.set`
+## `Traverse`
+* `Traverse.TraverseChain`
+* `Traverse.checkIteratable`
+* `Traverse.clone`
+* `Traverse.copy`
+* `Traverse.eq`
+* `Traverse.eqValue`
+* `Traverse.forEach`
+* `Traverse.iterate`
+* `Traverse.remove`
+* `Traverse.skip`
+* `Traverse.stop`
+* `Traverse.update`
-## `TraverseChain.prototype`
-* `TraverseChain.prototype.traverse`
+## `TraverseChain`
+* `TraverseChain.traverse`
## `add`
-* `add`
-* `add`
+* `add`
## `addTypes`
-* `addTypes`
-
-
-
-
-
-## `after`
-* `after`
+* `addTypes`
## `alias`
-* `alias`
-
-
-
-
-
-## `allProperties`
-* `allProperties`
+* `alias`
## `anyKeyVal`
-* `anyKeyVal`
+* `anyKeyVal`
## `argumentor`
-* `argumentor`
+* `argumentor`
## `arithmeticTypeFactory`
-* `arithmeticTypeFactory`
+* `arithmeticTypeFactory`
## `autoIncrement`
-* `autoIncrement`
-
-
-
-
-
-## `before`
-* `before`
+* `autoIncrement`
-## `block`
-* `block`
+## `builder`
+* `builder`
-## `builder`
-* `builder`
+## `camelCase`
+* `camelCase`
-## `camelCase`
-* `camelCase`
+## `clone`
+* `clone`
-## `circular`
-* `circular`
+## `compose`
+* `compose.compose`
-## `clear`
-* `clear`
+## `concat`
+* `concat`
-## `compose.prototype`
-* `compose.prototype.compose`
+## `conditional`
+* `conditional.all`
+* `conditional.and`
+* `conditional.not`
+* `conditional.or`
-## `conditional.prototype`
-* `conditional.prototype.all`
-* `conditional.prototype.and`
-* `conditional.prototype.not`
-* `conditional.prototype.or`
+## `copy`
+* `copy`
## `debug`
-* `debug`
+* `debug`
## `define`
-* `define`
+* `define`
## `delete`
-* `delete`
-* `delete`
-* `delete`
+* `delete`
-## `dopemerge.prototype`
-* `dopemerge.prototype.cloneIfNeeded`
-* `dopemerge.prototype.defaultArrayMerge`
-* `dopemerge.prototype.dopemerge`
-* `dopemerge.prototype.emptyTarget`
-* `dopemerge.prototype.isMergeableObj`
+## `dopemerge`
+* `dopemerge.cloneIfNeeded`
+* `dopemerge.defaultArrayMerge`
+* `dopemerge.dopemerge`
+* `dopemerge.emptyTarget`
+* `dopemerge.isMergeableObj`
## `dot`
-* `dot`
+* `dot`
+* `dot.dot.delete`
+* `dot.dot.get`
+* `dot.dot.has`
+* `dot.dotPropSegments`
## `encase`
-* `encase`
-
-
-
-
-
-## `encase.prototype`
-* `encase.prototype.error$3`
-
-
-
-
-
-## `end`
-* `end`
+* `encase.encase`
+* `encase.error$3`
+* `encase.tryCatch`
+* `encase.withSpecification`
## `entries`
-* `entries`
+* `entries`
-## `forEach`
-* `forEach`
+## `fp`
+* `fp.`
+* `fp.`
+* `fp.`
+* `fp.`
+* `fp.`
+* `fp.`
+* `fp.`
+* `fp.`
+* `fp.arity`
+* `fp.mapWhere`
## `from`
-* `from`
+* `from`
## `get`
-* `get`
+* `get`
## `getMeta`
-* `getMeta`
+* `getMeta`
## `has`
-* `has`
-* `has`
-* `has`
+* `has`
+* `has`
## `if`
-* `if`
+* `if`
+
+
+
+
+
+## `includes`
+* `includes.includes`
## `index`
-* ``
-* ``
-* ``
-* ``
-* ``
-* ``
-* ``
-* ``
+* ``
+* ``
+* ``
+* ``
+* ``
+* ``
+* ``
-## `is.prototype`
-* `is.prototype.isBoolean`
-* `is.prototype.isDate`
-* `is.prototype.isError`
-* `is.prototype.isFalse`
-* `is.prototype.isFunction`
-* `is.prototype.isIterator`
-* `is.prototype.isMap`
-* `is.prototype.isMapish`
-* `is.prototype.isMatcher`
-* `is.prototype.isNotEmptyArray`
-* `is.prototype.isNull`
-* `is.prototype.isNullOrUndefined`
-* `is.prototype.isNumber`
-* `is.prototype.isObj`
-* `is.prototype.isObjLoose`
-* `is.prototype.isObjStrict`
-* `is.prototype.isObjWithKeys`
-* `is.prototype.isReal`
-* `is.prototype.isTrue`
-* `is.prototype.isUndefined`
-* `is.prototype.string`
-* `is.prototype.stringOrNumber`
-* `is.prototype.stringPrimitive`
-* `is.prototype.symbol`
-* `is.prototype.toS`
+## `is`
+* `is.`
+* `is.arrayOf`
+* `is.exports`
+* `is.hasIn`
+* `is.isArray`
+* `is.isAsync`
+* `is.isAsyncish`
+* `is.isBoolean`
+* `is.isBooleanPrimitive`
+* `is.isDate`
+* `is.isDot`
+* `is.isEnumerable`
+* `is.isError`
+* `is.isFalse`
+* `is.isFunction`
+* `is.isIn`
+* `is.isIterator`
+* `is.isMap`
+* `is.isMapish`
+* `is.isMatcher`
+* `is.isNull`
+* `is.isNullOrUndefined`
+* `is.isNumber`
+* `is.isNumberPrimitive`
+* `is.isObj`
+* `is.isObjLoose`
+* `is.isObjNotNull`
+* `is.isObjPure`
+* `is.isObjWithKeys`
+* `is.isPromise`
+* `is.isPrototypeOf`
+* `is.isReal`
+* `is.isTrue`
+* `is.isUndefined`
+* `is.primitive$2`
+* `is.string`
+* `is.stringOrNumber`
+* `is.stringPrimitive`
+* `is.symbol`
-## `is.prototype.index$12`
-* `is.prototype.index$12`
+## `is.index$12`
+* `is.index$12`
-## `isArray`
-* `isArray`
+## `isNotRealOrIsEmpty`
+* `isNotRealOrIsEmpty`
-## `isRoot`
-* `isRoot`
+## `iteratable`
+* `iteratable`
-## `key`
-* `key`
+## `keysObjOrArray`
+* `keysObjOrArray`
-## `level`
-* `level`
+## `lengthFromZero`
+* `lengthFromZero`
## `markForGarbageCollection`
-* `markForGarbageCollection`
+* `markForGarbageCollection`
-## `matcher.prototype`
-* `matcher.prototype.escapeStringRegExp`
-* `matcher.prototype.make`
-* `matcher.prototype.match`
-* `matcher.prototype.matcher`
-* `matcher.prototype.toRegExp`
+## `matcher`
+* `matcher.escapeStringRegExp`
+* `matcher.make`
+* `matcher.match`
+* `matcher.matcher`
+* `matcher.toRegExp`
## `merge`
-* `merge`
-* `merge`
-* `merge`
+* `merge`
+* `merge`
## `meta`
-* `meta`
+* `meta`
## `method`
-* `method`
+* `method`
## `methodEncasingFactory`
-* `methodEncasingFactory`
-
-
-
-
-
-## `node`
-* `node`
-
-
-
-
-
-## `node_`
-* `node_`
+* `methodEncasingFactory`
-## `parent`
-* `parent`
+## `noop`
+* `noop`
-## `path`
-* `path`
+## `notNested`
+* `notNested`
## `paths`
-* `paths`
-
-
-
-
-
-## `post`
-* `post`
-
-
-
-
-
-## `pre`
-* `pre`
-
-
-
-
-
-## `prepend`
-* `prepend`
+* `paths`
-## `prototype[iterator]`
-* `prototype[iterator]`
+## `pooler`
+* `pooler.addPoolingTo`
+* `pooler.oneArgumentPooler`
+* `pooler.standardReleaser`
-## `prototype[primitive]`
-* `prototype[primitive]`
+## `pooler.// const pooler`
+* `pooler.// const pooler`
## `reduce`
-* `reduce`
-
-
-
-
-
-## `reduce.prototype`
-* `reduce.prototype.clean`
+* `reduce`
+* `reduce.clean`
## `regexp`
-* `regexp`
-
-
-
-
-
-## `remove`
-* `remove`
-
-
-
-
-
-## `return`
-* `return`
+* `regexp`
## `schema`
-* `schema`
-
-
-
-
-
-## `schema.prototype`
-* `schema.prototype.typeListFactory`
-* `schema.prototype.typeValidator`
+* `schema`
+* `schema.typeListFactory`
+* `schema.typeValidator`
## `schemaFactory`
-* `schemaFactory`
+* `schemaFactory`
## `scopedEncase`
-* `scopedEncase`
+* `scopedEncase`
## `set`
-* `set`
+* `set`
## `set$$2`
-* `set$$2`
+* `set$$2`
## `setChosen`
-* `setChosen`
+* `setChosen`
## `simpleKindOf`
-* `simpleKindOf`
-
-
-
-
-
-## `state`
-* `state`
-
-
-
-
-
-## `stop`
-* `stop`
+* `simpleKindOf`
## `test`
-* `test`
+* `test`
## `this.extend`
-* `this.extend`
+* `this.extend`
## `toArr`
-* `toArr`
+* `toArr`
## `toTest`
-* `toTest`
+* `toTest`
## `traverse`
-* `traverse`
-* `traverse`
-
-
-
-
-
-## `traverse.prototype`
-* `traverse.prototype.eq`
+* `traverse`
## `traversed`
-* `traversed`
-
-
-
-
-
-## `tryCatch`
-* `tryCatch`
+* `traversed`
## `typedOnCall`
-* `typedOnCall`
+* `typedOnCall`
## `types`
-* `types`
+* `types`
-## `update`
-* `update`
-
-
-
-
-
-## `updateState`
-* `updateState`
+## `util`
+* `util.assign`
## `validators`
-* `validators`
+* `validators`
-## `values`
-* `values`
+## `while`
+* `while`
-
-
-## `when`
-* `when`
-
+
+
-## `while`
-* `while`
+## `Chainable`
-
+
-
+🌊 Types: Chainable.d
-
+🔬 Tests: Chainable
-
+Chainable.Chainable
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L15 "View in source") [Ⓣ][1]
-## `CM`
+(Chainable): Trait class that can inherit any class passed into compose, extended by ChainedMap & ChainedSet
-
-* 🌊 Types: ChainedMap.d
-* 🌊 Types: ChainedMapBase.d
+#### @see
-🔬 Tests: ChainedMap
+* chain-pattern
+* ChainedMap
+* ChainedSet
-# CM([SuperClass=ChainedMapBase])
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L5479 "View in source") [Ⓣ][1]
+#### @classProps
-(Function): ChainedMap composer
+* {parent}
+* {className}
+
+---
+
-### @see
+
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
+Chainable.clear([clearPropertiesThatAreChainLike=true])
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L22 "View in source") [Ⓣ][1]
-### @extends
-ChainedMapBase
+(Function): clears the map, goes through this properties, calls .clear if they are instanceof Chainable or Map
-#### Since
-0.0.1
+#### @see
+* https://github.com/fliphub/flipchain/issues/2
+* ChainedSet
+* ChainedMap
+* map-clear
#### Arguments
-1. `[SuperClass=ChainedMapBase]` *(Class|Composable|Object)*: class to extend
+1. `[clearPropertiesThatAreChainLike=true]` *(|boolean)*: checks properties on the object, if they are `chain-like`, clears them as well
#### Returns
-*(Class)*: ChainedMap
+*(Chainable)*: @chainable
#### Example
```js
-const heh = class {}
-const composed = ChainedMap.compose(heh)
-const hehchain = new Composed()
-hehchain instanceof heh
-//=> true
+const chain = new Chain()
+chain.set('eh', 1)
+chain.entries()
+//=> {eh: 1}
+chain.clear()
+chain.entries()
+//=> {}
```
---
-
-
-## `Chainable.prototype`
-
-
+Chainable.delete(key=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L1237 "View in source") [Ⓣ][1]
-🌊 Types: Chainable.d
+(Function): calls .delete on this.store.map
-🔬 Tests: Chainable
-# Chainable.prototype.Chainable
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L16 "View in source") [Ⓣ][1]
+#### @see
-(Chainable): Trait class that can inherit any class passed into compose, extended by ChainedMap & ChainedSet
+* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/has
+* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/has
+* ChainedSet
+* ChainedMap
+#### @Since
+0.3.0
-### @see
+#### Arguments
+1. `key=undefined` *(Primitive)*: on a Map: key referencing the value. on a Set: the index
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
+#### Returns
+*(Chainable)*:
-### @classProps
+#### Example
+```js
+const chain = new Chain()
+chain.set('eh', 1)
+chain.get('eh')
+// => 1
+chain.delete('eh', 1)
+chain.get('eh')
+// => undefined
-* {parent}
-* {className}
-
+```
---
-
-
-## `ChainedMapBase.prototype`
-
-
-
-🌊 Types: ChainedMapBase.d
+Chainable.end()
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L1119 "View in source") [Ⓣ][1]
-🔬 Tests: ChainedMap
+(Function): for ending nested chains
-# ChainedMapBase.prototype.CMC
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L23 "View in source") [Ⓣ][1]
-(Chainable): this is to avoid circular requires
-because MergeChain & MethodChain extend this
-yet .method & .merge use those chains
+#### @see
+* Chainable.parent
+* FactoryChain
-### @see
+#### @Since
+0.4.0
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
+#### Returns
+*(*)*:
-### @classProps
+#### Example
+```js
+const parent = 'eh'
+const child = newChain(parent)
+child.end()
+//=> 'eh'
-* {meta} meta fn
-* {store} main store
-
+```
+---
-### @extends
-Chainable
+
+
-#### Since
-4.0.0-alpha.1
+Chainable.has(keyOrValue=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L15 "View in source") [Ⓣ][1]
----
+(Function): checks whether the store has a value for a given key
-
-
+#### @see
-# ChainedMapBase.prototype.cmc([SuperClass=Chainable])
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L1972 "View in source") [Ⓣ][1]
+* map-has
-(Composer): ChainedMapBase composer
+#### @Since
+0.3.0
#### Arguments
-1. `[SuperClass=Chainable]` *(Class|Composable|Object)*: class to extend
+1. `keyOrValue=undefined` *(any)*: key when Map, value when Set
#### Returns
-*(Class)*: ChainedMapBase
+*(boolean)*:
#### Example
```js
-const heh = class {}
-const composed = ChainedMapBase.compose(heh)
-const hehchain = new Composed()
-hehchain instanceof heh
+const chain = new Chain()
+chain.set('eh', 1).has('eh')
//=> true
+chain.has('canada')
+//=> false
```
---
@@ -945,32 +874,27 @@ hehchain instanceof heh
-# ChainedMapBase.prototype.entries([chains=false])
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L27 "View in source") [Ⓣ][1]
+Chainable.length()
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L1370 "View in source") [Ⓣ][1]
-(Function): spreads the entries from ChainedMapBase.store *(Map)* return store.entries, plus all chain properties if they exist
+Function
-### @see
+#### @see
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-#### Since
-0.4.0
+* ChainedMap.store
-#### Arguments
-1. `[chains=false]` *(boolean)*: if true, returns all properties that are chains
+#### @Since
+0.5.0
#### Returns
-*(Object)*: reduced object containing all properties from the store, and when `chains` is true, all instance properties, and recursive chains
-
-
-//
+*(number)*:
#### Example
```js
-map.set('a', 'alpha').set('b', 'beta').entries()
-//=> {a: 'alpha', b: 'beta'}
-
+for (var i = 0; i < chain.length; i++)
```
---
@@ -978,63 +902,63 @@ map.set('a', 'alpha').set('b', 'beta').entries()
-# ChainedMapBase.prototype.extend(methods=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L1847 "View in source") [Ⓣ][1]
+🔬 Tests: iteration
-(Function): shorthand methods, from strings to functions that call .set
+Chainable.prototype[iterator]()
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L1074 "View in source") [Ⓣ][1]
-#### Since
-0.4.0
-
-#### Arguments
-1. `methods=undefined` *(string[])*: decorates/extends an object with new shorthand functions to get/set
-
-#### Returns
-*(ChainedMapBase)*: @chainable
-
-#### Example
-```js
-const chain1 = new Chain()
-chain1.extend(['eh'])
+(generator): Iterator for looping values in the store
-const chain2 = new Chain()
-chain2.eh = val => this.set('eh', val)
-eq(chain2.eh, chain1.eh)
-//=> true
+#### @see
-```
----
+* https://github.com/sindresorhus/quick-lru/blob/master/index.js
+* https://stackoverflow.com/questions/36976832/what-is-the-meaning-of-symbol-iterator-in-this-context
+* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/iterator
+* this.store
-
+#### @notes
-
+* assigned to a variable so buble ignores it
+
-# ChainedMapBase.prototype.from(obj=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L1803 "View in source") [Ⓣ][1]
+#### @Since
+0.5.0
-(Function): checks each property of the object calls the chains accordingly
+#### Returns
+*(Object)*: {value: undefined | any, done: true | false}
+#### Example
+```js
+const chain = new Chain().set('eh', 1)
+for (var [key, val] of chain) console.log({ [key]: val })
+//=> {eh: 1}
-### @todos
+```
+#### Example
+```js
+*[Symbol.iterator](): void { for (const item of this.store) yield item }
+```
+#### Example
+```js
+const { ChainedSet } = require('chain-able')
+const set = new ChainedSet()
+set.add('eh')
-- [ ] could also add parsing stringified
-
-#### Since
-0.5.0
+for (const arr of set) {
+ const [key, val] = arr
-#### Arguments
-1. `obj=undefined` *(Object)*: object with functions to hydrate from
+ key
+ //=> 0
-#### Returns
-*(Chainable)*: @chainable
+ val
+ //=> 'eh'
-#### Example
-```js
-const from = new Chain().from({ eh: true })
-const eh = new Chain().set('eh', true)
-eq(from, eh)
-// => true
+ arr.length
+ //=> 2
+}
```
---
@@ -1043,33 +967,42 @@ eq(from, eh)
-# ChainedMapBase.prototype.get(key=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L27 "View in source") [Ⓣ][1]
+Chainable.prototype[primitive](hint=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L19 "View in source") [Ⓣ][1]
+
+(Function): symbol method for toString, toJSON, toNumber
-(Function): get value for key path in the Map store ❗ `debug` is a special key and is *not* included into .store it goes onto .meta
+#### @see
-### @see
+* well-known-symbols-es6
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-#### Since
-0.4.0
+#### @Since
+1.0.2
#### Arguments
-1. `key=undefined` *(Primitive)*: Primitive data key used as map property to reference the value
+1. `hint=undefined` *(string)*: enum[default, string, number]
#### Returns
-*(any)*: value in .store at key
+*(Primitive)*:
#### Example
```js
const chain = new Chain()
-chain.set('eh', true)
-chain.get('eh')
-//=> true
+chain.toNumber = () => 1 + chain
+//=> 1
+chain + 1
+//=>
-chain.get('nope')
-//=> undefined
+```
+#### Example
+```js
+const chain = new Chain()
+chain.toString = () => 'eh'
+chain + ''
+//=> 'eh'
```
---
@@ -1078,31 +1011,40 @@ chain.get('nope')
-# ChainedMapBase.prototype.set(key=undefined, value=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L25 "View in source") [Ⓣ][1]
+Chainable.values()
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L21 "View in source") [Ⓣ][1]
-(Function): sets the value using the key on store adds or updates an element with a specified key and value
+(Function): spreads the entries from ChainedMap.store.values allocates a new array, adds the values from the iterator
-### @see
+#### @see
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-#### Since
-0.4.0
+* mozilla-map-values
+* mozilla-set-values
+* compat-array-static-methods
+* set-to-array
-#### Arguments
-1. `key=undefined` *(Primitive)*: Primitive to reference the value
-2. `value=undefined` *(any)*: any data to store
+#### @notes
+
+* look at Chainable.constructor to ensure not to use `new Array...`
+* moved from ChainedMap and ChainedSet to Chainable @2.0.2
+* this was [...] & Array.from(this.store.values())
+
+
+#### @Since
+0.4.0
#### Returns
-*(ChainedMapBase)*: @chainable
+*(*): toArr(this.store.values())*
#### Example
```js
const chain = new Chain()
-chain.set('eh', true)
-chain.get('eh')
-//=> true
+chain.set('eh', 1)
+chain.values()
+//=> [1]
```
---
@@ -1111,48 +1053,25 @@ chain.get('eh')
-# ChainedMapBase.prototype.tap(name=undefined, fn=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L44 "View in source") [Ⓣ][1]
-
-(Function): tap a value with a function
-
-
-### @see
+Chainable.when(condition=undefined, [trueBrancher=Function], [falseBrancher=Function])
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L1145 "View in source") [Ⓣ][1]
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-#### Since
-4.0.0-alpha.1 <- moved from transform & shorthands
+(Function): when the condition is true, trueBrancher is called, else, falseBrancher is called
#### Arguments
-1. `name=undefined` *(any|string)*: key to `.get`
-2. `fn=undefined` *(Function)*: function to tap with
+1. `condition=undefined` *(boolean|string)*: when string, checks this.get
+2. `[trueBrancher=Function]` *(Function)*: called when true
+3. `[falseBrancher=Function]` *(Function)*: called when false
#### Returns
-*(Chain)*: @chainable
-
-#### Example
-```js
-chain
- .set('moose', { eh: true })
- .tap('moose', moose => {
- moose.eh = false
- return moose
- })
- .get('moose')
-
-// => {eh: false}
+*(Chainable)*: @chainable
-```
#### Example
```js
-const entries = new Chain()
- .set('str', 'emptyish')
- .tap('str', str => str + '+')
- .set('arr', [1])
- .tap('arr', arr => arr.concat([2]))
- .entries()
-
-//=> {str: 'emptyish+', arr: [1, 2]}
+const prod = process.env.NODE_ENV === 'production'
+chains.when(prod, c => c.set('prod', true), c => c.set('prod', false))
```
---
@@ -1163,213 +1082,193 @@ const entries = new Chain()
-## `ChainedSet`
+## `ChainedMapBase`
-🌊 Types: ChainedSet.d
-
-🔬 Tests: ChainedSet
+* 🌊 Types: ChainedMap.d
+* 🌊 Types: ChainedMapBase.d
-# ChainedSet
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L5593 "View in source") [Ⓣ][1]
+🔬 Tests: ChainedMap
-Set
+ChainedMapBase.ComposeChainedMap([SuperClass=ChainedMapBase])
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L8393 "View in source") [Ⓣ][1]
+(Function): ChainedMap composer
-### @see
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
+#### @see
-### @notes
+* ChainedMapBase
-* had Symbol.isConcatSpreadable but it was not useful
-
+#### @extends
+ChainedMapBase
-### @todos
-- [ ] could add .first .last ?
-
-### @classProps
+#### @Since
+0.0.1
-* {store}
-
+#### Arguments
+1. `[SuperClass=ChainedMapBase]` *(Class|Composable|Object)*: class to extend
-### @extends
-Chainable
+#### Returns
+*(Class)*: ChainedMap
+#### Example
+```js
+const heh = class {}
+const composed = ChainedMap.compose(heh)
+const hehchain = new Composed()
+hehchain instanceof heh
+//=> true
+```
---
-
-
-## `DotProp.prototype`
+🌊 Types: ChainedMapBase.d
-
+🔬 Tests: ChainedMap
-# DotProp.prototype.get(key=undefined, [fallback=undefined])
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L7478 "View in source") [Ⓣ][1]
+ChainedMapBase.ComposeChainedMapBase
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L21 "View in source") [Ⓣ][1]
-(Function): dot-prop enabled get
+(Chainable): this is to avoid circular requires
+because MergeChain & MethodChain extend this
+yet .method & .merge use those chains
+...also, it serves as a non-references creator for extending new instances of Chainable, where it splits into *(Map | Set)* -> composed prototype decorators
-### @see
+#### @see
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
+* pony-map
+* mozilla-map
+* emca-map
+* ChainedMap
+* Chainable
+* MergeChain
+* MethodChain
+* ChainedMap
-### @todos
+#### @classProps
-- [ ] dot-prop on non-store instance.property when using nested chains...
+* {meta} meta fn
+* {store} main store
-#### Since
-3.0.1
-
-#### Arguments
-1. `key=undefined` *(Primitive)*: dot prop key, or any primitive key
-2. `[fallback=undefined]` *(any)*: fallback value, if it cannot find value with key path
-
-#### Returns
-*(any)*: value for path, or fallback value if provided
-#### Example
-```js
-chain.set('moose.simple', 1)
-//=> Chain
+#### @extends
+Chainable
-chain.get('moose.simple')
-//=>1
-chain.get('moose')
-//=> {simple: 1}
-```
-#### Example
-```js
-//also works with an array (moose.simple)
-chain.get(['moose', 'simple'])
-//=> 1
+#### @Since
+4.0.0-alpha.1
-```
---
-# DotProp.prototype.set
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L7420 "View in source") [Ⓣ][1]
-
-unknown
+ChainedMapBase.cmc([Target=Chainable])
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2940 "View in source") [Ⓣ][1]
+(Composer): ChainedMapBase composer
-### @see
+#### Arguments
+1. `[Target=Chainable]` *(Class|Composable|Object)*: class to extend
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-#### Since
-3.0.1
+#### Returns
+*(Class)*: ChainedMapBase
#### Example
```js
-const chain = new Target()
-
-chain.set('moose.simple', 1)
-//=> Target store:Map: { moose: { simple: 1 } }
+const heh = class {}
+const composed = ChainedMapBase.compose(heh)
+const hehchain = new Composed()
+hehchain instanceof heh
+//=> true
```
---
-
-
-## `FactoryChain.prototype`
-
-
+ChainedMapBase.entries([chains=false])
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L21 "View in source") [Ⓣ][1]
-🌊 Types: FactoryChain.d
+(Function): spreads the entries from ChainedMapBase.store *(Map)* return store.entries, plus all chain properties if they exist
-🔬 Tests: FactoryChain
-# FactoryChain.prototype.FactoryChain
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L7 "View in source") [Ⓣ][1]
+#### @see
-Map
+* mozilla-map-entries
+#### @Since
+0.4.0
-### @classProps
+#### Arguments
+1. `[chains=false]` *(boolean)*: if true, returns all properties that are chains
-* {data}
-* {_calls}
-
-
-### @extends
-ChainedMapBase
+#### Returns
+*(Object)*: reduced object containing all properties from the store, and when `chains` is true, all instance properties, and recursive chains
+
+
+//
+#### Example
+```js
+map.set('a', 'alpha').set('b', 'beta').entries()
+//=> {a: 'alpha', b: 'beta'}
+```
---
-# FactoryChain.prototype.chainUpDowns(methods=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L5758 "View in source") [Ⓣ][1]
-
-(Function): chain back up to parent for any of these
+ChainedMapBase.extend(methods=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2815 "View in source") [Ⓣ][1]
+(Function): shorthand methods, from strings to functions that call .set
-### @todos
-- [ ] should have a debug log for this
-
-#### Since
-2.0.0
+#### @Since
+0.4.0
#### Arguments
-1. `methods=undefined` *(string[])*: methods to trigger `onChainUpDown` on
+1. `methods=undefined` *(string[])*: decorates/extends an object with new shorthand functions to get/set
#### Returns
-*(FactoryChain)*: @chainable
+*(ChainedMapBase)*: @chainable
#### Example
```js
-const { Chain, FactoryChain, ChainedSet } = require('chain-able')
-
-class Things extends Chain {
- constructor(parent) {
- super(parent)
- this.people = new ChainedSet(this)
- }
- person() {
- const person = new FactoryChain(this)
- person
- .props(['name', 'age', 'email'])
- .onChainUpDown(this.person)
- .chainUpDowns(['person'])
- .onDone(personChain => {
- this.people.add(personChain)
- return this
- })
+const chain1 = new Chain()
+chain1.extend(['eh'])
- return person
- }
-}
+const chain2 = new Chain()
+chain2.eh = val => this.set('eh', val)
-const things = new Things()
-const returned = things
- .person()
- .name('sue')
- .person()
- .age(100)
- .name('john')
- .email('@')
+eq(chain2.eh, chain1.eh)
+//=> true
```
---
@@ -1378,53 +1277,72 @@ const returned = things
-# FactoryChain.prototype.factory([obj={}])
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L5908 "View in source") [Ⓣ][1]
+ChainedMapBase.from(obj=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2771 "View in source") [Ⓣ][1]
-(Function): creates/add the `.end` method, which checks how many methods have been called, and decides whether to return parent or not
+(Function): checks each property of the object calls the chains accordingly
-#### Since
-2.0.0
+
+#### @todos
+
+- [ ] could also add parsing stringified
+
+
+#### @Since
+0.5.0
#### Arguments
-1. `[obj={}]` *(Object)*: optional object to use for creating .end
+1. `obj=undefined` *(Object)*: object with functions to hydrate from
#### Returns
-*(FactoryChain)*: @chainable
+*(Chainable)*: @chainable
+
+#### Example
+```js
+const from = new Chain().from({ eh: true })
+const eh = new Chain().set('eh', true)
+eq(from, eh)
+// => true
+```
---
-# FactoryChain.prototype.getData([prop=undefined])
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L5889 "View in source") [Ⓣ][1]
+ChainedMapBase.get(key=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L20 "View in source") [Ⓣ][1]
-(Function): access data being built when stepping through a factory
+(Function): get value for key path in the Map store ❗ `debug` is a special key and is *not* included into .store it goes onto .meta
-#### Since
-2.0.0
+
+#### @see
+
+* mozilla-map-get
+
+#### @Since
+0.4.0
#### Arguments
-1. `[prop=undefined]` *(Primitive)*: key of the data, or returns all data
+1. `key=undefined` *(Primitive)*: Primitive data key used as map property to reference the value
#### Returns
-*(any)*: this.data
+*(any)*: value in .store at key
#### Example
```js
-.data['prop'] = 'eh'
- .getData('prop')
- //=> 'eh'
- .getData()
- //=> {prop: 'eh'}
-```
-#### Example
-```js
-const person = new FactoryChain(this)
-const age = person.props(['name', 'age']).age(10).getData('age')
-expect(age).toBe(10)
+const chain = new Chain()
+chain.set('eh', true)
+chain.get('eh')
+//=> true
+
+chain.get('nope')
+//=> undefined
```
---
@@ -1433,29 +1351,35 @@ expect(age).toBe(10)
-# FactoryChain.prototype.prop(name=undefined, [onCall=undefined])
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L5829 "View in source") [Ⓣ][1]
+ChainedMapBase.set(key=undefined, value=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L19 "View in source") [Ⓣ][1]
-(Function): add property that are counted towards the call count for easy auto-ending chaining
+(Function): sets the value using the key on store adds or updates an element with a specified key and value
-#### Since
-2.0.0
+
+#### @see
+
+* mozilla-map-set
+* ChainedMapBase.store
+
+#### @Since
+0.4.0
#### Arguments
-1. `name=undefined` *(Primitive)*: property name
-2. `[onCall=undefined]` *(||Function)*: callback for the property
+1. `key=undefined` *(Primitive)*: Primitive to reference the value
+2. `value=undefined` *(any)*: any data to store
#### Returns
-*(FactoryChain)*: @chainable
+*(ChainedMapBase)*: @chainable
#### Example
```js
-person
- //.prop also accepts an optional callback,
- //for nestable nestable chains
- .prop('name')
- .prop('age')
- .prop('email')
+const chain = new Chain()
+chain.set('eh', true)
+chain.get('eh')
+//=> true
```
---
@@ -1464,41 +1388,53 @@ person
-# FactoryChain.prototype.props(names=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L5801 "View in source") [Ⓣ][1]
+ChainedMapBase.tap(name=undefined, fn=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L23 "View in source") [Ⓣ][1]
-(Function): adds an *array* of properties, using FactoryChain.prop
+(Function): tap a value with a function
-### @see
+#### @see
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-#### Since
-2.0.0
+* tapable
+* ChainedMapBase.set
+* ChainedMapBase.get
+
+#### @Since
+4.0.0-alpha.1 <- moved from transform & shorthands
#### Arguments
-1. `names=undefined` *(string[])*: property names
+1. `name=undefined` *(any|string)*: key to `.get`
+2. `fn=undefined` *(Function)*: function to tap with
#### Returns
-*(FactoryChain)*: @chainable
+*(Chain)*: @chainable
#### Example
```js
-person.props(['name', 'age', 'email'])
-
-typeof person.name
-//=> 'function'
+chain
+ .set('moose', { eh: true })
+ .tap('moose', moose => {
+ moose.eh = false
+ return moose
+ })
+ .get('moose')
-person.name().age()
-//=> FactoryChain
+// => {eh: false}
-person.name().age().email()
-//=> ParentChain
+```
+#### Example
+```js
+const entries = new Chain()
+ .set('str', 'emptyish')
+ .tap('str', str => str + '+')
+ .set('arr', [1])
+ .tap('arr', arr => arr.concat([2]))
+ .entries()
-// person.name().age().person()
-//=> FactoryChain
-//^ because .person is `chainUpDowns`
-//^ so it finishes the old chain, and begins a new one
+//=> {str: 'emptyish+', arr: [1, 2]}
```
---
@@ -1509,35 +1445,46 @@ person.name().age().email()
-## `MergeChain.prototype`
+## `ChainedSet`
-🔬 Tests: MergeChain
+🌊 Types: ChainedSet.d
-# MergeChain.prototype.MergeChain
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L12 "View in source") [Ⓣ][1]
+🔬 Tests: ChainedSet
-Map
+ChainedSet.ChainedSet
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L8516 "View in source") [Ⓣ][1]
+Set
-### @see
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
+#### @see
-### @todos
+* http://2ality.com/2015/09/well-known-symbols-es6.html
+* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/isConcatSpreadable
+* Chainable
-- [ ] consider just making this a function,
- because 80/20 onValue merger & onExisting
- are rarely used & are easily overridable with .merge
+#### @notes
+
+* had Symbol.isConcatSpreadable but it was not useful
-### @extends
-ChainedMapBase
+#### @todos
+
+- [ ] could add .first .last ?
+
+#### @classProps
+
+* {store}
+
+
+#### @extends
+Chainable
-#### Since
-1.0.0
---
@@ -1545,37 +1492,36 @@ ChainedMapBase
-# MergeChain.prototype.init(opts=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L5199 "View in source") [Ⓣ][1]
+ChainedSet.add(value=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L19 "View in source") [Ⓣ][1]
-(Function): options for merging with dopemerge
+(Function): appends a new element with a specified value to the end of the .store
-### @see
+#### @see
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-#### Since
-1.0.2
+* mozilla-set-add
+* lodash-add-set-entry
+
+#### @Since
+0.4.0
#### Arguments
-1. `opts=undefined` *(Function|Object)*: when object: options for the merger. when function: is the merger
+1. `value=undefined` *(any)*: any value to add to **end** of the store
#### Returns
-*(MergeChain)*: @chainable
+*(ChainedSet)*: @chainable
#### Example
```js
-{
- stringToArray: true,
- boolToArray: false,
- boolAsRight: true,
- ignoreTypes: ['null', 'undefined', 'NaN'],
- debug: false,
- }
-```
-#### Example
-```js
-.merger(require('lodash.mergewith')())
+const people = new ChainedSet()
+people.add('sam').add('sue')
+
+for (let name of people) console.log(name)
+//=> sam, sue
+
```
---
@@ -1583,96 +1529,1444 @@ ChainedMapBase
-# MergeChain.prototype.MergeChain_1
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L5447 "View in source") [Ⓣ][1]
+ChainedSet.merge(arr=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L8600 "View in source") [Ⓣ][1]
-unknown
+(Function): merge any Array/Set/Iteratable/Concatables into the array, at the end
-#### Since
-0.9.0
+
+#### @Since
+0.4.0
+
+#### Arguments
+1. `arr=undefined` *(Array|Concatable|Set)*: values to merge in and append
+
+#### Returns
+*(ChainedSet)*: @chainable
#### Example
```js
-const { Chain, MergeChain } = require('chain-able')
+const people = new ChainedSet()
+people.add('sam').add('sue').prepend('first').merge(['merged'])
-const chain = new Chain().set('str', 'stringy')
+for (let name of people) console.log(name)
+//=> first, sam, sue, merged
-MergeChain.init(chain).onExisting((a, b) => a + b).merge({ str: '+' })
+```
+---
+
+
+
+
+
+ChainedSet.prepend(value=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L8574 "View in source") [Ⓣ][1]
+
+(Function): inserts the value at the **beginning** of the Set
+
+
+#### @Since
+0.4.0
+
+#### Arguments
+1. `value=undefined` *(any)*: any value to add to **beginning** the store
+
+#### Returns
+*(ChainedSet)*: @chainable
+
+#### Example
+```js
+const people = new ChainedSet()
+people.add('sue').prepend('first')
+
+for (let name of people) console.log(name)
+//=> first, sue
+
+```
+---
+
+
+
+
+
+
+
+## `DotProp`
+
+
+
+DotProp.get(key=undefined, [fallback=undefined])
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L10478 "View in source") [Ⓣ][1]
+
+(Function): dot-prop enabled get
+
+
+#### @see
+
+* ChainedMap.get
+* deps/dot
+* deps/is/dot
+
+#### @todos
+
+- [ ] dot-prop on non-store instance.property when using nested chains...
+
+
+#### @Since
+3.0.1
+
+#### Arguments
+1. `key=undefined` *(Primitive)*: dot prop key, or any primitive key
+2. `[fallback=undefined]` *(any)*: fallback value, if it cannot find value with key path
+
+#### Returns
+*(any)*: value for path, or fallback value if provided
+
+#### Example
+```js
+chain.set('moose.simple', 1)
+//=> Chain
+
+chain.get('moose.simple')
+//=>1
+
+chain.get('moose')
+//=> {simple: 1}
+
+```
+#### Example
+```js
+//also works with an array (moose.simple)
+chain.get(['moose', 'simple'])
+//=> 1
+
+```
+---
+
+
+
+
+
+DotProp.set
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L10420 "View in source") [Ⓣ][1]
+
+unknown
+
+
+#### @see
+
+* TargetedMap.set
+* .dot
+
+#### @Since
+3.0.1
+
+#### Example
+```js
+const chain = new Target()
+
+chain.set('moose.simple', 1)
+//=> Target store:Map: { moose: { simple: 1 } }
+
+```
+---
+
+
+
+
+
+
+
+## `FactoryChain`
+
+
+
+🌊 Types: FactoryChain.d
+
+🔬 Tests: FactoryChain
+
+FactoryChain.FactoryChain
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L7 "View in source") [Ⓣ][1]
+
+Map
+
+
+#### @classProps
+
+* {data}
+* {_calls}
+
+
+#### @extends
+ChainedMapBase
+
+
+---
+
+
+
+
+
+FactoryChain.chainUpDowns(methods=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L8701 "View in source") [Ⓣ][1]
+
+(Function): chain back up to parent for any of these
+
+
+#### @todos
+
+- [ ] should have a debug log for this
+
+
+#### @Since
+2.0.0
+
+#### Arguments
+1. `methods=undefined` *(string[])*: methods to trigger `onChainUpDown` on
+
+#### Returns
+*(FactoryChain)*: @chainable
+
+#### Example
+```js
+const { Chain, FactoryChain, ChainedSet } = require('chain-able')
+
+class Things extends Chain {
+ constructor(parent) {
+ super(parent)
+ this.people = new ChainedSet(this)
+ }
+ person() {
+ const person = new FactoryChain(this)
+ person
+ .props(['name', 'age', 'email'])
+ .onChainUpDown(this.person)
+ .chainUpDowns(['person'])
+ .onDone(personChain => {
+ this.people.add(personChain)
+ return this
+ })
+
+ return person
+ }
+}
+
+const things = new Things()
+const returned = things
+ .person()
+ .name('sue')
+ .person()
+ .age(100)
+ .name('john')
+ .email('@')
+
+```
+---
+
+
+
+
+
+FactoryChain.factory([obj={}])
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L8851 "View in source") [Ⓣ][1]
+
+(Function): creates/add the `.end` method, which checks how many methods have been called, and decides whether to return parent or not
+
+
+#### @Since
+2.0.0
+
+#### Arguments
+1. `[obj={}]` *(Object)*: optional object to use for creating .end
+
+#### Returns
+*(FactoryChain)*: @chainable
+
+---
+
+
+
+
+
+FactoryChain.getData([prop=undefined])
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L8832 "View in source") [Ⓣ][1]
+
+(Function): access data being built when stepping through a factory
+
+
+#### @Since
+2.0.0
+
+#### Arguments
+1. `[prop=undefined]` *(Primitive)*: key of the data, or returns all data
+
+#### Returns
+*(any)*: this.data
+
+#### Example
+```js
+.data['prop'] = 'eh'
+ .getData('prop')
+ //=> 'eh'
+ .getData()
+ //=> {prop: 'eh'}
+```
+#### Example
+```js
+const person = new FactoryChain(this)
+const age = person.props(['name', 'age']).age(10).getData('age')
+expect(age).toBe(10)
+
+```
+---
+
+
+
+
+
+FactoryChain.prop(name=undefined, [onCall=undefined])
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L8772 "View in source") [Ⓣ][1]
+
+(Function): add property that are counted towards the call count for easy auto-ending chaining
+
+
+#### @Since
+2.0.0
+
+#### Arguments
+1. `name=undefined` *(Primitive)*: property name
+2. `[onCall=undefined]` *(||Function)*: callback for the property
+
+#### Returns
+*(FactoryChain)*: @chainable
+
+#### Example
+```js
+person
+ //.prop also accepts an optional callback,
+ //for nestable nestable chains
+ .prop('name')
+ .prop('age')
+ .prop('email')
+
+```
+---
+
+
+
+
+
+FactoryChain.props(names=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L8744 "View in source") [Ⓣ][1]
+
+(Function): adds an *array* of properties, using FactoryChain.prop
+
+
+#### @see
+
+* FactoryChain.prop
+
+#### @Since
+2.0.0
+
+#### Arguments
+1. `names=undefined` *(string[])*: property names
+
+#### Returns
+*(FactoryChain)*: @chainable
+
+#### Example
+```js
+person.props(['name', 'age', 'email'])
+
+typeof person.name
+//=> 'function'
+
+person.name().age()
+//=> FactoryChain
+
+person.name().age().email()
+//=> ParentChain
+
+// person.name().age().person()
+//=> FactoryChain
+//^ because .person is `chainUpDowns`
+//^ so it finishes the old chain, and begins a new one
+
+```
+---
+
+
+
+
+
+
+
+## `MergeChain`
+
+
+
+🔬 Tests: MergeChain
+
+MergeChain.MergeChain
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L12 "View in source") [Ⓣ][1]
+
+Map
+
+
+#### @see
+
+* deps/dopemerge
+
+#### @todos
+
+- [ ] consider just making this a function,
+ because 80/20 onValue merger & onExisting
+ are rarely used & are easily overridable with .merge
+
+
+#### @extends
+ChainedMapBase
+
+
+
+#### @Since
+1.0.0
+
+---
+
+
+
+
+
+MergeChain.init(opts=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L8102 "View in source") [Ⓣ][1]
+
+(Function): options for merging with dopemerge
+
+
+#### @see
+
+* dopemerge
+
+#### @Since
+1.0.2
+
+#### Arguments
+1. `opts=undefined` *(Function|Object)*: when object: options for the merger. when function: is the merger
+
+#### Returns
+*(MergeChain)*: @chainable
+
+#### Example
+```js
+{
+ stringToArray: true,
+ boolToArray: false,
+ boolAsRight: true,
+ ignoreTypes: ['null', 'undefined', 'NaN'],
+ debug: false,
+ }
+```
+#### Example
+```js
+.merger(require('lodash.mergewith')())
+```
+---
+
+
+
+
+
+MergeChain.MergeChain_1
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L8351 "View in source") [Ⓣ][1]
+
+unknown
+
+
+#### @Since
+0.9.0
+
+#### Example
+```js
+const { Chain, MergeChain } = require('chain-able')
+
+const chain = new Chain().set('str', 'stringy')
+
+MergeChain.init(chain).onExisting((a, b) => a + b).merge({ str: '+' })
+
+chain.get('str')
+//=> 'stringy+'
+
+```
+---
+
+
+
+
+
+
+
+## `MethodChain`
+
+
+
+🌊 Types: MethodChain.d
+
+🔬 Tests: MethodChain
+
+MethodChain.MethodChain
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L7304 "View in source") [Ⓣ][1]
+
+(Map): ❗ using `+` will call `.build()` in a shorthand fashion
+
+
+#### @todos
+
+- [ ] maybe abstract the most re-usable core as a protected class
+ so the shorthands could be used, and more functionality made external
+- [ ] need to separate schema from here as external functionality & add .add
+- [ ] .prop - for things on the instance, not in the store?
+ !!! .sponge - absorn properties into the store
+
+
+#### @extends
+ChainedMap
+
+
+
+#### @Since
+4.0.0
+
+---
+
+
+
+
+
+MethodChain._build(name=undefined, parent=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L7642 "View in source") [Ⓣ][1]
+
+Function
+
+
+#### @notes
+
+* scoping here adding default functions have to rescope arguments
+
+
+#### @todos
+
+- [ ] allow config of method var in plugins since it is scoped...
+- [ ] add to .meta(shorthands)
+- [ ] reduce complexity if perf allows
+
+
+#### @Since
+4.0.0-alpha.1
+
+#### Arguments
+1. `name=undefined` *(Primitive)*:
+2. `parent=undefined` *(Object)*:
+
+#### Returns
+*(void)*:
+
+---
+
+
+
+
+
+MethodChain._defaults(name=undefined, parent=undefined, built=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L7602 "View in source") [Ⓣ][1]
+
+Function
+
+
+#### @todos
+
+- [ ] optimize the size of this
+ with some bitwise operators
+ hashing the things that have been defaulted
+ also could be plugin
+
+
+#### @Since
+4.0.0
+
+#### Arguments
+1. `name=undefined` *(Primitive)*: method name
+2. `parent=undefined` *(Object)*: being decorated
+3. `built=undefined` *(Object)*: method being built
+
+#### Returns
+*(void)*:
+
+#### Example
+```js
+._defaults('', {}, {})
+```
+#### Example
+```js
+let methodFactories
+
+ ### `onSet`
+
+ > defaults to `this.set(key, value)`
+
+ ```ts
+ public onSet(fn: Fn): MethodChain
+ ```
+
+ ### `onCall`
+
+ > defaults to .onSet ^
+
+ ```ts
+ public onCall(fn: Fn): MethodChain
+ ```
+
+ ### `onGet`
+
+ > defaults to `this.get(key)`
+
+ ```ts
+ public onGet(fn: Fn): MethodChain
+ ```
+```
+---
+
+
+
+
+
+MethodChain.autoGetSet(name=undefined, parent=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L7039 "View in source") [Ⓣ][1]
+
+Function
+
+
+#### @see
+
+* MethodChain
+#### Arguments
+1. `name=undefined` *(Primitive)*: method name being built
+2. `parent=undefined` *(Object)*: parent containing the method
+
+#### Returns
+*(MethodChain)*: @chainable
+
+#### Example
+```js
+const chain = new Chain()
+chain.methods('eh').plugin(autoGetSet).build()
+
+chain.eh(1)
+//=> Chain
+chain.eh()
+//=> 1
+
+```
+---
+
+
+
+
+
+MethodChain.autoIncrement()
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L7948 "View in source") [Ⓣ][1]
+
+(Function): adds a plugin to increment the value on every call
+
+
+#### @see
+
+* plugins/autoIncrement
+
+#### @Since
+0.4.0
+
+#### Returns
+*(MethodChain)*: @chainable
+
+#### Example
+```js
+chain.methods(['index']).autoIncrement().build().index().index(+1).index()
+chain.get('index')
+//=> 3
+
+```
+---
+
+
+
+
+
+MethodChain.build([returnValue=undefined])
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L7528 "View in source") [Ⓣ][1]
+
+(Function): set the actual method, also need .context - use .parent
+
+
+#### @see
+
+* https://github.com/iluwatar/java-design-patterns/tree/master/step-builder
+
+#### @todos
+
+- [ ] if passing in a name that already exists, operations are decorations... (partially done)
+
+
+#### @Since
+4.0.0
+
+#### Arguments
+1. `[returnValue=undefined]` *(any)*: returned at the end of the function for ease of use
+
+#### Returns
+*(MethodChain)*: @chainable
+
+#### Example
+```js
+var obj = {}
+const one = new MethodChain(obj).methods('eh').getSet().build(1)
+//=> 1
+
+typeof obj.getEh
+//=> 'function'
+
+```
+---
+
+
+
+
+
+MethodChain.decorate(parentToDecorate=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L6980 "View in source") [Ⓣ][1]
+
+(Function): decorates a parent when the argument is provided
+BUT THE FUNCTIONS WILL STILL BE SCOPED TO CURRENT PARENT
+for easy factory chaining
+
+
+#### @see
+
+* MethodChain
+
+#### @todos
+
+- [ ] this is more like a preset since it *adds* plugins?
+ more of methodFactory now
+
+
+#### @Since
+4.0.0-alpha.1
+
+#### Arguments
+1. `parentToDecorate=undefined` *(Object)*: object to put the method on instead
+
+#### Returns
+*(MethodChain)*: @chainable
+
+#### Example
+```js
+const chain = new Chain()
+const obj = {}
+chain.method('ehOh').decorate(obj).build()
+typeof obj.ehOh
+//=> 'function'
+
+```
+---
+
+
+
+
+
+MethodChain.decorate([parentToDecorate=undefined])
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L7917 "View in source") [Ⓣ][1]
+
+(Function): add methods to the parent for easier chaining
+
+
+#### @see
+
+* plugins/decorate
+* ChainedMap.parent
+#### Arguments
+1. `[parentToDecorate=undefined]` *(Object)*: decorate a specific parent shorthand
+
+#### Returns
+*(ChainedMap)*: @chainable
+
+#### Example
+```js
+var obj = {}
+new MethodChain({}).name('eh').decorate(obj).build()
+typeof obj.eh
+//=> 'function'
+
+```
+#### Example
+```js
+class Decorator extends Chain {
+ constructor(parent) {
+ super(parent)
+ this.methods(['easy']).decorate(parent).build()
+ this.methods('advanced')
+ .onCall(this.advanced.bind(this))
+ .decorate(parent)
+ .build()
+ }
+ advanced(arg) {
+ this.set('advanced', arg)
+ return this.parent
+ }
+ easy(arg) {
+ this.parent.set('easy-peasy', arg)
+ }
+}
+
+class Master extends Chain {
+ constructor(parent) {
+ super(parent)
+ this.eh = new Decorator(this)
+ }
+}
+
+const master = new Master()
+
+master.get('easy-peasy')
+//=> true
+
+master.eh.get('advanced')
+//=> 'a+'
+
+```
+#### Example
+```js
+;+chain.method('ehOh').decorate(null)
+//=> @throws Error('must provide parent argument')
+
+```
+---
+
+
+
+
+
+MethodChain.name(methods=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L7420 "View in source") [Ⓣ][1]
+
+(Function): setup methods to build
+
+#### Arguments
+1. `methods=undefined` *(Object|string|string[])*: method names to build
+
+#### Returns
+*(MethodChain)*: @chainable
+
+#### Example
+```js
+var obj = {}
+new MethodChain(obj).name('eh').build()
+typeof obj.eh
+//=> 'function'
+
+```
+---
+
+
+
+
+
+MethodChain.schema(obj=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L7503 "View in source") [Ⓣ][1]
+
+(Function): an object that contains nestable `.type`s
+they are recursively *(using an optimized traversal cache)* mapped to validators
+❗ this method auto-calls .build, all other method config calls should be done before it
+
+
+#### @todos
+
+- [ ] link to `deps/is` docs
+- [ ] move out into a plugin to show how easy it is to use a plugin
+ and make it able to be split out for size when needed
+- [ ] inherit properties (in plugin, for each key)
+ from this for say, dotProp, getSet
+- [ ] very @important
+ that we setup schema validation at the highest root for validation
+ and then have some demo for how to validate on set using say mobx
+ observables for all the way down...
+
+
+#### @Since
+4.0.0
+
+#### Arguments
+1. `obj=undefined` *(Object)*: schema
+
+#### Returns
+*(MethodChain)*: @chainable
+
+#### Example
+```js
+chain
+ .methods()
+ .define()
+ .getSet()
+ .onInvalid((error, arg, instance) => console.log(error))
+ .schema({
+ id: '?number',
+ users: '?object|array',
+ topic: '?string[]',
+ roles: '?array',
+ creator: {
+ name: 'string',
+ email: 'email',
+ id: 'uuid',
+ },
+ created_at: 'date',
+ updated_at: 'date|date[]',
+ summary: 'string',
+ })
+
+//--- valid
+chain.created_at = new Date()
+chain.setCreatedAt(new Date())
+
+isDate(chain.created_at) === true
+
+//--- nestable validation 👍
+chain.merge({ creator: { name: 'string' } })
+
+//--- invalid
+chain.updated_at = false
+
+```
+---
+
+
+
+
+
+
+
+## `Observe`
+
+
+
+Observe.observe(properties=undefined, fn=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L37 "View in source") [Ⓣ][1]
+
+(Function): observe properties when they change
+
+
+#### @see
+
+* traversers/eq
+* toarr
+* matcher
+*
+* examples/playground/TodoStore
+
+#### @todos
+
+- [ ] gotta update `data` if `deleting` too...
+- [ ] un-observe
+- [ ] should hash these callback properties
+- [ ] just throttle the `.set` to allow easier version of .commit
+
+#### Arguments
+1. `properties=undefined` *(Matchable)*: Matchable properties to observe
+2. `fn=undefined` *(Function)*: onChanged
+
+#### Returns
+*(Target)*: @chainable
+
+#### Example
+```js
+const Target = require('chain-able')
+
+const chain = new Target()
+const log = arg => console.log(arg)
+
+chain.extend(['eh']).observe('eh', data => log(data)).eh(true)
+//=> {eh: true}
+
+```
+#### Example
+```js
+chain
+ .extend(['canada', 'timbuck'])
+ .observe(['canad*'], data => console.log(data.canada))
+ .canada(true)
+ .canada(true)
+ .timbuck(false)
+
+//=> true
+//=> false
+
+// only called when changed,
+// otherwise it would be 2 `true` & 1 `false`
+
+```
+---
+
+
+
+
+
+🔬 Tests: DotProp
+
+Observe.DotProp(Target=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L10367 "View in source") [Ⓣ][1]
+
+Function
+
+
+#### @see
+
+* deps/dot
+
+#### @extends
+ChainedMap
+
+
+#### Arguments
+1. `Target=undefined` *(Class|Composable)*: composable class
+
+#### Returns
+*(DotProp)*: class
+
+#### Example
+```js
+const { compose } = require('chain-able')
+const { DotProp } = compose
+new DotProp()
+//=> DotProp
+
+```
+#### Example
+```js
+const chain = new Chain()
+
+chain.set('moose.simple', 1)
+//=> Chain
+
+chain.get('moose.simple')
+//=>1
+
+chain.get('moose')
+//=> {simple: 1}
+
+chain.set('moose.canada.eh', true).set('moose.canada.igloo', true)
+//=> Chain
+
+//set, has, get, delete :-)
+chain.delete('moose.canada.eh')
+//=> Chain
+
+//also works with an array (moose.canada.igloo)
+chain.get(['moose', 'canada', 'igloo'])
+//=> true
+
+```
+---
+
+
+
+
+
+🔬 Tests: observe
+
+Observe.Observe(Target=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L21 "View in source") [Ⓣ][1]
+
+(Function): > subscribe to changes ❗ called only on **change** observers are only called when data they subscribe to changes
+
+
+#### @see
+
+* ChainedMap
+* DotProp
+* deps/matcher
+* deps/traversers/eq
+* deps/traverse
+* DotProp
+* reactivex
+* awesome-observables
+* building-observables
+* observer-pattern
+* observable-air
+
+#### @extends
+
+* ChainedMap
+* DotProp
+
+
+
+#### @Since
+3.0.1
+
+#### Arguments
+1. `Target=undefined` *(Class|Composable)*: composable class
+
+#### Returns
+*(Observe)*: class
+
+#### Example
+```js
+const { compose } = require('chain-able')
+const { DotProp } = compose
+new DotProp()
+//=> DotProp
+
+```
+---
+
+
+
+
+
+
+
+## `ShorthandChain`
+
+
+
+ShorthandChain.return(value=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L9494 "View in source") [Ⓣ][1]
+
+(Function): returns any value passed in return a value at the end of a chain regardless
+
+
+#### @Since
+3.0.0
+
+#### Arguments
+1. `value=undefined` *(any)*: value to return at the end of a chain
+
+#### Returns
+*(any)*: value
+
+#### Example
+```js
+const chain = new Chain()
+
+const saveAndDebug = env =>
+ chain.from({ env: env.NODE_ENV }).return(JSON.stringify(env))
+
+console.log(saveAndDebug(process.env))
+//=> value of process.env
+
+```
+---
+
+
+
+
+
+ShorthandChain.setIfEmpty(name=undefined, value=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L9468 "View in source") [Ⓣ][1]
+
+(Function): sets a value **only** when .has is false aka set if the value has not been set
+
+
+#### @see
+
+* ChainedMapBase.set
+
+#### @Since
+1.0.2
+
+#### Arguments
+1. `name=undefined` *(Primitive)*: key to set if it has not been done so already
+2. `value=undefined` *(any)*: value to set when key has not been already set
+
+#### Returns
+*(ShorthandChain)*: @chainable
+
+#### Example
+```js
+const chain = new Chain()
+
+chain.set('eh', true)
+
+// eh is already set ^, ignored
+chain.setIfEmpty('eh', false)
+
+chain.get('eh')
+//=> true
+
+```
+#### Example
+```js
+new Chain().setIfEmpty('canada', true).entries()
+//=> {canada: true}
+
+```
+#### Example
+```js
+// longhand way to do the same thing
+if (chain.has('eh') === false) {
+ chain.set('eh', false)
+}
+
+// or using .when
+chain.when(!chain.has('eh'), instance => instance.set('eh', false))
+
+```
+---
+
+
+
+
+
+ShorthandChain.wrap(fn=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L9527 "View in source") [Ⓣ][1]
+
+(Function): wrap a value, if it's a Function call it, return this aka execute something and return this
+
+
+#### @Since
+2.0.0
+
+#### Arguments
+1. `fn=undefined` *(Function|any)*: function to call, or just any value
+
+#### Returns
+*(ShorthandChain)*: @chainable
+
+#### Example
+```js
+const { eh } = chain.wrap(chain => (chain.eh = true))
+//=> true
+
+```
+#### Example
+```js
+new Chain()
+ .wrap(
+ encased =>
+ (encased.fn = arg => {
+ throw new Error('encased yo')
+ })
+ )
+ .method('fn')
+ .encase()
+ .catch(error => {
+ //=> Error('encasedYo')
+ })
+ .build()
+ .fn(true)
+
+```
+---
+
+
+
+
+
+
+
+## `Transform`
+
+
+
+
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L9916 "View in source") [Ⓣ][1]
+
+Function
+
+#### Arguments
+1. `Target=undefined` *(Class|Composable)*: composable class
+
+#### Returns
+*(TransformChain)*: class
+
+#### Example
+```js
+compose(class {})
+//=> TransformChain
+
+```
+---
+
+
+
+
+
+
+
+## `TransformChain`
+
+
+
+🔬 Tests: TransformChain
+
+
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L11 "View in source") [Ⓣ][1]
-chain.get('str')
-//=> 'stringy+'
+Map
-```
----
-
+#### @see
+
+* deps/traverse
+* TraverseChain
+
+#### @symb
+
+🤖
+
+#### @extends
+ChainedMap
+
+
+---
-## `MethodChain.prototype`
+
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L10112 "View in source") [Ⓣ][1]
-
+(Function): remap properties from `1` to another, for example, apis with inconsistent naming
-🌊 Types: MethodChain.d
-🔬 Tests: MethodChain
+#### @see
-# MethodChain.prototype.MethodChain
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L4410 "View in source") [Ⓣ][1]
+* TransformChain.transform
-(Map): ❗ using `+` will call `.build()` in a shorthand fashion
+#### @symb
+🗺
-### @todos
+#### @Since
+1.0.0
-- [ ] maybe abstract the most re-usable core as a protected class
- so the shorthands could be used, and more functionality made external
-- [ ] need to separate schema from here as external functionality & add .add
-- [ ] .prop - for things on the instance, not in the store?
- !!! .sponge - absorn properties into the store
-
+#### Arguments
+1. `from=undefined` *(Object|string)*: property name string, or {[from]: to}
+2. `[to=undefined]` *(string)*: property name to change key to
-### @extends
-ChainedMap
+#### Returns
+*(Chain)*: @chainable
+
+#### Example
+```js
+chain.remap('dis', 'dat').from({ dis: true })
+chain.entries()
+//=> {dat: true}
-#### Since
-4.0.0
+```
+#### Example
+```js
+chain
+ .remap({dis: 'dat'})
+ .from({dis: 1, other: true}}
+ chain.entries()
+ //=> {dist: 1, other: true}
+```
---
-# MethodChain.prototype._build(name=undefined, parent=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L4748 "View in source") [Ⓣ][1]
+
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L10024 "View in source") [Ⓣ][1]
Function
-### @notes
-
-* scoping here adding default functions have to rescope arguments
-
+#### @see
-### @todos
+*
-- [ ] allow config of method var in plugins since it is scoped...
-- [ ] add to .meta(shorthands)
-- [ ] reduce complexity if perf allows
-
-#### Since
-4.0.0-alpha.1
+#### @Since
+1.0.0
#### Arguments
-1. `name=undefined` *(Primitive)*:
-2. `parent=undefined` *(Object)*:
+1. `key=undefined` *(Primitive)*: key to set with
+2. `val=undefined` *(any)*: value to set for key
+3. `dotPropKey=undefined` *(|string|string[])*: special key used for initializing dot prop values in an optimized way to keep reference
#### Returns
-*(void)*:
+*(Chainable)*: @chainable
---
@@ -1680,61 +2974,149 @@ Function
-# MethodChain.prototype._defaults(name=undefined, parent=undefined, built=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L4708 "View in source") [Ⓣ][1]
+
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L10006 "View in source") [Ⓣ][1]
Function
-### @todos
+#### @todos
-- [ ] optimize the size of this
- with some bitwise operators
- hashing the things that have been defaulted
- also could be plugin
+- [ ] dot-prop here
-#### Since
-4.0.0
+
+#### @Since
+1.0.2
#### Arguments
-1. `name=undefined` *(Primitive)*: method name
-2. `parent=undefined` *(Object)*: being decorated
-3. `built=undefined` *(Object)*: method being built
+1. `key=undefined` *(Function|string)*: currently just string
+2. `value=undefined` *(Function)*: callback accepting the value as only arg to transform with
#### Returns
-*(void)*:
+*(TransformChain)*: @chainable
#### Example
```js
-._defaults('', {}, {})
+// coerce values with .id into the value they hold
+chain.transform('dis', val => (typeof val === 'string' ? val : val.id))
+
+chain.set('dis', 'eh')
+chain.get('dis')
+//=> 'eh'
+
+chain.set('dis', { id: 'eh' })
+chain.get('dis')
+//=> 'eh'
+
```
#### Example
```js
-let methodFactories
+import { format } from 'date-fns/esm'
+import { Chain } from 'chain-able'
- ### `onSet`
+const chain = new Chain()
+chain.transform('created_at', date => format(date, 'MM/DD/YYYY'))
+chain.set('created_at', new Date())
- > defaults to `this.set(key, value)`
+// is formatted human-readable pretty!
+const { created_at } = chain.entries()
+//=> '02/11/2014'
- ```ts
- public onSet(fn: Fn): MethodChain
- ```
+```
+---
- ### `onCall`
+
- > defaults to .onSet ^
+
- ```ts
- public onCall(fn: Fn): MethodChain
- ```
+
- ### `onGet`
+## `Traverse`
- > defaults to `this.get(key)`
+
- ```ts
- public onGet(fn: Fn): MethodChain
- ```
+🌊 Types: TraverseChain.d
+
+🔬 Tests: TraverseChain
+
+Traverse.TraverseChain
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L9726 "View in source") [Ⓣ][1]
+
+Map
+
+
+#### @see
+
+* deps/traverse
+
+#### @symb
+
+👣
+
+#### @classProps
+
+* {obj}
+* {keys}
+* {vals}
+* {onMatch}
+* {onNonMatch}
+* {clone}
+
+
+#### @extends
+ChainedMapBase
+
+
+
+#### @Since
+1.0.0
+
+---
+
+
+
+
+
+Traverse.checkIteratable(node=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L4720 "View in source") [Ⓣ][1]
+
+(Function): checks whether a node is iteratable
+
+
+#### @todos
+
+- [ ] move into the wrapper? if perf allows?
+
+#### Arguments
+1. `node=undefined` *(*)*: value to check
+
+#### Returns
+*(void)*:
+
+#### Example
+```js
+.checkIteratable({eh: true})
+ //=> this.isLeaf = false
+ //=> this.isCircular = false
+ //=> this.isIteratable = true
+
+ .checkIteratable({} || [])
+ //=> this.isLeaf = true
+ //=> this.isCircular = false
+ //=> this.isIteratable = false
+
+ var circular = {}
+ circular.circular = circular
+ .checkIteratable(circular)
+ //=> this.isLeaf = false
+ //=> this.isCircular = true
+ //=> this.isIteratable = true
```
---
@@ -1742,31 +3124,43 @@ let methodFactories
-# MethodChain.prototype.autoGetSet(name=undefined, parent=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L4183 "View in source") [Ⓣ][1]
+Traverse.clone(arg=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L5218 "View in source") [Ⓣ][1]
-Function
+(Function): clone any value
+
+
+#### @see
+
+* dopemerge
+
+#### @extends
+
+* undefined
+* undefined
-### @see
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
+#### @Since
+4.0.0
+
#### Arguments
-1. `name=undefined` *(Primitive)*: method name being built
-2. `parent=undefined` *(Object)*: parent containing the method
+1. `arg=undefined` *(*)*: argument to clone
#### Returns
-*(MethodChain)*: @chainable
+*(*)*: cloned value
#### Example
```js
-const chain = new Chain()
-chain.methods('eh').plugin(autoGetSet).build()
+var obj = { eh: true }
+clone(obj) === obj //=> false
-chain.eh(1)
-//=> Chain
-chain.eh()
-//=> 1
+var obj = { eh: true }
+var obj2 = clone(obj)
+obj.eh = false
+console.log(obj2.eh) //=> true
```
---
@@ -1775,26 +3169,33 @@ chain.eh()
-# MethodChain.prototype.autoIncrement()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L5054 "View in source") [Ⓣ][1]
+Traverse.copy(src=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L3729 "View in source") [Ⓣ][1]
+
+(Function): copy any primitive value, part of clone
-(Function): adds a plugin to increment the value on every call
+#### @see
-### @see
+* clone
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-#### Since
-0.4.0
+#### @Since
+3.0.0
+
+#### Arguments
+1. `src=undefined` *(*)*: value to copy
#### Returns
-*(MethodChain)*: @chainable
+*(*)*: copied
#### Example
```js
-chain.methods(['index']).autoIncrement().build().index().index(+1).index()
-chain.get('index')
-//=> 3
+copy(/eh/gim) //=> new RegExp('eh', 'gmi')
+copy(new Error('eh')) // => new Error with copied stack + msg
+copy([1]) // => [1]
+copy({}) // => {}
```
---
@@ -1803,37 +3204,86 @@ chain.get('index')
-# MethodChain.prototype.build([returnValue=undefined])
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L4634 "View in source") [Ⓣ][1]
+Traverse.eq(traverse=undefined, a=undefined, b=undefined, [loose=undefined])
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L21 "View in source") [Ⓣ][1]
-(Function): set the actual method, also need .context - use .parent
+Function
-### @see
+#### @see
+
+* immutable-js-deep-equal
+* node-deep-equal
+* ramda-equals
+* lodash-is-equal
+* angular-is-equal
+* underscore-equal
+* traverse-deep-equal
+* react-deep-differ
+
+#### @extends
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-### @todos
-- [ ] if passing in a name that already exists, operations are decorations... (partially done)
-
-#### Since
-4.0.0
+
+#### @Since
+3.0.0
#### Arguments
-1. `[returnValue=undefined]` *(any)*: returned at the end of the function for ease of use
+1. `traverse=undefined` *(Traverse): traversejs *(scoped, @FIXME @HACK)**
+2. `a=undefined` *(*)*: compare to b
+3. `b=undefined` *(*)*: compare to a
+4. `[loose=undefined]` *(boolean)*: compare loosely
#### Returns
-*(MethodChain)*: @chainable
+*(boolean)*: isEqual: a === b
#### Example
```js
-var obj = {}
-const one = new MethodChain(obj).methods('eh').getSet().build(1)
-//=> 1
+eq(1, 1) //=> true
+eq(1, '1') //=> false
+eq(1, '1', true) //=> true
+eq([1], [1]) //=> true
+
+```
+---
+
+
+
+
+
+Traverse.eqValue(x=undefined, y=undefined, [loose=false])
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L3876 "View in source") [Ⓣ][1]
+
+(Function): checks value equality, used by eq which compares all types
+
+
+#### @todos
+
+- [ ] !!!!!! USE ENUM FLAGS ON LOOSE TO ALLOW MORE CONFIG FOR ==, COMPARATOR, VALUEOF, walk proto (check ownProps...)...
+
+
+#### @Since
+4.1.0
+
+#### Arguments
+1. `x=undefined` *(*)*: compare to y
+2. `y=undefined` *(*)*: compare to x
+3. `[loose=false]` *(boolean|number)*: use == checks when typof !=
+
+#### Returns
+*(boolean)*:
-typeof obj.getEh
-//=> 'function'
+#### Example
+```js
+eqValue(1, 1) //=> true
+eqValue('1', 1) //=> false
+eqValue('1', 1, true) //=> true
+eqValue({}, {}) //=> true
```
---
@@ -1842,39 +3292,29 @@ typeof obj.getEh
-# MethodChain.prototype.decorate(parentToDecorate=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L4128 "View in source") [Ⓣ][1]
-
-(Function): decorates a parent when the argument is provided
-BUT THE FUNCTIONS WILL STILL BE SCOPED TO CURRENT PARENT
-for easy factory chaining
-
-
-### @see
+Traverse.forEach(cb=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L4633 "View in source") [Ⓣ][1]
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
+(Function): this is the main usage of Traverse
-### @todos
-- [ ] this is more like a preset since it *adds* plugins?
- more of methodFactory now
-
-#### Since
-4.0.0-alpha.1
+#### @Since
+3.0.0
#### Arguments
-1. `parentToDecorate=undefined` *(Object)*: object to put the method on instead
+1. `cb=undefined` *(Function)*: callback for each iteration
#### Returns
-*(MethodChain)*: @chainable
+*(*)*: mapped result or original value, depends how it is used
#### Example
```js
-const chain = new Chain()
-const obj = {}
-chain.method('ehOh').decorate(obj).build()
-typeof obj.ehOh
-//=> 'function'
+traverse([1, 2, 3]).forEach((key, value) => console.log({ [key]: value }))
+//=> {'0': 1}
+//=> {'1': 2}
+//=> {'2': 3}
```
---
@@ -1883,69 +3323,67 @@ typeof obj.ehOh
-# MethodChain.prototype.decorate([parentToDecorate=undefined])
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L5023 "View in source") [Ⓣ][1]
+Traverse.iterate(on=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L4901 "View in source") [Ⓣ][1]
-(Function): add methods to the parent for easier chaining
+Function
-### @see
+#### @todos
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
+- [ ] handler for Set & Map so they can be skipped or traversed, for example when cloning...
+- [ ] add hook to add custom checking if isIteratable
+- [ ] deal with .isRoot if needed
+- [ ] examples with clone and stop
+
+
+#### @sig
+
+on(key: null | Primitive, val: any, instance: Traverse): any
#### Arguments
-1. `[parentToDecorate=undefined]` *(Object)*: decorate a specific parent shorthand
+1. `on=undefined` *(Function)*: callback fn for each iteration
#### Returns
-*(ChainedMap)*: @chainable
+*(*)*: this.node
#### Example
```js
-var obj = {}
-new MethodChain({}).name('eh').decorate(obj).build()
-typeof obj.eh
-//=> 'function'
+iterate([])
+//=> []
+//=> on(null, [])
```
#### Example
```js
-class Decorator extends Chain {
- constructor(parent) {
- super(parent)
- this.methods(['easy']).decorate(parent).build()
- this.methods('advanced')
- .onCall(this.advanced.bind(this))
- .decorate(parent)
- .build()
- }
- advanced(arg) {
- this.set('advanced', arg)
- return this.parent
- }
- easy(arg) {
- this.parent.set('easy-peasy', arg)
- }
-}
-
-class Master extends Chain {
- constructor(parent) {
- super(parent)
- this.eh = new Decorator(this)
- }
-}
-
-const master = new Master()
-
-master.get('easy-peasy')
-//=> true
+iterate([1])
+//=> [1]
+//=> on(null, [1])
+//=> on('1', 1)
-master.eh.get('advanced')
-//=> 'a+'
+```
+#### Example
+```js
+//primitive - same for any number, string, symbol, null, undefined
+iterate(Symbol('eh'))
+//=> Symbol('eh')
+//=> on(Symbol('eh'))
```
#### Example
```js
-;+chain.method('ehOh').decorate(null)
-//=> @throws Error('must provide parent argument')
+var deeper = { eh: 'canada', arr: [{ moose: true }, 0] }
+iterate(deeper)
+//=> deeper // returns
+//=> on(null, deeper, this) // root
+
+//=> on('eh', 'canada', this) // 1st branch
+
+//=> on('arr', [{moose: true}, 0], this)
+//=> on('arr.0', [{moose: true}], this)
+//=> on('arr.0.moose', true, this)
+//=> on('arr.1', [0], this)
```
---
@@ -1954,23 +3392,37 @@ master.eh.get('advanced')
-# MethodChain.prototype.name(methods=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L4526 "View in source") [Ⓣ][1]
+Traverse.remove([arg=undefined])
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L4780 "View in source") [Ⓣ][1]
-(Function): setup methods to build
+(Function): Remove the current element from the output.
+If the node is in an Array it will be spliced off.
+Otherwise it will be deleted from its parent.
+
+
+#### @Since
+2.0.0
#### Arguments
-1. `methods=undefined` *(Object|string|string[])*: method names to build
+1. `[arg=undefined]` *(|Object)*: optional obj to use, defaults to this.node
#### Returns
-*(MethodChain)*: @chainable
+*(void)*:
#### Example
```js
-var obj = {}
-new MethodChain(obj).name('eh').build()
-typeof obj.eh
-//=> 'function'
+traverse([0]).forEach((key, val, it) => it.remove())
+//=> []
+
+traverse({ eh: true }).forEach((key, val, it) => it.remove())
+//=> {}
+
+traverse({ eh: true, str: 'stringy' }).forEach((key, val, it) => {
+ if (!isString(val)) it.remove()
+})
+//=> {str: 'stringy'}
```
---
@@ -1979,131 +3431,53 @@ typeof obj.eh
-# MethodChain.prototype.schema(obj=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L4609 "View in source") [Ⓣ][1]
+Traverse.skip()
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L4681 "View in source") [Ⓣ][1]
-(Function): an object that contains nestable `.type`s
-they are recursively *(using an optimized traversal cache)* mapped to validators
-❗ this method auto-calls .build, all other method config calls should be done before it
+Function
-### @todos
+#### @todos
-- [ ] link to `deps/is` docs
-- [ ] move out into a plugin to show how easy it is to use a plugin
- and make it able to be split out for size when needed
-- [ ] inherit properties (in plugin, for each key)
- from this for say, dotProp, getSet
-- [ ] very @important
- that we setup schema validation at the highest root for validation
- and then have some demo for how to validate on set using say mobx
- observables for all the way down...
+- [ ] skip 1 branch
-#### Since
-4.0.0
-#### Arguments
-1. `obj=undefined` *(Object)*: schema
+#### @Since
+3.0.0
#### Returns
-*(MethodChain)*: @chainable
+*(void)*:
#### Example
```js
-chain
- .methods()
- .define()
- .getSet()
- .onInvalid((error, arg, instance) => console.log(error))
- .schema({
- id: '?number',
- users: '?object|array',
- topic: '?string[]',
- roles: '?array',
- creator: {
- name: 'string',
- email: 'email',
- id: 'uuid',
- },
- created_at: 'date',
- updated_at: 'date|date[]',
- summary: 'string',
- })
-
-//--- valid
-chain.created_at = new Date()
-chain.setCreatedAt(new Date())
-
-isDate(chain.created_at) === true
-
-//--- nestable validation 👍
-chain.merge({ creator: { name: 'string' } })
-
-//--- invalid
-chain.updated_at = false
+traverse([1, 2, 3, [4]]).forEach((key, val, t) => {
+ if (isArray(val)) t.skip()
+})
```
---
-
-
-
-
-## `Observe.prototype`
-
-# Observe.prototype.observe(properties=undefined, fn=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L62 "View in source") [Ⓣ][1]
-
-(Function): observe properties when they change
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-
-### @todos
+Traverse.stop()
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L4661 "View in source") [Ⓣ][1]
-- [ ] gotta update `data` if `deleting` too...
-- [ ] un-observe
-- [ ] should hash these callback properties
-- [ ] just throttle the `.set` to allow easier version of .commit
-
-#### Arguments
-1. `properties=undefined` *(Matchable)*: Matchable properties to observe
-2. `fn=undefined` *(Function)*: onChanged
+(Function): stop the iteration
#### Returns
-*(Target)*: @chainable
-
-#### Example
-```js
-const Target = require('chain-able')
-
-const chain = new Target()
-const log = arg => console.log(arg)
-
-chain.extend(['eh']).observe('eh', data => log(data)).eh(true)
-//=> {eh: true}
+*(void)*:
-```
#### Example
```js
-chain
- .extend(['canada', 'timbuck'])
- .observe(['canad*'], data => console.log(data.canada))
- .canada(true)
- .canada(true)
- .timbuck(false)
-
-//=> true
-//=> false
-
-// only called when changed,
-// otherwise it would be 2 `true` & 1 `false`
+traverse({ eh: true, arr: [] }).forEach((key, val, t) => {
+ if (isArray(val)) this.stop()
+})
```
---
@@ -2112,100 +3486,88 @@ chain
-🔬 Tests: DotProp
-
-# Observe.prototype.DotProp(Chain=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L7367 "View in source") [Ⓣ][1]
-
-Function
-
-
-### @see
+Traverse.update(value=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L4823 "View in source") [Ⓣ][1]
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
+(Function): update the value for the current key
-### @extends
-ChainedMap
+#### @Since
+2.0.0
#### Arguments
-1. `Chain=undefined` *(Class|Composable)*: composable class
+1. `value=undefined` *(*)*: this.node[this.key] = value
#### Returns
-*(DotProp)*: class
-
-#### Example
-```js
-const { compose } = require('chain-able')
-const { DotProp } = compose
-new DotProp()
-//=> DotProp
+*(void)*:
-```
#### Example
```js
-const chain = new Chain()
-
-chain.set('moose.simple', 1)
-//=> Chain
-
-chain.get('moose.simple')
-//=>1
-
-chain.get('moose')
-//=> {simple: 1}
-
-chain.set('moose.canada.eh', true).set('moose.canada.igloo', true)
-//=> Chain
-
-//set, has, get, delete :-)
-chain.delete('moose.canada.eh')
-//=> Chain
-
-//also works with an array (moose.canada.igloo)
-chain.get(['moose', 'canada', 'igloo'])
-//=> true
+traverse({ eh: true }).forEach((key, val, traverser) => {
+ if (this.isRoot) return
+ traverser.update(false)
+})
+//=> {eh: false}
```
---
+
+
-🔬 Tests: observe
+## `TraverseChain`
-# Observe.prototype.Observe(Chain=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L34 "View in source") [Ⓣ][1]
+
-(Function): > subscribe to changes ❗ called only on **change** observers are only called when data they subscribe to changes
+TraverseChain.traverse([shouldReturn=false])
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L9783 "View in source") [Ⓣ][1]
+(Function): runs traverser, checks the tests, calls the onMatch
-### @see
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
+#### @Since
+1.0.0
-### @extends
+#### Arguments
+1. `[shouldReturn=false]` *(boolean)*: returns traversed object
-* ChainedMap
-* DotProp
+#### Returns
+*(any)*: this.obj/data cleaned
+#### Example
+```js
+const traversed = new Chain()
+ .merge({ flat: 0, one: { two: true } })
+ .traverse(false)
+ .vals([/true/])
+ .onMatch((current, traverser) => {
+ traverser.path.join('.')
+ //=> 'one.two'
-#### Since
-3.0.1
+ current
+ //=> true
-#### Arguments
-1. `Chain=undefined` *(Class|Composable)*: composable class
+ typeof traverser.update === typeof traverser.remove
+ typeof traverser.update === 'function'
+ //=> true
-#### Returns
-*(Observe)*: class
+ traverser.remove()
+ //=> void
+ })
+ .onNonMatch(val => {
+ // ignore
+ })
+ .call(true)
-#### Example
-```js
-const { compose } = require('chain-able')
-const { DotProp } = compose
-new DotProp()
-//=> DotProp
+traversed
+//=> {flat: 0}
```
---
@@ -2216,132 +3578,142 @@ new DotProp()
-## `ShorthandChain.prototype`
+## `add`
-# ShorthandChain.prototype.return(value=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L6790 "View in source") [Ⓣ][1]
+add(methodFactory=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L7985 "View in source") [Ⓣ][1]
+
+(Function): add methodFactories easily
-(Function): returns any value passed in return a value at the end of a chain regardless
-#### Since
-3.0.0
+#### @Since
+4.0.0-beta.2
#### Arguments
-1. `value=undefined` *(any)*: value to return at the end of a chain
+1. `methodFactory=undefined` *(Object)*: factories to add
#### Returns
-*(any)*: value
+*(void)*:
#### Example
```js
-const chain = new Chain()
+function autoGetSet(name, parent) {
+ const auto = arg =>
+ isUndefined(arg) ? parent.get(name) : parent.set(name, arg)
-const saveAndDebug = env =>
- chain.from({ env: env.NODE_ENV }).return(JSON.stringify(env))
+ //so we know if we defaulted them
+ auto.autoGetSet = true
+ return this.onSet(auto).onGet(auto).onCall(auto)
+}
+MethodChain.addPlugin({ autoGetSet })
-console.log(saveAndDebug(process.env))
-//=> value of process.env
+const chain = new Chain()
+chain.methods('eh').autoGetSet().build()
+
+chain.eh(1)
+//=> chain
+chain.eh()
+//=> 1 *
```
---
+
+
+
+
+## `addTypes`
+
-# ShorthandChain.prototype.setIfEmpty(name=undefined, value=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L6764 "View in source") [Ⓣ][1]
+🌊 Types: schema.d
-(Function): sets a value **only** when .has is false aka set if the value has not been set
+addTypes(types=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L6096 "View in source") [Ⓣ][1]
+(Function): add custom types for validation
-### @see
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-#### Since
-1.0.2
+#### @see
+* deps/validators/validatorFactory
#### Arguments
-1. `name=undefined` *(Primitive)*: key to set if it has not been done so already
-2. `value=undefined` *(any)*: value to set when key has not been already set
-
-#### Returns
-*(ShorthandChain)*: @chainable
+1. `types=undefined` *(Object)*: custom Types
#### Example
```js
-const chain = new Chain()
-
-chain.set('eh', true)
+addTypes({ yaya: x => typeof x === 'string' })
-// eh is already set ^, ignored
-chain.setIfEmpty('eh', false)
+const chain = new Chain().methods('eh').type('yaya').build()
-chain.get('eh')
-//=> true
+chain.eh('good')
+//=> chain
-```
-#### Example
-```js
-new Chain().setIfEmpty('canada', true).entries()
-//=> {canada: true}
+chain.eh(!!'throws')
+//=> TypeError(false != {yaya: x => typeof x === 'string'})
```
#### Example
```js
-// longhand way to do the same thing
-if (chain.has('eh') === false) {
- chain.set('eh', false)
-}
+const custom = {}
+custom.enums = enums => x => enums.includes(x)
+custom['*'] = x => true
+addTypes(custom)
+//-> void
-// or using .when
-chain.when(!chain.has('eh'), instance => instance.set('eh', false))
+new Chain().methods('eh').type('*').build().eh
+//=> validateType(custom['*'])
```
---
+
+
-# ShorthandChain.prototype.wrap(fn=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L6823 "View in source") [Ⓣ][1]
+## `alias`
-(Function): wrap a value, if it's a Function call it, return this aka execute something and return this
+
+
+alias(aliases=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L7370 "View in source") [Ⓣ][1]
+
+(Function): alias methods
-#### Since
+
+#### @notes
+
+* these would be .transform
+
+
+#### @Since
2.0.0
#### Arguments
-1. `fn=undefined` *(Function|any)*: function to call, or just any value
+1. `aliases=undefined` *(string|string[])*: aliases to remap to the current method being built
#### Returns
-*(ShorthandChain)*: @chainable
-
-#### Example
-```js
-const { eh } = chain.wrap(chain => (chain.eh = true))
-//=> true
+*(MethodChain)*: @chainable
-```
#### Example
```js
-new Chain()
- .wrap(
- encased =>
- (encased.fn = arg => {
- throw new Error('encased yo')
- })
- )
- .method('fn')
- .encase()
- .catch(error => {
- //=> Error('encasedYo')
- })
- .build()
- .fn(true)
+const chain = new Chain()
+chain.methods(['canada']).alias(['eh']).build()
+chain.eh('actually...canada o.o')
+chain.get('canada')
+//=> 'actually...canada o.o')
```
---
@@ -2352,25 +3724,44 @@ new Chain()
-## `Transform`
+## `anyKeyVal`
-
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L7089 "View in source") [Ⓣ][1]
+🌊 Types: matcher.d
-Function
+anyKeyVal(keys=undefined, vals=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L9684 "View in source") [Ⓣ][1]
+
+(Function): the original simple to-test matcher for traversable,
+will be merged into, or simplified as simplified into matcher
+
+
+#### @todos
+
+- [ ] should use matcher,
+- [ ] should inprove the callback data...
+
+
+#### @Since
+2.0.0
#### Arguments
-1. `SuperClass=undefined` *(Class|Composable)*: composable class
+1. `keys=undefined` *(Matchable[])*: matchable keys
+2. `vals=undefined` *(Matchable[])*: matchable values
#### Returns
-*(TransformChain)*: class
+*(boolean)*: matched or not
#### Example
```js
-compose(class {})
-//=> TransformChain
+anyKeyVal([], [])(0, 0)
+//=> false
+
+anyKeyVal([() => true], [])(0, 0)
+//=> true
```
---
@@ -2381,154 +3772,200 @@ compose(class {})
-## `TransformChain.prototype`
+## `argumentor`
-🔬 Tests: TransformChain
-
-
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L11 "View in source") [Ⓣ][1]
+argumentor()
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L7077 "View in source") [Ⓣ][1]
-Map
+(Function): turns arguments into an array, used as a util, for opt
-### @see
+#### @see
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
+* https://github.com/aretecode/awesome-deopt
+* https://github.com/petkaantonov/bluebird/wiki/Optimization-killers
+* deps/util/lengthFromZero
-### @symb
+#### @Since
+3.0.0
-🤖
+#### Returns
+*(*)*:
-### @extends
-ChainedMap
+#### Example
+```js
+function eh() {
+ const args = argumentor.apply(null, arguments).slice(1)
+ console.log(args)
+ //=> [1, 10, 100]
+}
+eh(0, 1, 10, 100)
+```
---
+
+
-
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L7258 "View in source") [Ⓣ][1]
+## `arithmeticTypeFactory`
-(Function): remap properties from `1` to another, for example, apis with inconsistent naming
+
+
+🌊 Types: schema.d
+arithmeticTypeFactory(fullKey=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L6193 "View in source") [Ⓣ][1]
-### @see
+(Function): transform arithmetic strings into types
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-### @symb
+#### @see
-🗺
-#### Since
-1.0.0
+* is
+
+#### @todos
+
+- [ ] coercing values to certain types: arithmeticTypeFactory('')
+
+
+#### @Since
+4.0.0-alpha.1
#### Arguments
-1. `from=undefined` *(Object|string)*: property name string, or {[from]: to}
-2. `[to=undefined]` *(string)*: property name to change key to
+1. `fullKey=undefined` *(Matchable)*: arithmetic type key
#### Returns
-*(Chain)*: @chainable
+*(Matchable)*: function to match with, with .inspect for easy debugging
#### Example
```js
-chain.remap('dis', 'dat').from({ dis: true })
+arithmeticTypeFactory('?string')
+//=> x => !isReal(x) || isString(x)
-chain.entries()
-//=> {dat: true}
+```
+#### Example
+```js
+arithmeticTypeFactory('?string|string[]')
+//=> x => isString(x) || isArrayOf(isString)(x)
```
#### Example
```js
-chain
- .remap({dis: 'dat'})
- .from({dis: 1, other: true}}
+arithmeticTypeFactory('!string')
+//=> x => not(isString)(x)
+
+```
+#### Example
+```js
+types.addTypes({ star: x => true })
+arithmeticTypeFactory('object|function|star')
+//=> x => isObj(x) || isFunction(x) || isStar(x)
+
+```
+#### Example
+```js
+arithmeticTypeFactory('===')
+//=> x => (['===']).includes(x)
- chain.entries()
- //=> {dist: 1, other: true}
```
---
-
+
-
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L7197 "View in source") [Ⓣ][1]
+
-Function
+## `autoIncrement`
+
-### @see
+autoIncrement(name=undefined, parent=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L7011 "View in source") [Ⓣ][1]
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-#### Since
-1.0.0
+Function
#### Arguments
-1. `key=undefined` *(Primitive)*: key to set with
-2. `val=undefined` *(any)*: value to set for key
-3. `dotPropKey=undefined` *(|string|string[])*: special key used for initializing dot prop values in an optimized way to keep reference
+1. `name=undefined` *(Primitive)*: method name
+2. `parent=undefined` *(Object)*: Parent
#### Returns
-*(Chainable)*: @chainable
+*(MethodChain)*: @chainable
---
+
+
-
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L7179 "View in source") [Ⓣ][1]
+## `builder`
-Function
+
+
+builder(fullKey=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L6258 "View in source") [Ⓣ][1]
+(Function): @pattern @builder -> builds using multiple factories depending on conditons or abstractFactory whatever opinionated: if it's a function, it's a validator...
-### @todos
-- [ ] dot-prop here
+#### @see
+
+* https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/Default_parameters
+
+#### @notes
+
+* if/else is for uglifying ternaries, even though else if is not needed
+* if key is number, iterating the array
-#### Since
-1.0.2
+
+#### @Since
+4.0.0
#### Arguments
-1. `key=undefined` *(Function|string)*: currently just string
-2. `value=undefined` *(Function)*: callback accepting the value as only arg to transform with
+1. `fullKey=undefined` *(Function|Primitive|string)*: arithmetic key to the validator
#### Returns
-*(TransformChain)*: @chainable
+*(Function)*: validator
#### Example
```js
-// coerce values with .id into the value they hold
-chain.transform('dis', val => (typeof val === 'string' ? val : val.id))
-
-chain.set('dis', 'eh')
-chain.get('dis')
-//=> 'eh'
-
-chain.set('dis', { id: 'eh' })
-chain.get('dis')
-//=> 'eh'
+// functionType
+const isString = x => typeof x === 'string'
+builder(isString)
+// => isString
```
#### Example
```js
-import { format } from 'date-fns/esm'
-import { Chain } from 'chain-able'
+// stringType (built in, or custom-keyed validator, or eqeqeq)
+builder('string')
+// => isString
-const chain = new Chain()
-chain.transform('created_at', date => format(date, 'MM/DD/YYYY'))
-chain.set('created_at', new Date())
+const enummy = builder('enum')
+// => x => ['enum'].includes(x)
-// is formatted human-readable pretty!
-const { created_at } = chain.entries()
-//=> '02/11/2014'
+```
+#### Example
+```js
+// arithmeticType
+builder('string|string[]')
+// => isString || isArrayOf(isString)
```
---
@@ -2539,258 +3976,309 @@ const { created_at } = chain.entries()
-## `Traverse.prototype`
+## `camelCase`
-* 🌊 Types: TraverseChain.d
-* 🌊 Types: traverse.d
+* 🌊 Types: deps.d
+* 🌊 Types: deps.encase.d
+* 🌊 Types: deps.reduce.d
-* 🔬 Tests: circular
-* 🔬 Tests: date
-* 🔬 Tests: equal
-* 🔬 Tests: error
-* 🔬 Tests: has
-* 🔬 Tests: index
-* 🔬 Tests: instance
-* 🔬 Tests: interface
-* 🔬 Tests: json
-* 🔬 Tests: keys
-* 🔬 Tests: leaves
-* 🔬 Tests: negative
-* 🔬 Tests: obj
-* 🔬 Tests: set-map
-* 🔬 Tests: siblings
-* 🔬 Tests: stop
-* 🔬 Tests: stringify
-* 🔬 Tests: subexpr
-* 🔬 Tests: superDeep
+🔬 Tests: camelCase
-# Traverse.prototype.Traverse(obj=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2211 "View in source") [Ⓣ][1]
+camelCase(str=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L5801 "View in source") [Ⓣ][1]
-Function
+(Function): camelCase
-### @see
+#### @see
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
+* https://stackoverflow.com/questions/1533131/what-useful-bitwise-operator-code-tricks-should-a-developer-know-about
-### @todos
+#### @todos
-- [ ] : symbol, map, set
+- [ ] s.charAt(0).toLowerCase() + string.slice(1)
-### @classProps
+#### @symb
+
+🐫
+
+#### @Since
+0.2.0
-* {value} the data passed in as an argument to traverse on
-
#### Arguments
-1. `obj=undefined` *(Traversable)*: any traversable value
+1. `str=undefined` *(string)*: string to turn into camelCase
+
+#### Returns
+*(string)*: camelCased string
#### Example
```js
-traverse({})
-//=> Traverser
+camelCase('snake_case')
+//=> 'snakeCase'
```
---
+
+
+
+
+## `clone`
+
-# Traverse.prototype.map(cb=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2319 "View in source") [Ⓣ][1]
+clone(arg=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L5186 "View in source") [Ⓣ][1]
-(Function): Execute fn for each node in the object and return a new object with the results of the walk. To update nodes in the result use this.update(value).
+Function
-### @see
+#### @todos
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
+- [ ] merge with dopemerge?
+- [ ] needs tests converted back for this (observe tests do cover somewhat)
+
#### Arguments
-1. `cb=undefined` *(Function)*: fn for each node in the object
+1. `arg=undefined` *(*)*: defaults to this.node
#### Returns
-*(any)*:
+*(*)*: cloned
#### Example
```js
-var { traverse } = require('chain-able')
-
-var obj = { a: 1, b: 2, c: [3, 4] }
-obj.c.push(obj)
-
-var scrubbed = traverse(obj).map(function(x) {
- if (this.circular) this.remove()
-})
-console.dir(scrubbed)
-//=> { a: 1, b: 2, c: [ 3, 4 ] }
+var obj = {}
+var cloned = traverse().clone(obj)
+obj.eh = true
+eq(obj, cloned)
+//=> false
```
---
-
-
-🌊 Types: TraverseChain.d
-
-🔬 Tests: TraverseChain
-
-# Traverse.prototype.TraverseChain
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L6931 "View in source") [Ⓣ][1]
+
-Map
+
+## `compose`
-### @see
+
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
+🌊 Types: compose.d
-### @symb
+🔬 Tests: compose
-👣
+compose.compose([target=ChainedMap], [extensions=[Observe,Shorthands,Transform,DotProp]])
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L10621 "View in source") [Ⓣ][1]
-### @classProps
+(Function): compose chains all the way up from Chainable
-* {obj}
-* {keys}
-* {vals}
-* {onMatch}
-* {onNonMatch}
-* {clone}
-
-### @extends
-ChainedMapBase
+#### @see
+* https://formidable.com/blog/2017/infinite-state-composition-with-freactal/
+* https://blog.javascripting.com/2016/02/02/encapsulation-in-redux/
+* https://www.barbarianmeetscoding.com/blog/2016/01/04/safer-javascript-object-composition-with-traits-and-traits-dot-js/
+* https://medium.com/javascript-scene/why-learn-functional-programming-in-javascript-composing-software-ea13afc7a257
+* https://hackernoon.com/javascript-functional-composition-for-every-day-use-22421ef65a10
+* https://github.com/stoeffel/awesome-fp-js
-#### Since
-1.0.0
+#### @symb
----
+🎼
-
+#### @Since
+3.0.0
-
+#### Arguments
+1. `[target=ChainedMap]` *(|Class|Function)*: class or function to extend
+2. `[extensions=[Observe,Shorthands,Transform,DotProp]]` *(|Array)*: Array of extensions to compose together left to right
-# Traverse.prototype.clone()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2439 "View in source") [Ⓣ][1]
+#### Returns
+*(*)*: composed
-(Function): Create a deep clone of the object.
+#### Example
+```js
+class Eh extends compose() {}
+new Eh() instanceof Chainable
+//=> true
-#### Returns
-*(any)*:
+```
+#### Example
+```js
+class Target {}
+class Eh extends compose(Target) {}
+new Eh() instanceof Target
+//=> true
+```
#### Example
```js
-const { traverse, eq } = require('chain-able')
+class Target {}
+const mixin = SuperClass => class extends SuperClass {}
+class Eh extends compose(Target) {}
+new Eh() instanceof Chainable
+//=> true
-const obj = { eh: true, canada: [1] }
-const cloned = traverse(obj).clone()
-cloned.eh = false
-eq(cloned, obj)
-//=> false
+```
+#### Example
+```js
+class Winning {}
+class Yes extends compose(Winning) {
+ get winning() {
+ return true
+ }
+}
+const yes = new Yes()
+yes instanceof Winning && yes.winning
+//=> true
```
---
+
+
+
+
+## `concat`
+
-# Traverse.prototype.forEach(callback=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2346 "View in source") [Ⓣ][1]
+concat(one=undefined, two=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2406 "View in source") [Ⓣ][1]
-(Function): Execute fn for each node in the object but unlike .map(), when this.update() is called it updates the object in-place. executes a provided function once for each traversed element.
+(Function): concat two values, coerce to arrays
-### @see
+#### @Since
+4.0.0
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
#### Arguments
-1. `callback=undefined` *(Function)*: provided callback function
+1. `one=undefined` *(*|Array)*: toArr1
+2. `two=undefined` *(*|Array)*: toArr2
#### Returns
-*(any)*: this.value
+*(Array)*: [one, two]
#### Example
```js
-var { traverse } = require('chain-able')
-
-var obj = [5, 6, -3, [7, 8, -2, 1], { f: 10, g: -13 }]
-traverse(obj).forEach(function(x) {
- if (x < 0) this.update(x + 128)
-})
+concat([1], [2]) //=> [1, 2]
+concat([1], 2) //=> [1, 2]
+concat(1, 2) //=> [1, 2]
+concat(new Set([1]), 2) //=> [1, 2]
-console.dir(obj)
-//=> [ 5, 6, 125, [ 7, 8, 126, 1 ], { f: 10, g: 115 } ]
+// kind of weird...
+concat(null, 2) //=> [2]
+concat(undefined, 2) //=> [2]
+concat(1, null) //=> [1, null]
```
---
+
+
+
+
+## `conditional`
+
-# Traverse.prototype.get(ps=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2225 "View in source") [Ⓣ][1]
+conditional.all(predicate=undefined, array=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L20 "View in source") [Ⓣ][1]
-(Function): Get the element at the array path.
+(Function): map all values in an array to see if all match
+Returns `true` if all elements of the list match the predicate, `false` if there are any that don't.
-### @see
+#### @see
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
+* ramda-all
+* fp/curry
-### @todos
+#### @todos
-- [ ] hasOwnProperty
+- [ ] `not(some)` ?
+
+#### @sig
+
+(a -> Boolean) -> [a] -> Boolean
+
+#### @Since
+4.0.1
+
#### Arguments
-1. `ps=undefined` *(string[])*: paths
+1. `predicate=undefined` *(Function)*: match the value
+2. `array=undefined` *(Array)*: to match against predicate
#### Returns
-*(any)*: value at dot-prop
+*(boolean)*: all match predicate
+
+#### Example
+```js
+const allBoolean = all(x => typeof x === 'boolean'q)
+
+ allBoolean([true])
+ //=> true
+ allBoolean([1])
+ //=> false
+```
---
-# Traverse.prototype.has(pathsArray=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2264 "View in source") [Ⓣ][1]
+conditional.and(left=undefined, right=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L5878 "View in source") [Ⓣ][1]
-(Function): Return whether the element at the array path exists.
+(Function): first fn & second fn
-### @see
+#### @Since
+4.0.1
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
#### Arguments
-1. `pathsArray=undefined` *(string[])*: paths
+1. `left=undefined` *(Function)*: first fn
+2. `right=undefined` *(Function)*: second fn
#### Returns
-*(boolean)*: has element at path
+*(boolean)*: both functions return truthy
#### Example
```js
-traverse({ eh: true }).has(['eh'])
+const both = and(x => typeof x === 'boolean', x => x === true)
+
+both([true])
//=> true
-```
-#### Example
-```js
-traverse({ eh: true }).has(['canada'])
+both([false])
//=> false
-```
-#### Example
-```js
-traverse([0]).has([2])
+both([1])
//=> false
```
@@ -2800,93 +4288,115 @@ traverse([0]).has([2])
-# Traverse.prototype.nodes()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2414 "View in source") [Ⓣ][1]
-
-(Function): Return an Array of every node in the object.
+conditional.not(fn=undefined, x=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L5839 "View in source") [Ⓣ][1]
-#### Returns
-*(*)*:
+(Function): return a negated function
+A function wrapping a call to the given function in a `!` operation.
+It will:
+
+* return `true` when the underlying function would return a false-y value,
+
+* and `false` when it would return a truth-y one.
----
-
+#### @Since
+4.0.1
-
+#### Arguments
+1. `fn=undefined` *(Function)*: any function
+2. `x=undefined` *(*)*: value to pass to function
-🔬 Tests: keys
+#### Returns
+*(Function): !Function(x)*
-# Traverse.prototype.paths()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2401 "View in source") [Ⓣ][1]
+#### Example
+```js
+const falsed = not(x => true)
+const trued = not(x => false)
-(Function): Return an Array of every possible non-cyclic path in the object. Paths are Arrays of string keys.
+trued()
+//=> true
-#### Returns
-*(*)*:
+falsed()
+//=> false
+```
---
-# Traverse.prototype.reduce(cb=undefined, init=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2384 "View in source") [Ⓣ][1]
+conditional.or(left=undefined, right=undefined, x=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L3178 "View in source") [Ⓣ][1]
-(Function): applies a function against an accumulator and each element in the array *(from left to right)* to reduce it to a single value. calls cb for each loop that is .notRoot defaults initial value to `this.value`
+(Function): first fn || second fn, curried
-### @see
+#### @Since
+4.0.1
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
#### Arguments
-1. `cb=undefined` *(Function)*: callback forEach
-2. `init=undefined` *(Array|Object|any)*: initial value
+1. `left=undefined` *(Function)*: first fn
+2. `right=undefined` *(Function)*: second fn
+3. `x=undefined` *(*)*: value to pass into left & right, curried
#### Returns
-*(*)*:
+*(boolean)*: one of the functions return truthy
#### Example
```js
-var { traverse } = require('chain-able')
+const { isTrue, isFalse } = require('chain-able')
-var obj = {
- a: [1, 2, 3],
- b: 4,
- c: [5, 6],
- d: { e: [7, 8], f: 9 },
-}
+const either = or(isFalse, isTrue)
+
+either([true])
+//=> true
-var leaves = traverse(obj).reduce(function(acc, x) {
- if (this.isLeaf) acc.push(x)
- return acc
-}, [])
+either([new Boolean(true)])
+//=> false
+
+either([1])
+//=> false
-console.dir(leaves)
-//=> [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
+// because curried
+or(isTrue, isFalse, true) //=> true
```
---
+
+
+
+
+## `copy`
+
-# Traverse.prototype.set(arrayPath=undefined, value=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2286 "View in source") [Ⓣ][1]
+copy(src=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L5193 "View in source") [Ⓣ][1]
-(Function): Set the element at the array path to value.
+Function
-### @see
+#### @todos
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
+- [ ] ugh, how to clone better with *recursive* objects?
+
#### Arguments
-1. `arrayPath=undefined` *(string[])*: paths
-2. `value=undefined` *(any)*: any value to assign to the element @ the path
+1. `src=undefined` *(any)*: wip
#### Returns
-*(any)*: value passed in
+*(any)*: wip
---
@@ -2896,51 +4406,40 @@ console.dir(leaves)
-## `TraverseChain.prototype`
+## `debug`
-# TraverseChain.prototype.traverse([shouldReturn=false])
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L6987 "View in source") [Ⓣ][1]
+debug([should=true])
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L9422 "View in source") [Ⓣ][1]
+
+(Function): sets on store not this.set for easier extension
-(Function): runs traverser, checks the tests, calls the onMatch
-#### Since
-1.0.0
+#### @notes
+* is inherited by any chain with a parent with .meta.debug
+
#### Arguments
-1. `[shouldReturn=false]` *(boolean)*: returns traversed object
+1. `[should=true]` *(boolean)*: shouldDebug
#### Returns
-*(any)*: this.obj/data cleaned
+*(Chainable)*: @chainable
#### Example
```js
-const traversed = new Chain()
- .merge({ flat: 0, one: { two: true } })
- .traverse(false)
- .vals([/true/])
- .onMatch((current, traverser) => {
- traverser.path.join('.')
- //=> 'one.two'
-
- current
- //=> true
-
- typeof traverser.update === typeof traverser.remove
- typeof traverser.update === 'function'
- //=> true
+const Chain = require('chain-able')
+const chain = new Chain()
+chain.debug()
- traverser.remove()
- //=> void
- })
- .onNonMatch(val => {
- // ignore
- })
- .call(true)
+chain.get('debug')
+//=> true
-traversed
-//=> {flat: 0}
+// not in entries
+chain.entries()
+//=> {}
```
---
@@ -2951,76 +4450,79 @@ traversed
-## `add`
+## `define`
-# add(methodFactory=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L5091 "View in source") [Ⓣ][1]
+define(obj=undefined, name=undefined, descriptor=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L911 "View in source") [Ⓣ][1]
-(Function): add methodFactories easily
+(Function): default to configurable and enumerable, unless configured otherwise
-#### Since
-4.0.0-beta.2
+
+#### @Since
+4.0.0
#### Arguments
-1. `methodFactory=undefined` *(Object)*: factories to add
+1. `obj=undefined` *(Object)*: object to define on
+2. `name=undefined` *(Primitive)*: property name to define
+3. `descriptor=undefined` *(Object)*: object descriptor
#### Returns
*(void)*:
#### Example
```js
-function autoGetSet(name, parent) {
- const auto = arg =>
- isUndefined(arg) ? parent.get(name) : parent.set(name, arg)
-
- //so we know if we defaulted them
- auto.autoGetSet = true
- return this.onSet(auto).onGet(auto).onCall(auto)
-}
-MethodChain.addPlugin({ autoGetSet })
-
-const chain = new Chain()
-chain.methods('eh').autoGetSet().build()
-
-chain.eh(1)
-//=> chain
-chain.eh()
-//=> 1 *
+var desc = Object.getOwnPropertyDescriptor(obj, 'eh', {
+ get: () => console.log('eh'),
+})
```
---
+
+
-# add(value=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L5620 "View in source") [Ⓣ][1]
+## `delete`
-(Function): appends a new element with a specified value to the end of the .store
+
+delete
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L10534 "View in source") [Ⓣ][1]
-### @see
+unknown
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-#### Since
-0.4.0
-#### Arguments
-1. `value=undefined` *(any)*: any value to add to **end** of the store
+#### @see
-#### Returns
-*(ChainedSet)*: @chainable
+* deps/dot
+* deps/is/dot
+
+#### @Since
+3.0.1
#### Example
```js
-const people = new ChainedSet()
-people.add('sam').add('sue')
+chain.set('moose.canada.eh', true)
+chain.set('moose.canada.igloo', true)
+//=> Chain
-for (let name of people) console.log(name)
-//=> sam, sue
+chain.delete('moose.canada.eh')
+//=> Chain
+
+chain.has('moose.canada.eh')
+//=> true
+
+//still has moose.canada.igloo
+chain.has('moose.canada')
+//=> true
```
---
@@ -3031,152 +4533,234 @@ for (let name of people) console.log(name)
-## `addTypes`
+## `dopemerge`
-🌊 Types: schema.d
+dopemerge.cloneIfNeeded(value=undefined, optsArg=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L1856 "View in source") [Ⓣ][1]
+
+(Function): Defaults to `false`.
+If `clone` is `true` then both `x` and `y` are recursively cloned as part of the merge.
-# addTypes(types=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L3323 "View in source") [Ⓣ][1]
-(Function): add custom types for validation
+#### @see
+* emptyTarget
+* isMergeableObj
-### @see
+#### @Since
+2.0.0
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
#### Arguments
-1. `types=undefined` *(Object)*: custom Types
+1. `value=undefined` *(*)*: value to clone if needed
+2. `optsArg=undefined` *(DopeMergeOptions)*: dopemerge options, could contain .clone
+
+#### Returns
+*(*)*: cloned or original value
#### Example
```js
-addTypes({ yaya: x => typeof x === 'string' })
-
-const chain = new Chain().methods('eh').type('yaya').build()
+var obj = { eh: true }
-chain.eh('good')
-//=> chain
+cloneIfNeeded(obj, { clone: true }) === obj
+//=> false
-chain.eh(!!'throws')
-//=> TypeError(false != {yaya: x => typeof x === 'string'})
+cloneIfNeeded(obj, { clone: false }) === obj
+//=> true
```
+---
+
+
+
+
+
+dopemerge.defaultArrayMerge(target=undefined, source=undefined, optsArg=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L1895 "View in source") [Ⓣ][1]
+
+(Function): The merge will also merge arrays and array values by default.
+However, there are nigh-infinite valid ways to merge arrays,
+and you may want to supply your own.
+You can do this by passing an `arrayMerge` function as an option.
+
+
+#### @Since
+2.0.0
+
+#### Arguments
+1. `target=undefined` *(*)*: array merged onto, could be emptyTarget if cloning
+2. `source=undefined` *(*)*: original source array
+3. `optsArg=undefined` *(*)*: dopemerge options
+
+#### Returns
+*(*)*: merged array
+
#### Example
```js
-const custom = {}
-custom.enums = enums => x => enums.includes(x)
-custom['*'] = x => true
-addTypes(custom)
-//-> void
+function concatMerge(destinationArray, sourceArray, options) {
+ destinationArray
+ //=> [1, 2, 3]
-new Chain().methods('eh').type('*').build().eh
-//=> validateType(custom['*'])
+ sourceArray
+ //=> [3, 2, 1]
+
+ options
+ //=> { arrayMerge: concatMerge }
+
+ return destinationArray.concat(sourceArray)
+}
+merge([1, 2, 3], [3, 2, 1], { arrayMerge: concatMerge })
+//=> [1, 2, 3, 3, 2, 1]
```
---
-
-
-## `after`
+🌊 Types: _dopemergelater.d
-
+dopemerge.dopemerge(obj1=undefined, obj2=undefined, opts=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L43 "View in source") [Ⓣ][1]
-# after(fn=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2605 "View in source") [Ⓣ][1]
+(Function): Merge the enumerable attributes of two objects deeply. Merge two objects `x` and `y` deeply, returning a new merged object with the elements from both `x` and `y`. If an element at the same key is present for both `x` and `y`, the value from
+`y` will appear in the result. Merging creates a new object, so that neither `x` or `y` are be modified. However, child objects on `x` or `y` are copied over - if you want to copy all values, you must pass `true` to the clone option.
-(Function): Call this function after any of the children are traversed.
+#### @see
+
+* deepmerge
#### Arguments
-1. `fn=undefined` *(Function)*:
+1. `obj1=undefined` *(*)*: left
+2. `obj2=undefined` *(*)*: right
+3. `opts=undefined` *(*)*: dopemerge options
+
+#### Returns
+*(*)*: merged
+
+#### Example
+```js
+var x = {
+ foo: { bar: 3 },
+ array: [
+ {
+ does: 'work',
+ too: [1, 2, 3],
+ },
+ ],
+}
+
+var y = {
+ foo: { baz: 4 },
+ quux: 5,
+ array: [
+ {
+ does: 'work',
+ too: [4, 5, 6],
+ },
+ {
+ really: 'yes',
+ },
+ ],
+}
+
+var expected = {
+ foo: {
+ bar: 3,
+ baz: 4,
+ },
+ array: [
+ {
+ does: 'work',
+ too: [1, 2, 3, 4, 5, 6],
+ },
+ {
+ really: 'yes',
+ },
+ ],
+ quux: 5,
+}
-#### Returns
-*(any)*:
+merge(x, y)
+//=> expected
+```
---
-
-
-
-
-## `alias`
-
-# alias(aliases=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L4476 "View in source") [Ⓣ][1]
-
-(Function): alias methods
+dopemerge.emptyTarget(val=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L1769 "View in source") [Ⓣ][1]
+(Function): make a new empty Array or Object for cloning
-### @notes
-* these would be .transform
-
-#### Since
+#### @Since
2.0.0
#### Arguments
-1. `aliases=undefined` *(string|string[])*: aliases to remap to the current method being built
+1. `val=undefined` *(*)*: array or object to return an empty one of
#### Returns
-*(MethodChain)*: @chainable
+*(*)*: depending on the data type of val
#### Example
```js
-const chain = new Chain()
-chain.methods(['canada']).alias(['eh']).build()
-chain.eh('actually...canada o.o')
-chain.get('canada')
-//=> 'actually...canada o.o')
+emptyTarget({ eh: true })
+//=> {}
+
+emptyTarget([1])
+//=> []
```
---
-
-
-## `allProperties`
+dopemerge.isMergeableObj(x=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L1827 "View in source") [Ⓣ][1]
-
+(Function): 1: not null object `2`: object toString is not a date or regex
-# allProperties(obj=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L4221 "View in source") [Ⓣ][1]
-(Function): properties, property symbols, object keys ^ all again for prototype
+#### @Since
+2.0.0
#### Arguments
-1. `obj=undefined` *(Object)*: object to get properties & symbols from
+1. `x=undefined` *(*)*: value to check
#### Returns
-*(*)*: properties
+*(boolean)*:
#### Example
```js
-var obj = { key: true }
-allProperties(obj)
-//=> ['key']
+isMergeableObj({})
+//=> true
-```
-#### Example
-```js
-class One {
- method() {}
-}
-class Two extends One {
- eh() {}
-}
-allProperties(new Two())
-//=> ['eh', 'method']
+isMergeableObj(Object.create(null))
+// => true
+
+isMergeableObj(new Date())
+//=> false
+
+isMergeableObj(/eh/)
+//=> false
```
---
@@ -3187,217 +4771,180 @@ allProperties(new Two())
-## `anyKeyVal`
+## `dot`
-🌊 Types: matcher.d
+dot([useDot=undefined])
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L10395 "View in source") [Ⓣ][1]
-# anyKeyVal(keys=undefined, vals=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L6898 "View in source") [Ⓣ][1]
+Function
-(Function): the original simple to-test matcher for traversable,
-will be merged into, or simplified as simplified into matcher
+#### @see
-### @todos
+* deps/meta
-- [ ] should use matcher,
-- [ ] should inprove the callback data...
-
-#### Since
-2.0.0
+#### @Since
+3.0.1
#### Arguments
-1. `keys=undefined` *(Matchable[])*: matchable keys
-2. `vals=undefined` *(Matchable[])*: matchable values
+1. `[useDot=undefined]` *(boolean)*: use dot prop or not
#### Returns
-*(boolean)*: matched or not
+*(DotProp)*: @chainable
#### Example
```js
-anyKeyVal([], [])(0, 0)
-//=> false
+const chain = new Target()
+chain.dot(false)
+chain.set('moose.simple', 1)
-anyKeyVal([() => true], [])(0, 0)
-//=> true
+toArr(chain.store.keys())
+//=> ['moose.simple']
```
---
-
-
-## `argumentor`
+dot.dot.delete(obj=undefined, path=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L10201 "View in source") [Ⓣ][1]
-
+(Function): delete a path on an object
-# argumentor()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2108 "View in source") [Ⓣ][1]
-(Function): turns arguments into an array, used as a util, for opt
+#### @extends
-### @see
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-#### Since
+
+#### @Since
3.0.0
+#### Arguments
+1. `obj=undefined` *(Object)*: the object to DELETE the nested property from.
+2. `path=undefined` *(Array|Dottable|string)*: dot-prop-path to use
+
#### Returns
-*(*)*:
+*(void)*:
#### Example
```js
-function eh() {
- const args = argumentor.apply(null, arguments).slice(1)
-
- console.log(args)
- //=> [1, 10, 100]
-}
-eh(0, 1, 10, 100)
+dot.get({ a: { b: 2 } }, 'a.b') //=> 2
+dot.get({ a: { b: 2 } }, ['a', 'b']) //=> 2
+dot.get({ c: { b: 2 } }, ['a', 'b']) //=> undefined
```
---
-
-
-
-
-## `arithmeticTypeFactory`
-
-🌊 Types: schema.d
+dot.dot.get(obj=undefined, path=undefined, fallback=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L5407 "View in source") [Ⓣ][1]
-# arithmeticTypeFactory(fullKey=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L3429 "View in source") [Ⓣ][1]
+Function
-(Function): transform arithmetic strings into types
+#### @extends
-### @see
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-### @todos
-- [ ] coercing values to certain types: arithmeticTypeFactory('')
-
-#### Since
-4.0.0-alpha.1
+#### @Since
+3.0.0
#### Arguments
-1. `fullKey=undefined` *(Matchable)*: arithmetic type key
+1. `obj=undefined` *(Object)*: the object to retrieve the nested property from.
+2. `path=undefined` *(Array|Dottable|string)*: dot-prop-path to use
+3. `fallback=undefined` *(*)*: use when there is no value at specified path
#### Returns
-*(Matchable)*: function to match with, with .inspect for easy debugging
-
-#### Example
-```js
-arithmeticTypeFactory('?string')
-//=> x => !isReal(x) || isString(x)
+*(*)*: value at path or fallback
-```
-#### Example
-```js
-arithmeticTypeFactory('?string|string[]')
-//=> x => isString(x) || isArrayOf(isString)(x)
-
-```
-#### Example
-```js
-arithmeticTypeFactory('!string')
-//=> x => not(isString)(x)
-
-```
-#### Example
-```js
-types.addTypes({ star: x => true })
-arithmeticTypeFactory('object|function|star')
-//=> x => isObj(x) || isFunction(x) || isStar(x)
-
-```
#### Example
```js
-arithmeticTypeFactory('===')
-//=> x => (['===']).includes(x)
+dot.get({ a: { b: 2 } }, 'a.b') //=> 2
+dot.get({ a: { b: 2 } }, ['a', 'b']) //=> 2
+dot.get({ c: { b: 2 } }, ['a', 'b']) //=> undefined
```
---
-
-
-## `autoIncrement`
-
-
-
-# autoIncrement(name=undefined, parent=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L4158 "View in source") [Ⓣ][1]
+dot.dot.has(obj=undefined, path=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L10152 "View in source") [Ⓣ][1]
Function
-#### Arguments
-1. `name=undefined` *(Primitive)*: method name
-2. `parent=undefined` *(Object)*: Parent
-
-#### Returns
-*(MethodChain)*: @chainable
-
----
-
-
-
-
-
+#### @extends
-## `before`
-
-# before(fn=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2597 "View in source") [Ⓣ][1]
-(Function): Call this function before any of the children are traversed.
-You can assign into this.keys here to traverse in a custom order.
+#### @Since
+3.0.0
#### Arguments
-1. `fn=undefined` *(Function)*:
+1. `obj=undefined` *(Object)*: the object to retrieve the nested property from.
+2. `path=undefined` *(Array|Dottable|string)*: dot-prop-path to use
#### Returns
-*(any)*:
+*(boolean)*: has at path
----
+#### Example
+```js
+dot.has({ a: { b: 2 } }, 'a.b') //=> true
+dot.has({ a: { b: 2 } }, ['a', 'b']) //=> true
+dot.has({ c: { b: 2 } }, ['a', 'b']) //=> undefined
-
+```
+---
-## `block`
+dot.dotPropSegments(path=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L3526 "View in source") [Ⓣ][1]
-
+Function
-# block()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2637 "View in source") [Ⓣ][1]
-Function
+#### @Since
+4.0.0
+
+#### Arguments
+1. `path=undefined` *(string|string[])*: dot-prop-path
#### Returns
-*(void)*:
+*(*)*: array path
+
+#### Example
+```js
+dotPropSegments('eh.oh') //=> ['eh', 'oh']
+dotPropSegments(['eh', 'oh']) //=> ['eh', 'oh']
+dotPropSegments('ehoh') //=> ['ehoh']
+```
---
@@ -3406,153 +4953,184 @@ Function
-## `builder`
+## `encase`
-# builder(fullKey=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L3494 "View in source") [Ⓣ][1]
+encase.encase(call=undefined, [encaser=tryCatch])
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L21 "View in source") [Ⓣ][1]
-(Function): @pattern @builder -> builds using multiple factories depending on conditons or abstractFactory whatever opinionated: if it's a function, it's a validator...
+Function
-### @see
+#### @see
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
+* lodash-attempt
+* fluture-encase
-### @notes
+#### @symb
-* if/else is for uglifying ternaries, even though else if is not needed
-* if key is number, iterating the array
-
-#### Since
+🛡
+
+#### @Since
4.0.0
#### Arguments
-1. `fullKey=undefined` *(Function|Primitive|string)*: arithmetic key to the validator
+1. `call=undefined` *(Function)*: function to _encase_
+2. `[encaser=tryCatch]` *(|Function)*: function to encase _with_
#### Returns
-*(Function)*: validator
+*(Function)*: -> FunctionObject{onInvalid, onValid, rethrow, call}
#### Example
```js
-// functionType
-const isString = x => typeof x === 'string'
-builder(isString)
-// => isString
+const throws = x => {
+ if (x === false) {
+ throw new Error('invalid - cannot be false')
+ }
+ return true
+}
+const api = encase(throws)
-```
-#### Example
-```js
-// stringType (built in, or custom-keyed validator, or eqeqeq)
-builder('string')
-// => isString
+api.onValid(console.log)
+api.onInvalid(console.error)
-const enummy = builder('enum')
-// => x => ['enum'].includes(x)
+//--- invalid
+api.call(false)
+//=> 'invalid - cannot be false'
-```
-#### Example
-```js
-// arithmeticType
-builder('string|string[]')
-// => isString || isArrayOf(isString)
+//--- valid
+api.call(true)
+//=> 'true'
```
---
-
-
-
-
-## `camelCase`
-
-# camelCase(str=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L3147 "View in source") [Ⓣ][1]
+encase.error$3(method=undefined, type=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L6609 "View in source") [Ⓣ][1]
-(Function): camelCase
+(Function): enhance an Error, enable rethrowing & better inspection
-### @see
+#### @see
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
+* MethodChain
+* validators/schemaBuilder
+* validators/validatorBuilder
+* plugins/encase
-### @todos
+#### @todos
-- [ ] s.charAt(0).toLowerCase() + string.slice(1)
+- [ ] js stringify if development
-#### Since
-0.2.0
+
+#### @Since
+4.0.0-alpha.1
#### Arguments
-1. `str=undefined` *(string)*: string to turn into camelCase
+1. `method=undefined` *(Primitive)*: method being decorated
+2. `type=undefined` *(Type)*: type to validate with
#### Returns
-*(string)*: camelCased string
+*(Function): function that returns a decorated TypeError with .inspect & metadata (arg, thrown, meta)*
#### Example
```js
-camelCase('snake_case')
-//=> 'snakeCase'
+const badValidator = x => {
+ if (x === 'bad') {
+ throw new Error('bad!')
+ }
+}
+const enhancer = enhanceError('eh', badValidator)
+
+// called by plugins/encase when throws or invalid
+let error
+let arg = 'bad'
+try {
+ error = badValidator(arg)
+} catch (e) {
+ error = enhancer(arg, e, { metadata: true })
+}
+
+console.log(error)
+//=> {[eh]: { type: badValidator, arg: 'bad', json, str, rethrow }}
+//=> console.log on DEVELOPMENT
```
---
-
-
-## `circular`
+encase.tryCatch(call=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L6673 "View in source") [Ⓣ][1]
-
+Function
-# circular
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2547 "View in source") [Ⓣ][1]
-unknown
+#### @see
----
+* https://github.com/fluture-js/Fluture#encase
-
+#### @todos
+
+- [ ] could curry
+
+#### Arguments
+1. `call=undefined` *(Function)*:
+
+#### Returns
+*(*)*: validation/encased function call result
+
+---
-## `clear`
+encase.withSpecification(specification=undefined, call=undefined, onInvalid=undefined, onInvalid=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L6549 "View in source") [Ⓣ][1]
-
+(Function): a special encased wrapper with no try catch but same api
-# clear([clearPropertiesThatAreChainLike=true])
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L505 "View in source") [Ⓣ][1]
-(Function): clears the map, goes through this properties, calls .clear if they are instanceof Chainable or Map
+#### @see
+* fp/curry
-### @see
+#### @Since
+4.0.0
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
#### Arguments
-1. `[clearPropertiesThatAreChainLike=true]` *(|boolean)*: checks properties on the object, if they are `chain-like`, clears them as well
+1. `specification=undefined` *(Function)*: match
+2. `call=undefined` *(Function)*: cb to determine valid or invalid
+3. `onInvalid=undefined` *(Function)*: cb when invalid
+4. `onInvalid=undefined` *(Function)*: cb when valid
#### Returns
-*(Chainable)*: @chainable
+*(Function)*: a lot of functions...
#### Example
```js
-const chain = new Chain()
-chain.set('eh', 1)
-chain.entries()
-//=> {eh: 1}
-chain.clear()
-chain.entries()
-//=> {}
+const onInvalid = console.error
+const onValid = console.debug
+const onCall = console.log
+const encased = withSpecification(x => true)(onCall)(onValid, onInvalid)
+
+encased(1, 2, 3) //=> onCall (did not throw)
```
---
@@ -3563,73 +5141,85 @@ chain.entries()
-## `compose.prototype`
+## `entries`
-🌊 Types: compose.d
+entries(reduced=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2246 "View in source") [Ⓣ][1]
-🔬 Tests: compose
+(Function): recursively reduce maps and objects that include reducable data
-# compose.prototype.compose([target=ChainedMap], [extensions=[Observe,Shorthands,Transform,DotProp]])
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L7603 "View in source") [Ⓣ][1]
-(Function): compose chains all the way up from Chainable
+#### @see
+
+* https://www.airpair.com/javascript/javascript-array-reduce
+* ChainedMap
+#### @notes
-### @see
+* could curry, but this is super hot function
+
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
+#### @sig
-### @symb
+reduced => object => isMap(object) -> reduced; merge(object, reduced)
-🎼
-#### Since
-3.0.0
+#### @Since
+4.0.0
#### Arguments
-1. `[target=ChainedMap]` *(|Class|Function)*: class or function to extend
-2. `[extensions=[Observe,Shorthands,Transform,DotProp]]` *(|Array)*: Array of extensions to compose together left ro right
+1. `reduced=undefined` *(Object|any)*: merged object and reduced
#### Returns
-*(*)*: composed
-
-#### Example
-```js
-class Eh extends compose() {}
-new Eh() instanceof Chainable
-//=> true
-
-```
-#### Example
-```js
-class Target {}
-class Eh extends compose(Target) {}
-new Eh() instanceof Target
-//=> true
+*(Function): Function(values: Object)*
-```
#### Example
```js
-class Target {}
-const mixin = SuperClass => class extends SuperClass {}
-class Eh extends compose(Target) {}
-new Eh() instanceof Chainable
-//=> true
+const map = new Map()
+ map.set('eh', true)
+ const nested = new Map()
+ nested.set('reduced', true)
+ const chain = {
+ entries() {
+ return {
+ nested: reduce(nested),
+ key: true,
+ }
+ },
+ }
+ const reduced = reduce(map)
+ reduceEntries(reduced)({chain})
+ // => {
+ eh: true,
+ chain: {
+ nested: {
+ reduced: true,
+ key: true,
+ },
+ },
+ }
```
#### Example
```js
-class Winning {}
-class Yes extends compose(Winning) {
- get winning() {
- return true
+const reducedIgnored = {
+ canada: {
+ store: chain,
+ },
+ }
+ const ignored = reduceEntries(reduced)(reducedIgnored)
+ //=> {
+ eh: true,
+ chain: {
+ nested: {
+ reduced: true,
+ },
+ key: true,
+ },
}
-}
-const yes = new Yes()
-yes instanceof Winning && yes.winning
-//=> true
-
```
---
@@ -3639,67 +5229,75 @@ yes instanceof Winning && yes.winning
-## `conditional.prototype`
+## `fp`
-# conditional.prototype.all(predicate=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L3241 "View in source") [Ⓣ][1]
-
-(Function): map all values in an array to see if all match
-
-#### Since
-4.0.1
-
-#### Arguments
-1. `predicate=undefined` *(Function)*: match the value
+🌊 Types: fp.d
-#### Returns
-*(boolean)*: all match predicate
+🔬 Tests: curry
-#### Example
-```js
-const allBoolean = all(x => typeof x === 'boolean'q)
+fp._curryN(length=undefined, received=undefined, fn=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L43 "View in source") [Ⓣ][1]
- allBoolean([true])
- //=> true
+(Function): Returns a curried equivalent of the provided function, with the specified
+arity. The curried function has two unusual capabilities. First, its
+arguments needn't be provided one at a time. If `g` is `R.curryN(3, f)`, the
+following are equivalent:
+
+
+ * `g(1)(2)(3)`
+ * `g(1)(2, 3)`
+ * `g(1, 2)(3)`
+ * `g(1, 2, 3)`
+
+
+Secondly, the special placeholder value [`R.__`](#__) may be used to specify
+"gaps", allowing partial application of any combination of arguments,
+regardless of their positions. If `g` is as above and `_` is [`R.__`](#__),
+the following are equivalent:
+
+
+ * `g(1, 2, 3)`
+ * `g(_, 2, 3)(1)`
+ * `g(_, _, 3)(1)(2)`
+ * `g(_, _, 3)(1, 2)`
+ * `g(_, 2)(1)(3)`
+ * `g(_, 2)(1, 3)`
+ * `g(_, 2)(_, 3)(1)`
- allBoolean([1])
- //=> false
-```
----
-
+#### @see
-
+* ramda-curry
+* lodash-curry
+* ramda-uncurry
-# conditional.prototype.and(left=undefined, right=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L3197 "View in source") [Ⓣ][1]
+#### @sig
-(Function): first fn & second fn
+Number -> (* -> a) -> (* -> a)
-#### Since
-4.0.1
+#### @Since
+5.0.0-beta.1
#### Arguments
-1. `left=undefined` *(Function)*: first fn
-2. `right=undefined` *(Function)*: second fn
+1. `length=undefined` *(Number)*: The arity of the curried function.
+2. `received=undefined` *(Array)*: An array of arguments received thus far.
+3. `fn=undefined` *(Function)*: The function to curry.
#### Returns
-*(boolean)*: both functions return truthy
+*(Function)*: A new, curried function.
#### Example
```js
-const both = and(x => typeof x === 'boolean', x => x === true)
-
-both([true])
-//=> true
+var sumArgs = (...args) => R.sum(args)
-both([false])
-//=> false
-
-both([1])
-//=> false
+var curriedAddFourNumbers = R.curryN(4, sumArgs)
+var f = curriedAddFourNumbers(1, 2)
+var g = f(3)
+g(4) //=> 10
```
---
@@ -3708,183 +5306,222 @@ both([1])
-# conditional.prototype.not(fn=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L3173 "View in source") [Ⓣ][1]
-
-(Function): return a negated function
-
-#### Since
-4.0.1
-
-#### Arguments
-1. `fn=undefined` *(Function)*: any function
-
-#### Returns
-*(Function)*: !Function
-
-#### Example
-```js
-const falsed = not(x => true)
-const trued = not(x => false)
-
-trued()
-//=> true
+fp.curry(length=undefined, fn=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L470 "View in source") [Ⓣ][1]
-falsed()
-//=> false
+(Function): Returns a curried equivalent of the provided function, with the specified
+arity. The curried function has two unusual capabilities. First, its
+arguments needn't be provided one at a time. If `g` is `R.curryN(3, f)`, the
+following are equivalent:
+
+
+ * `g(1)(2)(3)`
+ * `g(1)(2, 3)`
+ * `g(1, 2)(3)`
+ * `g(1, 2, 3)`
+
+
+Secondly, the special placeholder value [`R.__`](#__) may be used to specify
+"gaps", allowing partial application of any combination of arguments,
+regardless of their positions. If `g` is as above and `_` is [`R.__`](#__),
+the following are equivalent:
+
+
+ * `g(1, 2, 3)`
+ * `g(_, 2, 3)(1)`
+ * `g(_, _, 3)(1)(2)`
+ * `g(_, _, 3)(1, 2)`
+ * `g(_, 2)(1)(3)`
+ * `g(_, 2)(1, 3)`
+ * `g(_, 2)(_, 3)(1)`
-```
----
-
+#### @see
-
+* ramda
-# conditional.prototype.or(left=undefined, right=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L3221 "View in source") [Ⓣ][1]
+#### @sig
-(Function): first fn || second fn
+Number -> (* -> a) -> (* -> a)
-#### Since
-4.0.1
+#### @Since
+v0.5.0
#### Arguments
-1. `left=undefined` *(Function)*: first fn
-2. `right=undefined` *(Function)*: second fn
+1. `length=undefined` *(Number)*: The arity for the returned function.
+2. `fn=undefined` *(Function)*: The function to curry.
#### Returns
-*(boolean)*: one of the functions return truthy
+*(Function)*: A new, curried function.
#### Example
```js
-const either = or(x => x === false, x => x === true)
-
-either([true])
-//=> true
-
-either([new Boolean(true)])
-//=> false
+var sumArgs = (...args) => R.sum(args)
-either([1])
-//=> false
+var curriedAddFourNumbers = R.curryN(4, sumArgs)
+var f = curriedAddFourNumbers(1, 2)
+var g = f(3)
+g(4) //=> 10
```
---
-
-
-## `debug`
+🌊 Types: fp.d
-
+🔬 Tests: always
-# debug([should=true])
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L6718 "View in source") [Ⓣ][1]
+fp./* ___filename___(value=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L21 "View in source") [Ⓣ][1]
-(Function): sets on store not this.set for easier extension
+(Function): Returns a function that always returns the given value. Note that for
+non-primitives the value returned is a reference to the original value.
+
+
+This function is known as `const`, `constant`, or `K` *(for K combinator)* in
+other languages and libraries.
-### @notes
+#### @see
+
+* ramda-constant-docs-issue
+* ramda-always
+* lodash-constant
+* underscore-constant
+
+#### @sig
+
+a -> (* -> a)
+
+#### @Since
+v5.0.0
-* is inherited by any chain with a parent with .meta.debug
-
#### Arguments
-1. `[should=true]` *(boolean)*: shouldDebug
+1. `value=undefined` *(*)*: The value to wrap in a function
#### Returns
-*(Chainable)*: @chainable
+*(Function)*: A Function :: * -> val.
#### Example
-```js
-const Chain = require('chain-able')
-const chain = new Chain()
-chain.debug()
-
-chain.get('debug')
-//=> true
-
-// not in entries
-chain.entries()
-//=> {}
+```js
+var t = always('Tee')
+t() //=> 'Tee'
```
---
-
-
-## `define`
+🌊 Types: fp.d
-
+fp.prop(p=undefined, obj=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L3484 "View in source") [Ⓣ][1]
-# define(obj=undefined, name=undefined, descriptor=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L281 "View in source") [Ⓣ][1]
+(Function): Returns a function that when supplied an object returns the indicated
+property of that object, if it exists.
-(Function): default to configurable and enumerable, unless configured otherwise
-#### Since
-4.0.0
+#### @sig
+
+s -> {s: a} -> a | Undefined
+
+#### @Since
+v5.0.0
#### Arguments
-1. `obj=undefined` *(Object)*: object to define on
-2. `name=undefined` *(Primitive)*: property name to define
-3. `descriptor=undefined` *(Object)*: object descriptor
+1. `p=undefined` *(String)*: The property name
+2. `obj=undefined` *(Object)*: The object to query
#### Returns
-*(void)*:
+*(*)*: The value at `obj.p`.
#### Example
```js
-var desc = Object.getOwnPropertyDescriptor(obj, 'eh', {
- get: () => console.log('eh'),
-})
+R.prop('x', { x: 100 }) //=> 100
+R.prop('x', {}) //=> undefined
```
---
-
-
-## `delete`
+fp.constructN(n=undefined, Klass=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L45 "View in source") [Ⓣ][1]
-
+(Function): Wraps a constructor function inside a curried function that can be called
+with the same arguments and returns the same type. The arity of the function
+returned is specified to allow using variadic constructor functions.
-# delete(key=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L545 "View in source") [Ⓣ][1]
-(Function): calls .delete on this.store.map
+#### @see
+* ramda-construct
+* isNumberPrimitive
-### @see
+#### @sig
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-#### Since
-0.3.0
+Number -> (* -> {*}) -> (* -> {*})
+
+#### @symb
+
+👷
+
+#### @extends
+
+* undefined
+* undefined
+
+
+
+#### @Since
+5.0.0-beta.4
#### Arguments
-1. `key=undefined` *(Primitive)*: on a Map: key referencing the value. on a Set: the index
+1. `n=undefined` *(number): The arity of the constructor function. *(aka, number of args)**
+2. `Klass=undefined` *(Function): The constructor function to wrap. *(class to do `new Klass` on)**
#### Returns
-*(Chainable)*:
+*(Function)*: A wrapped, curried constructor function.
#### Example
```js
-const chain = new Chain()
-chain.set('eh', 1)
-chain.get('eh')
-// => 1
-chain.delete('eh', 1)
-chain.get('eh')
-// => undefined
+// Variadic Constructor function
+function Salad() {
+ this.ingredients = arguments
+}
+
+Salad.prototype.recipe = function() {
+ var instructions = R.map(
+ ingredient => 'Add a dollop of ' + ingredient,
+ this.ingredients
+ )
+ return R.join('\n', instructions)
+}
+
+var ThreeLayerSalad = R.constructN(3, Salad)
+
+// Notice we no longer need the 'new' keyword, and the constructor is curried for 3 arguments.
+var salad = ThreeLayerSalad('Mayonnaise')('Potato Chips')('Ketchup')
+
+console.log(salad.recipe())
+// Add a dollop of Mayonnaise
+// Add a dollop of Potato Chips
+// Add a dollop of Ketchup
```
---
@@ -3893,93 +5530,90 @@ chain.get('eh')
-# delete(stopHere=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2568 "View in source") [Ⓣ][1]
+🌊 Types: fp.d
-(Function): Delete the current element from its parent in the output. Calls delete even on Arrays.
+🔬 Tests: replace
-#### Arguments
-1. `stopHere=undefined` *(boolean)*:
+fp.replace(pattern=undefined, replacement=undefined, str=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L21 "View in source") [Ⓣ][1]
-#### Returns
-*(void)*:
+(Function): Replace a substring or regex match in a string with a replacement.
----
-
+#### @see
-
+* ramda-replace
+* lodash-replace
-# delete
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L7534 "View in source") [Ⓣ][1]
+#### @sig
-unknown
+RegExp|String -> String -> String -> String
+#### @Since
+v5.0.0
-### @see
+#### Arguments
+1. `pattern=undefined` *(RegExp|String)*: A regular expression or a substring to match.
+2. `replacement=undefined` *(String)*: The string to replace the matches with.
+3. `str=undefined` *(String)*: The String to do the search and replacement in.
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-#### Since
-3.0.1
+#### Returns
+*(String)*: The result.
#### Example
```js
-chain.set('moose.canada.eh', true)
-chain.set('moose.canada.igloo', true)
-//=> Chain
-
-chain.delete('moose.canada.eh')
-//=> Chain
-
-chain.has('moose.canada.eh')
-//=> true
+replace('foo', 'bar', 'foo foo foo') //=> 'bar foo foo'
+replace(/foo/, 'bar', 'foo foo foo') //=> 'bar foo foo'
-//still has moose.canada.igloo
-chain.has('moose.canada')
-//=> true
+// Use the "g" (global) flag to replace all occurrences:
+replace(/foo/g, 'bar', 'foo foo foo') //=> 'bar bar bar'
```
---
-
-
-## `dopemerge.prototype`
+🌊 Types: fp.d
-
+🔬 Tests: pipe
+
+fp.pipeTwo(f=undefined, g=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L8903 "View in source") [Ⓣ][1]
-# dopemerge.prototype.cloneIfNeeded(value=undefined, optsArg=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L1085 "View in source") [Ⓣ][1]
+(Function): Performs left-to-right function composition. ONLY CAN PIPE `2` ARGUMENTS
-(Function): Defaults to `false`.
-If `clone` is `true` then both `x` and `y` are recursively cloned as part of the merge.
+#### @see
-### @see
+* https://github.com/ramda/ramda/blob/master/src/pipe.js
+* https://github.com/ramda/ramda/blob/master/test/pipe.js
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-#### Since
-2.0.0
+#### @notes
+
+* The result of pipe is not automatically curried.
+* This is a variation, is the internal version with only 2 functions, for now
+
+
+#### @Since
+v5.0.0
#### Arguments
-1. `value=undefined` *(*)*: value to clone if needed
-2. `optsArg=undefined` *(DopeMergeOptions)*: dopemerge options, could contain .clone
+1. `f=undefined` *(...Function)*: function first
+2. `g=undefined` *(...Function)*: function next
#### Returns
-*(*)*: cloned or original value
+*(Function)*:
#### Example
```js
-var obj = { eh: true }
-
-cloneIfNeeded(obj, { clone: true }) === obj
-//=> false
-
-cloneIfNeeded(obj, { clone: false }) === obj
-//=> true
+var f = R.pipe(Math.pow, R.negate)
+f(3, 4) // -(3^4) + 1
```
---
@@ -3988,41 +5622,65 @@ cloneIfNeeded(obj, { clone: false }) === obj
-# dopemerge.prototype.defaultArrayMerge(target=undefined, source=undefined, optsArg=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L1124 "View in source") [Ⓣ][1]
+🌊 Types: fp.d
-(Function): The merge will also merge arrays and array values by default.
-However, there are nigh-infinite valid ways to merge arrays,
-and you may want to supply your own.
-You can do this by passing an `arrayMerge` function as an option.
+🔬 Tests: pipe
-#### Since
-2.0.0
+fp.pipe(first=undefined, rest=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L9586 "View in source") [Ⓣ][1]
+
+(Function): Performs left-to-right function composition. The leftmost function may have
+any arity; the remaining functions must be unary.
+In some libraries this function is named `sequence`.
+
+
+#### @see
+
+* R.compose
+* https://github.com/ramda/ramda/blob/master/src/pipe.js
+* https://github.com/ramda/ramda/blob/master/test/pipe.js
+
+#### @sig
+
+(((a, b, ..., n) -> o), (o -> p), ..., (x -> y), (y -> z)) -> ((a, b, ..., n) -> z)
+
+#### @symb
+
+R.pipe(f, g, h)(a, b) = h(g(f(a, b)))
+
+#### @extends
+
+
+
+
+#### @Since
+v5.0.0
#### Arguments
-1. `target=undefined` *(*)*: array merged onto, could be emptyTarget if cloning
-2. `source=undefined` *(*)*: original source array
-3. `optsArg=undefined` *(*)*: dopemerge options
+1. `first=undefined` *(Function)*: function first
+2. `rest=undefined` *(...Function)*: function next
#### Returns
-*(*)*: merged array
+*(Function)*:
#### Example
```js
-function concatMerge(destinationArray, sourceArray, options) {
- destinationArray
- //=> [1, 2, 3]
+var f = R.pipe(Math.pow, R.negate, R.inc)
+f(3, 4) // -(3^4) + 1
- sourceArray
- //=> [3, 2, 1]
-
- options
- //=> { arrayMerge: concatMerge }
+```
+#### Example
+```js
+var x = v => v + 'x'
+var y = v => v + 'y'
+var z = v => v + 'z'
- return destinationArray.concat(sourceArray)
-}
-merge([1, 2, 3], [3, 2, 1], { arrayMerge: concatMerge })
-//=> [1, 2, 3, 3, 2, 1]
+const xyz = pipe(x, y, z)
+/// starts with w, adds x, then y, then z
+const wxyz = xyz('w')
+//=> 'wxyz'
```
---
@@ -4031,72 +5689,38 @@ merge([1, 2, 3], [3, 2, 1], { arrayMerge: concatMerge })
-🌊 Types: _dopemergelater.d
+fp.arity(n=undefined, fn=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L14 "View in source") [Ⓣ][1]
-# dopemerge.prototype.dopemerge(obj1=undefined, obj2=undefined, opts=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L67 "View in source") [Ⓣ][1]
+(Function): just for `.length` of a function?
-(Function): Merge the enumerable attributes of two objects deeply. Merge two objects `x` and `y` deeply, returning a new merged object with the elements from both `x` and `y`. If an element at the same key is present for both `x` and `y`, the value from
-`y` will appear in the result. Merging creates a new object, so that neither `x` or `y` are be modified. However, child objects on `x` or `y` are copied over - if you want to copy all values, you must pass `true` to the clone option.
+#### @see
+
+* mozilla-func-arity
+
+#### @todos
+
+- [ ] keeping this means change uglify...
+
-### @see
+#### @Since
+5.0.0
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
#### Arguments
-1. `obj1=undefined` *(*)*: left
-2. `obj2=undefined` *(*)*: right
-3. `opts=undefined` *(*)*: dopemerge options
+1. `n=undefined` *(number)*: number of arguments
+2. `fn=undefined` *(Function)*: function to wrap
#### Returns
-*(*)*: merged
+*(Function)*: function with params
#### Example
```js
-var x = {
- foo: { bar: 3 },
- array: [
- {
- does: 'work',
- too: [1, 2, 3],
- },
- ],
-}
-
-var y = {
- foo: { baz: 4 },
- quux: 5,
- array: [
- {
- does: 'work',
- too: [4, 5, 6],
- },
- {
- really: 'yes',
- },
- ],
-}
-
-var expected = {
- foo: {
- bar: 3,
- baz: 4,
- },
- array: [
- {
- does: 'work',
- too: [1, 2, 3, 4, 5, 6],
- },
- {
- really: 'yes',
- },
- ],
- quux: 5,
-}
-
-merge(x, y)
-//=> expected
-
+const wan = one => console.log(one)
+ arity(1, wan)
+ => function(one => wan(one))
```
---
@@ -4104,64 +5728,89 @@ merge(x, y)
-# dopemerge.prototype.emptyTarget(val=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L1056 "View in source") [Ⓣ][1]
+fp.mapWhere(obj=undefined, predicate=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L10676 "View in source") [Ⓣ][1]
-(Function): make a new empty Array or Object for cloning
+(Function): Creates an array of values by running each property of `object` thru
+`iteratee`. The iteratee is invoked with three arguments: *(value, key, object)*.
-#### Since
-2.0.0
+
+#### @see
+
+* https://github.com/lodash/lodash/blob/master/map.js
+
+#### @Since
+5.0.0
#### Arguments
-1. `val=undefined` *(*)*: array or object to return an empty one of
+1. `obj=undefined` *(Object)*: The object to iterate over.
+2. `predicate=undefined` *(Function)*: The function invoked per iteration.
#### Returns
-*(*)*: depending on the data type of val
+*(Array)*: Returns the new mapped array.
#### Example
```js
-emptyTarget({ eh: true })
-//=> {}
-
-emptyTarget([1])
-//=> []
+const square = n => n * n
+map({ a: 4, b: 8 }, square)
+// => [16, 64] (iteration order is not guaranteed)
```
---
+
+
-# dopemerge.prototype.isMergeableObj(x=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L1036 "View in source") [Ⓣ][1]
+## `from`
-(Function): 1: not null object `2`: object toString is not a date or regex
+
-#### Since
-2.0.0
+from
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2087 "View in source") [Ⓣ][1]
-#### Arguments
-1. `x=undefined` *(*)*: value to check
+unknown
-#### Returns
-*(boolean)*:
-#### Example
-```js
-isMergeableObj({})
-//=> true
+#### @see
-isMergeableObj(Object.create(null))
-// => true
+* https://github.com/lodash/lodash/blob/master/.internal/setToArray.js
+---
-isMergeableObj(new Date())
-//=> false
+
-isMergeableObj(/eh/)
-//=> false
+
+
+
+
+## `get`
+
+
+
+get(key=undefined, [prop=undefined])
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2557 "View in source") [Ⓣ][1]
+
+Function
+
+
+#### @Since
+4.0.0
+
+#### Arguments
+1. `key=undefined` *(Primitive)*:
+2. `[prop=undefined]` *(|Primitive)*:
+
+#### Returns
+*(any)*:
-```
---
@@ -4170,38 +5819,27 @@ isMergeableObj(/eh/)
-## `dot`
+## `getMeta`
-# dot([useDot=undefined])
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L7395 "View in source") [Ⓣ][1]
+
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2510 "View in source") [Ⓣ][1]
Function
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-#### Since
-3.0.1
+#### @Since
+4.0.0
#### Arguments
-1. `[useDot=undefined]` *(boolean)*: use dot prop or not
+1. `_this=undefined` *(Chain)*:
#### Returns
-*(DotProp)*: @chainable
-
-#### Example
-```js
-const chain = new Target()
-chain.dot(false)
-chain.set('moose.simple', 1)
-
-toArr(chain.store.keys())
-//=> ['moose.simple']
+*(Chain)*:
-```
---
@@ -4210,106 +5848,76 @@ toArr(chain.store.keys())
-## `encase`
+## `has`
-# encase(call=undefined, [encaser=tryCatch])
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L3907 "View in source") [Ⓣ][1]
+has(key=undefined, [prop=undefined])
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2547 "View in source") [Ⓣ][1]
Function
-#### Since
+
+#### @Since
4.0.0
#### Arguments
-1. `call=undefined` *(Function)*: function to _encase_
-2. `[encaser=tryCatch]` *(|Function)*: function to encase _with_
+1. `key=undefined` *(Primitive)*:
+2. `[prop=undefined]` *(|Primitive)*:
#### Returns
-*(Function)*: -> FunctionObject{onInvalid, onValid, rethrow, call}
-
-#### Example
-```js
-const throws = x => {
- if (x === false) {
- throw new Error('invalid - cannot be false')
- }
- return true
-}
-const api = encase(throws)
-
-api.onValid(console.log)
-api.onInvalid(console.error)
-
-//--- invalid
-api.call(false)
-//=> 'invalid - cannot be false'
-
-//--- valid
-api.call(true)
-//=> 'true'
+*(boolean)*:
-```
---
-
-
-## `encase.prototype`
+has
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L10501 "View in source") [Ⓣ][1]
-
+unknown
-# encase.prototype.error$3(method=undefined, type=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L3805 "View in source") [Ⓣ][1]
-(Function): enhance an Error, enable rethrowing & better inspection
+#### @see
+* deps/dot
+* deps/is/dot
+
+#### @Since
+3.0.1
-### @see
+#### Example
+```js
+chain.set('one.two', 3)
+chain.has('one.two')
+//=> true
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
+```
+---
-### @todos
+
-- [ ] js stringify if development
-
-#### Since
-4.0.0-alpha.1
+
-#### Arguments
-1. `method=undefined` *(Primitive)*: method being decorated
-2. `type=undefined` *(Type)*: type to validate with
+
-#### Returns
-*(Function): function that returns a decorated TypeError with .inspect & metadata (arg, thrown, meta)*
+## `if`
-#### Example
-```js
-const badValidator = x => {
- if (x === 'bad') {
- throw new Error('bad!')
- }
-}
-const enhancer = enhanceError('eh', badValidator)
+
-// called by plugins/encase when throws or invalid
-let error
-let arg = 'bad'
-try {
- error = badValidator(arg)
-} catch (e) {
- error = enhancer(arg, e, { metadata: true })
-}
+if()
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L7430 "View in source") [Ⓣ][1]
-console.log(error)
-//=> {[eh]: { type: badValidator, arg: 'bad', json, str, rethrow }}
-//=> console.log on DEVELOPMENT
+(Function): this is a plugin for building methods schema defaults value to `.type` this defaults values to `.onCall`
-```
---
@@ -4318,31 +5926,40 @@ console.log(error)
-## `end`
+## `includes`
-# end()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L433 "View in source") [Ⓣ][1]
+includes.includes(haystack=undefined, needle=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L19 "View in source") [Ⓣ][1]
-(Function): for ending nested chains
+Function
-### @see
+#### @see
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-#### Since
-0.4.0
+* mozilla-bitwise-not
+* conditional/includes/flipped
+
+#### @todos
+
+- [ ] `~haystack.indexOf(needle)`
+
+#### Arguments
+1. `haystack=undefined` *(Array|string)*: haystack includes needle
+2. `needle=undefined` *(*|string)*: needle in haystack
#### Returns
-*(*)*:
+*(boolean)*: needle in haystack
#### Example
```js
-const parent = 'eh'
-const child = newChain(parent)
-child.end()
-//=> 'eh'
+includes('eh', 'e') //=> true
+includes('eh', 'nope') //=> false
+includes(['eh'], 'eh') //=> true
+includes(['eh'], 'nope') //=> false
```
---
@@ -4353,167 +5970,120 @@ child.end()
-## `entries`
+## `index`
-# entries(reduced=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L1413 "View in source") [Ⓣ][1]
-
-(Function): recursively reduce maps and objects that include reducable data
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-
-### @sig
+compose
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L1399 "View in source") [Ⓣ][1]
-reduced => object => isMap(object) -> reduced; merge(object, reduced)
-#### Since
-4.0.0
+unknown
-#### Arguments
-1. `reduced=undefined` *(Object|any)*: merged object and reduced
-#### Returns
-*(Function): Function(values: Object)*
+#### @Since
+3.0.0
#### Example
```js
-const map = new Map()
- map.set('eh', true)
- const nested = new Map()
- nested.set('reduced', true)
+class Target {}
+const TargetChain = Chainable.compose(Target)
+const chain = new TargetChain()
+chain instanceof Target
+//=> true
- const chain = {
- entries() {
- return {
- nested: reduce(nested),
- key: true,
- }
- },
- }
- const reduced = reduce(map)
- reduceEntries(reduced)({chain})
- // => {
- eh: true,
- chain: {
- nested: {
- reduced: true,
- key: true,
- },
- },
- }
-```
-#### Example
-```js
-const reducedIgnored = {
- canada: {
- store: chain,
- },
- }
- const ignored = reduceEntries(reduced)(reducedIgnored)
- //=> {
- eh: true,
- chain: {
- nested: {
- reduced: true,
- },
- key: true,
- },
- }
```
---
-
-
-## `forEach`
+
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2371 "View in source") [Ⓣ][1]
+
+unknown
+
+---
+
+
-# forEach()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2793 "View in source") [Ⓣ][1]
+
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2521 "View in source") [Ⓣ][1]
-(Function): adds methods to Traverser
+unknown
---
-
-
-## `from`
+
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L19 "View in source") [Ⓣ][1]
+
+unknown
+
+---
+
+
-# from
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L1312 "View in source") [Ⓣ][1]
+
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2 "View in source") [Ⓣ][1]
unknown
-### @see
+#### @todos
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
+- [ ] clarify .set vs .call
+
---
-
-
-
-
-## `get`
-
-# get(key=undefined, [prop=undefined])
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L1611 "View in source") [Ⓣ][1]
-
-Function
+
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L9323 "View in source") [Ⓣ][1]
-#### Since
-4.0.0
+unknown
-#### Arguments
-1. `key=undefined` *(Primitive)*:
-2. `[prop=undefined]` *(|Primitive)*:
-#### Returns
-*(any)*:
+#### @Since
+2.0.0
---
-
-
-
-
-## `getMeta`
-
-
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L1564 "View in source") [Ⓣ][1]
-
-Function
+
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L10286 "View in source") [Ⓣ][1]
-#### Since
-4.0.0
+unknown
-#### Arguments
-1. `_this=undefined` *(Chain)*:
-#### Returns
-*(Chain)*:
+#### @Since
+2.0.0
---
@@ -4523,35 +6093,45 @@ Function
-## `has`
+## `is`
+
+
+
+is.empty(x=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L3064 "View in source") [Ⓣ][1]
+
+(Function): Returns `true` if the given value is its type's empty value;
+`false` otherwise.
-
-# has(keyOrValue=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L565 "View in source") [Ⓣ][1]
+#### @see
-Function
+* empty
+* https://github.com/ramda/ramda/issues/1228
+#### @sig
-### @see
+a -> Boolean
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-#### Since
-0.3.0
+#### @Since
+v0.1.0
#### Arguments
-1. `keyOrValue=undefined` *(any)*: key when Map, value when Set
+1. `x=undefined` *(*)*: value to check if empty
#### Returns
*(boolean)*:
#### Example
```js
-const chain = new Chain()
-chain.set('eh', 1).has('eh')
-//=> true
-chain.has('canada')
-//=> false
+isEmpty([1, 2, 3]) //=> false
+isEmpty([]) //=> true
+isEmpty('') //=> true
+isEmpty(null) //=> false
+isEmpty({}) //=> true
+isEmpty({ length: 0 }) //=> false
```
---
@@ -4560,90 +6140,116 @@ chain.has('canada')
-# has(key=undefined, [prop=undefined])
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L1601 "View in source") [Ⓣ][1]
+is.arrayOf(predicate=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L5950 "View in source") [Ⓣ][1]
+
+(Function): every item in an array matches predicate
-Function
-#### Since
-4.0.0
+#### @Since
+4.0.0 was in validatorBuilder
#### Arguments
-1. `key=undefined` *(Primitive)*:
-2. `[prop=undefined]` *(|Primitive)*:
+1. `predicate=undefined` *(Function)*: test to pass on every item in an array
#### Returns
-*(boolean)*:
+*(boolean)*: all match predicate
+
+#### Example
+```js
+isArrayOf(isTrue)([true, true]) //=> true
+isArrayOf(isEmpty)(['']) //=> true
+isArrayOf(isBoolean)([true, false, 1, 2, 0]) //=> false
+isArrayOf(isString)(['string', Number]) //=> false
+
+```
---
-# has
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L7501 "View in source") [Ⓣ][1]
+is.exports(obj=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L646 "View in source") [Ⓣ][1]
-unknown
+(Function): The base implementation of `getTag` without fallbacks for buggy environments.
-### @see
+#### @see
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-#### Since
-3.0.1
+* https://github.com/lodash/lodash/blob/master/.internal/baseGetTag.js
+* https://github.com/jonschlinkert/kind-of
+* https://github.com/substack/js-traverse/blob/master/index.js#L285
+* http://luxiyalu.com/object-prototype-tostring-call/
+
+#### @todos
+
+- [ ] obj[Symbol.toStringTag]
+- [ ] run deopt check on this invoking see how many invocations... are needed to inline
+
+
+#### @Since
+3.0.0
+
+#### Arguments
+1. `obj=undefined` *(*)*: The value to `Object.prototype.toString.call(obj)`.
+
+#### Returns
+*(string)*: Returns the `toStringTag`.
#### Example
```js
-chain.set('one.two', 3)
-chain.has('one.two')
-//=> true
+toS({})
+//=> '[object Object]'
+
+toS(function() {})
+//=> '[Object Function]'
+
+getTag([])
+//=> '[object Array]'
```
---
-
-
-## `if`
-
-
-
-# if()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L4536 "View in source") [Ⓣ][1]
-
-(Function): this is a plugin for building methods schema defaults value to `.type` this defaults values to `.onCall`
+is.hasIn(obj=undefined, prop=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L521 "View in source") [Ⓣ][1]
----
+(Function): isIn, but first checks it is not null
-
-
+#### @extends
-
+* undefined
+* undefined
-## `index`
-
-# compose
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L711 "View in source") [Ⓣ][1]
+#### @Since
+5.0.0
-unknown
+#### Arguments
+1. `obj=undefined` *(Object)*: object to check
+2. `prop=undefined` *(any)*: property to check in object
-#### Since
-3.0.0
+#### Returns
+*(boolean)*:
#### Example
```js
-class Target {}
-const TargetChain = Chainable.compose(Target)
-const chain = new TargetChain()
-chain instanceof Target
-//=> true
+hasIn({}, 'eh') //=> false
+hasIn(null, 'eh') //=> false
+hasIn({ eh: true }, 'eh') //=> true
```
---
@@ -4652,21 +6258,31 @@ chain instanceof Target
-
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L1524 "View in source") [Ⓣ][1]
+is.isArray(arg=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L8 "View in source") [Ⓣ][1]
-unknown
+Function
----
-
+#### @see
-
+* mozilla-isarray
-
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L1575 "View in source") [Ⓣ][1]
+#### @todos
-unknown
+- [ ] is-arraylike https://github.com/facebook/immutable-js/blob/master/src/utils/isArrayLike.js
+
+
+#### @Since
+3.0.0
+
+#### Arguments
+1. `arg=undefined` *(*)*:
+
+#### Returns
+*(boolean): isArray(arg)*
---
@@ -4674,145 +6290,173 @@ unknown
-# walk(root=undefined, cb=undefined, immutable=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2480 "View in source") [Ⓣ][1]
+is.async(x=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L3204 "View in source") [Ⓣ][1]
Function
-### @see
+#### @see
+
+* is/toS
+
+#### @Since
+4.0.0-beta.2
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
#### Arguments
-1. `root=undefined` *(any)*: root node
-2. `cb=undefined` *(Function)*: callback for each
-3. `immutable=undefined` *(boolean)*: should mutate or not
+1. `x=undefined` *(*)*: value
#### Returns
-*(any)*:
+*(boolean)*: isAsync
+#### Example
+```js
+isAsync(async function() {})
+//=> true
+isAsync(new Promise(r => r()))
+//=> false
+isAsync({})
+//=> false
+isAsync(function() {})
+
+```
---
-# copy(src=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2730 "View in source") [Ⓣ][1]
+is.isAsyncish(x=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L3283 "View in source") [Ⓣ][1]
+
+(Function): async function or promise
-Function
+#### @extends
-### @notes
+* undefined
+* undefined
-* wicked ternary
-
-### @todos
-- [ ] does not respect ObjectDescriptors
-
+#### @Since
+4.0.0-beta.2
+
#### Arguments
-1. `src=undefined` *(any)*:
+1. `x=undefined` *(*)*: value
#### Returns
-*(any)*:
+*(boolean)*: x isAsyncish
+
+#### Example
+```js
+isAsyncish(async function() {}) //=> true
+isAsyncish(new Promise(r => r())) //=> true
+isAsyncish({}) //=> false
+isAsyncish(function() {}) //=> false
+
+```
---
-
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2 "View in source") [Ⓣ][1]
-
-unknown
-
-
-### @todos
+is.boolean_1(x=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L1675 "View in source") [Ⓣ][1]
-- [ ] clarify .set vs .call
-
----
+(Function): Checks if `value` is classified as a boolean primitive OR object.
-
-
+#### @see
-
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L6620 "View in source") [Ⓣ][1]
+* is/toS
-unknown
+#### @extends
-#### Since
-2.0.0
+* undefined
+* undefined
+* undefined
----
-
-
+#### @Since
+3.0.0
-
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L7286 "View in source") [Ⓣ][1]
+#### Arguments
+1. `x=undefined` *(*)*: value
-unknown
+#### Returns
+*(boolean)*: isBoolean
-#### Since
-2.0.0
+#### Example
+```js
+isBoolean(false)
+//=> true
+isBoolean(new Boolean(1))
+//=> true
+isBoolean(1)
+//=> false
+isBoolean('')
+//=> false
+```
---
-
-
-## `is.prototype`
-
-
-
-# is.prototype.boolean_1(x=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L972 "View in source") [Ⓣ][1]
+is.booleanPrimitive(x=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L1637 "View in source") [Ⓣ][1]
-(Function): Checks if `value` is classified as a boolean primitive or object.
+(Function): Checks if `value` is classified as a boolean primitive NOT object.
-### @see
+#### @see
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
+* is/toS
-### @notes
+#### @notes
* could also have typeof x === 'boolean' || (/true|false/).test(x)
-### @extends
+#### @extends
* undefined
* undefined
-#### Since
-3.0.0
+
+#### @Since
+5.0.0-beta.4
#### Arguments
1. `x=undefined` *(*)*: value
#### Returns
-*(boolean)*: isBoolean
+*(boolean)*: isBooleanPrimitive
#### Example
```js
-isBoolean(false)
-//=> true
-isBoolean(new Boolean(1))
+isBooleanPrimitive(false)
//=> true
-isBoolean(1)
+isBooleanPrimitive(new Boolean(1))
//=> false
-isBoolean('')
+
+isBooleanPrimitive(1)
+//=> false
+isBooleanPrimitive('')
//=> false
```
@@ -4822,12 +6466,20 @@ isBoolean('')
-# is.prototype.date(x=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L940 "View in source") [Ⓣ][1]
+is.date(x=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L1597 "View in source") [Ⓣ][1]
Function
-#### Since
+
+#### @extends
+
+
+
+
+#### @Since
3.0.0
#### Arguments
@@ -4868,11 +6520,109 @@ class Eh extends Date()
-# is.prototype.error$1(x=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2043 "View in source") [Ⓣ][1]
+is.isDot(x=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L10273 "View in source") [Ⓣ][1]
+
+Function
+
+
+#### @see
+
+* isArray
+* isString
+* includes
+
+#### @todos
+
+- [ ] update with conditional
+
+
+#### @Since
+3.0.0
+
+#### Arguments
+1. `x=undefined` *(*)*: value to check
+
+#### Returns
+*(boolean)*: x isDot
+
+#### Example
+```js
+isDot('eh.oh') //=> true
+isDot('eh') //=> false
+isDot(['eh', 'oh']) //=> true
+
+```
+---
+
+
+
+
+
+is.isEnumerable(obj=undefined, prop=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L21 "View in source") [Ⓣ][1]
+
+(Function): object at property is enumerable
+
+
+#### @see
+
+* mozilla-propertyisenumerable
+
+#### @todos
+
+- [ ] use fp/call
+
+
+#### @Since
+3.0.0
+
+#### Arguments
+1. `obj=undefined` *(*|Object)*:
+2. `prop=undefined` *(*|string)*:
+
+#### Returns
+*(boolean)*: obj[prop] is enumerable
+
+#### Example
+```js
+const obj = { eh: true }
+isEnumerable(obj, 'eh')
+//=> true
+
+const objPropEnumerable = isEnumerable(obj)
+objPropEnumerable('eh')
+//=> true
+
+Object.defineProperty(obj, 'length', {
+ enumerable: false,
+ value: () => Object.keys(obj).length,
+})
+isEnumerable(obj, 'length')
+//=> false
+
+```
+---
+
+
+
+
+
+is.error$1(x=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L3115 "View in source") [Ⓣ][1]
Function
+
+#### @Since
+4.0.0
+
#### Arguments
1. `x=undefined` *(*)*: value
@@ -4911,12 +6661,15 @@ class Eh extends Error()
-# is.prototype._false(x=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L257 "View in source") [Ⓣ][1]
+is._false(x=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L856 "View in source") [Ⓣ][1]
Function
-#### Since
+
+#### @Since
4.0.0-alpha.1
#### Arguments
@@ -4941,19 +6694,26 @@ isFalse('')
-
+
+
+is._function(x=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L22 "View in source") [Ⓣ][1]
+
+(Function): Checks if `value` is classified as a `Function` object.
-# is.prototype._function(x=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L178 "View in source") [Ⓣ][1]
-(Function): Checks if `value` is classified as a `Function` object.
+#### @see
+* underscore-is-function
-### @notes
+#### @notes
* || x instanceof Function
-#### Since
+
+#### @Since
3.0.0
#### Arguments
@@ -4985,16 +6745,49 @@ isFunction(/abc/)
-# is.prototype.(x=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L1471 "View in source") [Ⓣ][1]
+is.isIn(obj=undefined, prop=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L494 "View in source") [Ⓣ][1]
+
+(Function): prop is in Object(obj)
+
+
+#### @Since
+5.0.0
+
+#### Arguments
+1. `obj=undefined` *(Object)*: object to check property of
+2. `prop=undefined` *(Primitive)*: property in obj
+
+#### Returns
+*(boolean)*: property
+
+#### Example
+```js
+isIn({ eh: true }, 'eh') //=> true
+isIn({ eh: true }, 'oh') //=> false
+
+```
+---
+
+
+
+
+
+is.(x=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2308 "View in source") [Ⓣ][1]
Function
-### @see
+#### @see
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-#### Since
+* https://github.com/jonschlinkert/kind-of/pull/12
+
+#### @Since
3.0.0
#### Arguments
@@ -5040,16 +6833,19 @@ class Eh extends Set()
-# is.prototype.map(x=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L119 "View in source") [Ⓣ][1]
+is.map(x=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L694 "View in source") [Ⓣ][1]
(Function): Checks if `value` is classified as a `Map` object.
-### @see
+#### @see
+
+* https://github.com/jonschlinkert/kind-of
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-#### Since
+#### @Since
3.0.0
#### Arguments
@@ -5095,17 +6891,20 @@ class Eh extends Map()
-# is.prototype.mapish(x=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L5124 "View in source") [Ⓣ][1]
+is.mapish(x=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L8022 "View in source") [Ⓣ][1]
Function
-### @extends
+#### @extends
-#### Since
+
+#### @Since
3.0.0
#### Arguments
@@ -5135,12 +6934,21 @@ isMapish(1)
-# is.prototype.matcher(x=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L3083 "View in source") [Ⓣ][1]
+is.matcher(x=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L5722 "View in source") [Ⓣ][1]
Function
-#### Since
+
+#### @see
+
+* is/regexp
+* is/function
+* conditionals/or
+
+#### @Since
3.0.0
#### Arguments
@@ -5169,56 +6977,15 @@ isMatcher('.*')
-# is.prototype.notEmptyArray(x=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L7657 "View in source") [Ⓣ][1]
-
-(Function): value is an Array, with at least `1` value
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-
-### @extends
-
-
-
-#### Since
-4.0.0-alpha.1
-
-#### Arguments
-1. `x=undefined` *(*)*: value
-
-#### Returns
-*(boolean)*: isNotEmptyArray
-
-#### Example
-```js
-isNotEmptyArray(new Array(3))
-//=> true
-isNotEmptyArray([1, 2, 3])
-//=> true
-
-isNotEmptyArray(new Array())
-//=> false
-isNotEmptyArray([])
-//=> false
-isNotEmptyArray(new Map())
-//=> false
-
-```
----
-
-
-
-
-
-# is.prototype._null(x=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L775 "View in source") [Ⓣ][1]
+is._null(x=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L188 "View in source") [Ⓣ][1]
Function
-#### Since
+
+#### @Since
3.0.0
#### Arguments
@@ -5250,16 +7017,21 @@ isNull(1)
-# is.prototype.nullOrUndefined(x=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L814 "View in source") [Ⓣ][1]
+is.nullOrUndefined(x=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L235 "View in source") [Ⓣ][1]
(Function): Checks if `value` is `null` or `undefined`.
-### @see
+#### @see
+
+* is/null
+* is/undefined
+* https://github.com/infernojs/inferno/blob/master/packages/inferno-shared/src/index.ts#L23
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-#### Since
+#### @Since
4.0.0-alpha.1
#### Arguments
@@ -5295,17 +7067,20 @@ isNullOrUndefined(false)
-# is.prototype.number(x=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2086 "View in source") [Ⓣ][1]
+is.number(x=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L5491 "View in source") [Ⓣ][1]
Function
-### @see
+#### @see
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
+* is/real
+* http://stackoverflow.com/questions/18082/validate-decimal-numbers-in-javascript-isnumeric
-### @notes
+#### @notes
* was not needed except for abstract ==
const isObj = require('./obj')
@@ -5315,7 +7090,13 @@ Function
: (/^0x[0-9a-f]+$/i).test(x) ||
(/^[-+]?(?:\d+(?:\.\d*)?|\.\d+)(e[-+]?\d+)?$/).test(x))
-#### Since
+
+#### @extends
+
+
+
+
+#### @Since
3.0.0
#### Arguments
@@ -5328,6 +7109,8 @@ Function
```js
isNumber(1)
//=> true
+isNumber(new Number(1))
+//=> true
isNumber(Number(1))
//=> true
isNumber(NaN)
@@ -5353,21 +7136,77 @@ isNumber(false)
-# is.prototype.obj(value=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2009 "View in source") [Ⓣ][1]
+is.numberPrimitive(x=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L3320 "View in source") [Ⓣ][1]
+
+Function
+
+
+#### @see
+
+* is/real
+
+#### @Since
+3.0.0
+
+#### Arguments
+1. `x=undefined` *(*)*: value
+
+#### Returns
+*(boolean)*: isNumberPrimitive
+
+#### Example
+```js
+isNumberPrimitive(1)
+//=> true
+isNumberPrimitive(Number(1))
+//=> true
+isNumberPrimitive(NaN)
+//=> true
+isNumberPrimitive(new Number(1))
+//=> false
+
+isNumberPrimitive(null)
+//=> false
+isNumberPrimitive(undefined)
+//=> false
+isNumberPrimitive(void 0)
+//=> false
+isNumberPrimitive({})
+//=> false
+isNumberPrimitive('')
+//=> false
+isNumberPrimitive(false)
+//=> false
+
+```
+---
+
+
+
+
+
+is.obj(value=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2176 "View in source") [Ⓣ][1]
Function
-### @see
+#### @see
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
+* http://stackoverflow.com/questions/34111902/why-do-lodashs-isobject-isplainobject-behave-differently-than-typeof-x
+* https://github.com/lodash/lodash/blob/master/isObject.js
-### @notes
+#### @notes
* Object.prototype.toString.call(val) === '[object Object]'
-#### Since
+
+#### @Since
3.0.0
#### Arguments
@@ -5393,46 +7232,222 @@ isObject(null)
```
---
-
+
+
+
+
+is.objTypeof(x=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L1437 "View in source") [Ⓣ][1]
+
+Function
+
+
+#### @see
+
+* is/obj
+* is/objWithKeys
+* is/objStrict
+* is/null
+
+#### @Since
+3.0.0
+
+#### Arguments
+1. `x=undefined` *(*)*: value
+
+#### Returns
+*(boolean)*: isObjLoose
+
+#### Example
+```js
+isObjLoose(new Object())
+//=> true
+isObjLoose({})
+//=> true
+isObjLoose(Object.create(null))
+//=> true
+isObjLoose(null)
+//=> true
+
+isObjLoose(new Set())
+//=> false
+isObjLoose(function() {})
+//=> false
+isObjLoose('')
+//=> false
+isObjLoose(1)
+//=> false
+
+```
+---
+
+
+
+
+
+is.objNotNull(x=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L21 "View in source") [Ⓣ][1]
+
+Function
+
+
+#### @see
+
+* is/obj
+* is/objWithKeys
+* is/objTypeof
+* is/null
+* is-obj
+* lodash-is-object-like
+
+#### @todos
+
+- [ ] !Array.isArray
+
+
+#### @extends
+
+
+
+
+#### @Since
+3.0.0
+
+#### Arguments
+1. `x=undefined` *(*)*: value
+
+#### Returns
+*(boolean)*: isObjNotNull
+
+#### Example
+```js
+isObjNotNull(new Object())
+//=> true
+isObjNotNull({})
+//=> true
+isObjNotNull(Object.create(null))
+//=> true
+isObjNotNull(null)
+//=> false
+
+isObjNotNull(new Set())
+//=> false
+isObjNotNull(function() {})
+//=> false
+isObjNotNull('')
+//=> false
+isObjNotNull(1)
+//=> false
+
+```
+---
+
+
+
+
+
+is.isObjPure(x=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L5644 "View in source") [Ⓣ][1]
+
+Function
+
+
+#### @extends
+
+* undefined
+* undefined
+* undefined
+* undefined
+
+
+
+#### @Since
+3.0.0
+
+#### Arguments
+1. `x=undefined` *(*)*: value to check
+
+#### Returns
+*(boolean)*: is obj & !null & !undefined & !array & !function
+
+#### Example
+```js
+isObjPure(function() {})
+//=> false
+isObjPure(null)
+//=> false
+isObjPure([])
+//=> false
+
+isObjPure({})
+//=> true
+
+```
+---
+
+
+
+
+
+is.objWithKeys(x=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L5689 "View in source") [Ⓣ][1]
+
+Function
+
+
+#### @see
+
+* is/obj
+* is/objWithKeys
+* is/objStrict
+* is/null
+
+#### @todos
-
+- [ ] @NOTE need to be more careful, needs to check for vanilla objects, not native ones since e.g. Error has no keys
+
-# is.prototype.objLoose(x=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L748 "View in source") [Ⓣ][1]
+#### @extends
-Function
-### @see
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-#### Since
+#### @Since
3.0.0
#### Arguments
1. `x=undefined` *(*)*: value
#### Returns
-*(boolean)*: isObjLoose
+*(boolean)*: isObjWithKeys
#### Example
```js
-isObjLoose(new Object())
-//=> true
-isObjLoose({})
-//=> true
-isObjLoose(Object.create(null))
-//=> true
-isObjLoose(null)
+isObjWithKeys({ eh: true })
//=> true
-
-isObjLoose(new Set())
+isObjWithKeys({})
//=> false
-isObjLoose(function() {})
+isObjWithKeys(new Object())
//=> false
-isObjLoose('')
+isObjWithKeys(Object.create(null))
//=> false
-isObjLoose(1)
+isObjWithKeys(null)
+//=> false
+isObjWithKeys(new Set())
+//=> false
+isObjWithKeys(function() {})
+//=> false
+isObjWithKeys('')
+//=> false
+isObjWithKeys(1)
//=> false
```
@@ -5442,52 +7457,48 @@ isObjLoose(1)
-# is.prototype.objStrict(x=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L856 "View in source") [Ⓣ][1]
-
-Function
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-
-### @todos
+is.promise(x=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L3246 "View in source") [Ⓣ][1]
-- [ ] !Array.isArray
-
+(Function): is a Promise
-### @extends
+#### @see
+* https://github.com/jonschlinkert/kind-of/blob/master/index.js#L66
+* https://github.com/sindresorhus/promise-fun
-#### Since
-3.0.0
+#### @Since
+4.0.0-beta.2
#### Arguments
1. `x=undefined` *(*)*: value
#### Returns
-*(boolean)*: isObjStrict
+*(boolean)*: x isPromise
#### Example
```js
-isObjStrict(new Object())
+isPromise(new Promise(r => r))
//=> true
-isObjStrict({})
-//=> true
-isObjStrict(Object.create(null))
-//=> true
-isObjStrict(null)
-//=> false
+isPromise(async function() {})
+//=> false // on some environments, true
-isObjStrict(new Set())
+isPromise({})
+//=> false
+isPromise(Object.create(null))
//=> false
-isObjStrict(function() {})
+isPromise(null)
//=> false
-isObjStrict('')
+isPromise(new Set())
//=> false
-isObjStrict(1)
+isPromise(function() {})
+//=> false
+isPromise('')
+//=> false
+isPromise(1)
//=> false
```
@@ -5497,49 +7508,43 @@ isObjStrict(1)
-# is.prototype.objWithKeys(x=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L3038 "View in source") [Ⓣ][1]
-
-Function
+is.isPrototypeOf(haystack=undefined, needle=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L21 "View in source") [Ⓣ][1]
+(Function): check if arg `1` is prototype of arg `2`
-### @see
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
+#### @see
-### @extends
+* mozilla-obj-isprototypeof
+#### @todos
+- [ ] curry2
+
-#### Since
+#### @Since
3.0.0
#### Arguments
-1. `x=undefined` *(*)*: value
+1. `haystack=undefined` *(*|Object)*: check needle against
+2. `needle=undefined` *(*|Object)*: is prototype of haystack
#### Returns
-*(boolean)*: isObjWithKeys
+*(boolean)*: needle isPrototypeOf haystack
#### Example
```js
-isObjWithKeys({ eh: true })
-//=> true
-isObjWithKeys({})
-//=> false
-isObjWithKeys(new Object())
-//=> false
-isObjWithKeys(Object.create(null))
-//=> false
-isObjWithKeys(null)
-//=> false
-isObjWithKeys(new Set())
-//=> false
-isObjWithKeys(function() {})
-//=> false
-isObjWithKeys('')
-//=> false
-isObjWithKeys(1)
-//=> false
+class Eh extends Function {}
+class Canada extends Eh {}
+isPrototypeOf(Eh, Function) //=> true
+isPrototypeOf(Canada, Function) //=> true
+isPrototypeOf(Eh, Date) //=> false
+
+isPrototypeOf({}, Object) //=> true
+isPrototypeOf({}, Array) //=> false
```
---
@@ -5548,27 +7553,34 @@ isObjWithKeys(1)
-# is.prototype.real(x=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2999 "View in source") [Ⓣ][1]
+is.real(x=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L5573 "View in source") [Ⓣ][1]
Function
-### @see
+#### @see
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
+* is/null
+* is/undefined
+* http://2ality.com/2013/04/quirk-implicit-conversion.html
+* https://javascriptrefined.io/nan-and-typeof-36cd6e2a4e43
+* https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/isNaN
-### @notes
+#### @notes
* eslint-disable-next-line no-self-compare
&& x !== x
-### @extends
+#### @extends
-#### Since
+
+#### @Since
3.0.0
#### Arguments
@@ -5611,12 +7623,15 @@ isReal(1)
-# is.prototype._true(x=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L886 "View in source") [Ⓣ][1]
+is._true(x=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L1535 "View in source") [Ⓣ][1]
Function
-#### Since
+
+#### @Since
4.0.0-alpha.1
#### Arguments
@@ -5643,21 +7658,20 @@ isTrue('')
-# is.prototype._undefined(x=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L52 "View in source") [Ⓣ][1]
+is._undefined(x=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L147 "View in source") [Ⓣ][1]
(Function): Checks if `value` is `undefined`.
-### @see
+#### @see
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
+* is/nullOrUndefined
+* https://github.com/infernojs/inferno/blob/master/packages/inferno-shared/src/index.ts#L57
-### @notes
-
-* || typeof x === 'undefined'
-
-#### Since
+#### @Since
4.0.0-alpha.1
#### Arguments
@@ -5693,21 +7707,71 @@ isUndefined(false)
-# is.prototype.string(x=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L235 "View in source") [Ⓣ][1]
+is.primitive$2(x=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L3360 "View in source") [Ⓣ][1]
+
+(Function): Checks if `value` is classified as a **primitive**
+`(number|string|boolean|null|undefined)`
+
+
+#### @see
+
+* http://www.adequatelygood.com/Object-to-Primitive-Conversions-in-JavaScript.html
+* https://developer.mozilla.org/en-US/docs/Glossary/Primitive
+* http://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html
+
+#### @Since
+4.0.0 was in another file
+
+#### Arguments
+1. `x=undefined` *(*)*: The value to check.
+
+#### Returns
+*(boolean)*: x is number|string|boolean|null|undefined
+
+#### Example
+```js
+isPrimitive('abc') // => true
+isPrimitive(1) // => true
+isPrimitive('') // => true
+isPrimitive(null) // => true
+isPrimitive(undefined) // => true
+isPrimitive(void 0) // => true
+
+isPrimitive(new String('abc')) // => false
+isPrimitive([]) // => false
+isPrimitive(() => {}) // => false
+isPrimitive({}) // => false
+
+```
+---
+
+
+
+
+
+is.string(x=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L833 "View in source") [Ⓣ][1]
(Function): Checks if `value` is classified as a `String` primitive or object.
-### @see
+#### @see
+
+* https://github.com/lodash/lodash/blob/master/isString.js
+* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String
+* isStringPrimitive
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
+#### @extends
-### @extends
-#### Since
+#### @Since
3.0.0
#### Arguments
@@ -5734,16 +7798,20 @@ isString(1)
-# is.prototype.stringOrNumber(x=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2949 "View in source") [Ⓣ][1]
+is.stringOrNumber(x=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L5520 "View in source") [Ⓣ][1]
(Function): Checks if `value` is classified as a `String` primitive or object.
-### @see
+#### @see
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-#### Since
+* https://github.com/infernojs/inferno/blob/master/packages/inferno-shared/src/index.ts#L23
+* https://github.com/lodash/lodash/blob/master/isString.js
+
+#### @Since
3.0.0
#### Arguments
@@ -5767,16 +7835,21 @@ isString(1)
-# is.prototype.stringPrimitive(x=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L206 "View in source") [Ⓣ][1]
+is.stringPrimitive(x=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L797 "View in source") [Ⓣ][1]
(Function): Checks if `value` is classified as a `String` **primitive**.
-### @see
+#### @see
+
+* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String
+* https://github.com/lodash/lodash/blob/master/isString.js
+* is/string
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-#### Since
+#### @Since
3.0.0
#### Arguments
@@ -5803,12 +7876,15 @@ isString(1)
-# is.prototype.symbol(value=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L3059 "View in source") [Ⓣ][1]
+is.symbol(value=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L3143 "View in source") [Ⓣ][1]
(Function): Checks if `value` is classified as a `Symbol` primitive or object.
-#### Since
+
+#### @Since
4.0.0
#### Arguments
@@ -5830,28 +7906,35 @@ isSymbol('abc')
+
+
-# is.prototype.toS(value=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L77 "View in source") [Ⓣ][1]
+## `is.index$12`
-(Function): The base implementation of `getTag` without fallbacks for buggy environments.
+
+🌊 Types: is.d
-### @see
+* 🔬 Tests: empty
+* 🔬 Tests: index
+* 🔬 Tests: is
+* 🔬 Tests: json
+* 🔬 Tests: not-exported-in-entry
+* 🔬 Tests: primitives
+* 🔬 Tests: simple
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
+is.index$12
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L5746 "View in source") [Ⓣ][1]
-### @todos
+Object
-- [ ] obj[Symbol.toStringTag]
-
-#### Arguments
-1. `value=undefined` *(*)*: The value to query.
-#### Returns
-*(string)*: Returns the `toStringTag`.
+#### @see
+* https://github.com/lodash/lodash/issues/3237
---
@@ -5860,26 +7943,24 @@ isSymbol('abc')
-## `is.prototype.index$12`
+## `isNotRealOrIsEmpty`
-🌊 Types: is.d
-
-* 🔬 Tests: index
-* 🔬 Tests: is
-* 🔬 Tests: primitives
-* 🔬 Tests: simple
-
-# is.prototype.index$12
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L3100 "View in source") [Ⓣ][1]
+isNotRealOrIsEmpty
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L5973 "View in source") [Ⓣ][1]
-Object
+Function
-### @see
+#### @see
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
+* is/isReal
+* is/isEmpty
+* conditional/and
+* conditional/not
---
@@ -5888,22 +7969,46 @@ Object
-## `isArray`
+## `iteratable`
-# array
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L864 "View in source") [Ⓣ][1]
+iteratable(x=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L3412 "View in source") [Ⓣ][1]
-Function
+(Function): is able to be iterated on
-### @see
+#### @extends
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-#### Since
-3.0.0
+* undefined
+* undefined
+* undefined
+* undefined
+* undefined
+* undefined
+* undefined
+* undefined
+
+
+#### Arguments
+1. `x=undefined` *(*)*: node is iteratable
+
+#### Returns
+*(boolean)*: x isIteratable
+#### Example
+```js
+isIteratable([]) //=> true
+isIteratable({}) //=> true
+isIteratable(new Date()) //=> false
+isIteratable(Symbol('eh')) //=> false
+isIteratable(new Promise(r => r())) //=> false
+isIteratable(new Error('eh')) //=> false
+
+```
---
@@ -5912,32 +8017,59 @@ Function
-## `isRoot`
+## `keysObjOrArray`
-# isRoot
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2537 "View in source") [Ⓣ][1]
+keysObjOrArray(obj=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L22 "View in source") [Ⓣ][1]
-(Boolean): Whether the present node is the root node
+(Function): Creates an array of the own enumerable property names of `object`.
+**Note:** Non-object values are coerced to objects. See the
+[ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
+for more details.
----
-
+#### @see
-
+* deps/util/lengthFromZero
+* deps/util/props
+*
+* lodash-keys
+* lodash-get-all-keys
-
+#### @todos
-## `key`
+- [ ] https://github.com/lodash/lodash/blob/master/.internal/arrayLikeKeys.js
+
-
+#### @Since
+0.1.0
-# key
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2532 "View in source") [Ⓣ][1]
+#### Arguments
+1. `obj=undefined` *(Object)*: The object to query.
-unknown
+#### Returns
+*(Array)*: Returns the array of property names.
+#### Example
+```js
+function Foo() {
+ this.a = 1
+ this.b = 2
+}
+
+Foo.prototype.c = 3
+
+keys(new Foo())
+// => ['a', 'b'] (iteration order is not guaranteed)
+
+keys('hi')
+// => ['0', '1']
+
+```
---
@@ -5946,15 +8078,40 @@ unknown
-## `level`
+## `lengthFromZero`
-# level
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2542 "View in source") [Ⓣ][1]
+lengthFromZero(obj=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2970 "View in source") [Ⓣ][1]
+
+(Function): when length > `1`, use length-1
+otherwise, when length == `1`, use `0`
+default, use length
+
+
+#### @todos
+
+- [ ] lense to use an object, or transform it to one with .length?
+ const len = prop('length')
+ // when isObj, use len, otherwise, value
+ const coerceLength = lense([isObj, len])
+
+#### Arguments
+1. `obj=undefined` *(Array|Object|number)*: with length
-(number): Depth of the node within the traversal
+#### Returns
+*(number)*: obj length from `0`
+
+#### Example
+```js
+lengthFromZero([1]) //=> 1
+lengthFromZero([]) //=> 0
+lengthFromZero([1, 2, 3]) //=> 2
+```
---
@@ -5967,22 +8124,31 @@ unknown
-# markForGarbageCollection(obj=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L4268 "View in source") [Ⓣ][1]
+markForGarbageCollection(obj=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L7135 "View in source") [Ⓣ][1]
(Function): remove all methods, mark for garbage collection
-### @see
+#### @see
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
+* https://stackoverflow.com/questions/1947995/when-should-i-use-delete-vs-setting-elements-to-null-in-javascript
+* https://v8project.blogspot.ca/2015/08/getting-garbage-collection-for-free.html
+* https://github.com/natewatson999/js-gc
+* https://github.com/siddMahen/node-gc
+* http://buildnewgames.com/garbage-collector-friendly-code/
+* https://stackoverflow.com/questions/27597335/ensuring-object-can-be-garbage-collected
+* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_Management
-### @todos
+#### @todos
- [ ] blacklist = [] param
- [ ] put all GC events into a cached map and debounce the operation
-#### Since
+
+#### @Since
4.0.0
#### Arguments
@@ -6012,25 +8178,29 @@ obj
-## `matcher.prototype`
+## `matcher`
-# matcher.prototype.escapeStringRegex(str=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L20 "View in source") [Ⓣ][1]
+matcher.escapeStringRegex(str=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L19 "View in source") [Ⓣ][1]
Function
-### @see
+#### @see
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
+* escape-string-regexp
+* fp/replace
-### @notes
+#### @notes
* also as const escapeStringRegexp = require('escape-string-regexp');
-#### Since
+
+#### @Since
3.0.0
#### Arguments
@@ -6052,12 +8222,15 @@ new RegExp(escaped)
-# matcher.prototype.make(pattern=undefined, shouldNegate=undefined, alphaOmega=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L6268 "View in source") [Ⓣ][1]
+matcher.make(pattern=undefined, shouldNegate=undefined, alphaOmega=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L9032 "View in source") [Ⓣ][1]
(Function): turn any string[], function[], or RegExp[] into a matcher
-#### Since
+
+#### @Since
3.0.0
#### Arguments
@@ -6115,16 +8288,20 @@ matcher.make(noName, true, true)
-# matcher.prototype.matcher(inputs=undefined, patterns=undefined, shouldNegate=undefined, alphaOmega=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L6344 "View in source") [Ⓣ][1]
+matcher.matcher(inputs=undefined, patterns=undefined, shouldNegate=undefined, alphaOmega=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L9108 "View in source") [Ⓣ][1]
(Function): same as .make but also accepts inputs, and returns an array
-### @see
+#### @see
+
+* Matcher.make
+* compose/Observe
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-#### Since
+#### @Since
3.0.0
#### Arguments
@@ -6179,17 +8356,19 @@ matcher({ test: x => x === 'kinga' }, 'nope')
🔬 Tests: matcher
-# matcher.prototype.matcher
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L6219 "View in source") [Ⓣ][1]
+matcher.matcher
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L8983 "View in source") [Ⓣ][1]
unknown
-### @see
+#### @see
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
+* https://github.com/sindresorhus/matcher/blob/master/index.js
-### @symb
+#### @symb
🎯
---
@@ -6198,13 +8377,15 @@ unknown
-# matcher.prototype.toRegexp(str=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L6203 "View in source") [Ⓣ][1]
+matcher.toRegexp(str=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L8963 "View in source") [Ⓣ][1]
Function
-### @extends
+#### @extends
@@ -6234,22 +8415,25 @@ toRegExp('*')
-# merge([obj2=undefined])
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L5232 "View in source") [Ⓣ][1]
+merge([obj2=undefined])
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L8135 "View in source") [Ⓣ][1]
(Function): merges object in, goes through all keys, checks cbs, dopemerges
-### @see
+#### @see
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
+* ChainedMap
-### @todos
+#### @todos
- [ ] issue here if we extend without shorthands &
we want to merge existing values... :s
-#### Since
+
+#### @Since
1.0.0
#### Arguments
@@ -6273,21 +8457,25 @@ chain.entries()
-# merge(obj=undefined, [handleMergeFn=undefined])
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L5553 "View in source") [Ⓣ][1]
+merge(obj=undefined, [handleMergeFn=undefined])
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L8467 "View in source") [Ⓣ][1]
(Function): merges an object with the current store
-### @see
+#### @see
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
+* deps/dopemerge
+* MergeChain
-### @todos
+#### @todos
- [ ] needs to pass in additional opts somehow...
-#### Since
+
+#### @Since
0.4.0
#### Arguments
@@ -6305,45 +8493,16 @@ chain.merge({ eh: [2] })
chain.get('eh')
// => [1, 2]
-```
-#### Example
-```js
-const chain = new Chain()
- chain.set('emptyArr', [])
- chain.merge({emptyArr: []}, mergeChain =>
- mergeChain.onExisting((a, b) => []).merger((a, b) => []).merge()
- )
- chain.get('emptyArr').length)
- //=> 0
-```
----
-
-
-
-
-
-# merge(arr=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L5665 "View in source") [Ⓣ][1]
-
-(Function): merge any Array/Set/Iteratable/Concatables into the array, at the end
-
-#### Since
-0.4.0
-
-#### Arguments
-1. `arr=undefined` *(Array|Concatable|Set)*: values to merge in and append
-
-#### Returns
-*(ChainedSet)*: @chainable
-
+```
#### Example
```js
-const people = new ChainedSet()
-people.add('sam').add('sue').prepend('first').merge(['merged'])
-
-for (let name of people) console.log(name)
-//=> first, sam, sue, merged
-
+const chain = new Chain()
+ chain.set('emptyArr', [])
+ chain.merge({emptyArr: []}, mergeChain =>
+ mergeChain.onExisting((a, b) => []).merger((a, b) => []).merge()
+ )
+ chain.get('emptyArr').length)
+ //=> 0
```
---
@@ -6357,12 +8516,15 @@ for (let name of people) console.log(name)
-
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L1648 "View in source") [Ⓣ][1]
+
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2594 "View in source") [Ⓣ][1]
(Function): a single easily minifiable function, dynamically setting & getting depending on arguments to avoid nested property accessing only instantiating when values are **addded**
-#### Since
+
+#### @Since
4.0.0
#### Arguments
@@ -6385,16 +8547,19 @@ for (let name of people) console.log(name)
-# method(names=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L5517 "View in source") [Ⓣ][1]
+method(names=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L8431 "View in source") [Ⓣ][1]
(Function): the way to easily start building methods when using chainable instances
-### @see
+#### @see
+
+* MethodChain
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-#### Since
+#### @Since
4.0.0
#### Arguments
@@ -6424,8 +8589,12 @@ chain.get('eh')
-# methodEncasingFactory(name=undefined, parent=undefined, built=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L3956 "View in source") [Ⓣ][1]
+🌊 Types: deps.encase.d
+
+methodEncasingFactory(name=undefined, parent=undefined, built=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L6789 "View in source") [Ⓣ][1]
(Function): 3 steps
0. enhance error
@@ -6433,10 +8602,11 @@ chain.get('eh')
2. build a function to call onInvalid or onInvalid depending
-### @symb
+#### @symb
⛑🏭
-#### Since
+
+#### @Since
4.0.0
#### Arguments
@@ -6461,36 +8631,38 @@ methodEncasingFactory('eh', {}, { onSet: console.log })
-## `node`
+## `noop`
-# node
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2510 "View in source") [Ⓣ][1]
-
-(Array): The present node on the recursive walk
-
----
-
-
+noop()
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L4 "View in source") [Ⓣ][1]
-
+Function
-
-## `node_`
+#### @see
-
+* noop3
-# node_
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2516 "View in source") [Ⓣ][1]
+#### @Since
+5.0.0
-Array
+#### Returns
+*(void)*:
+#### Example
+```js
+noop
-### @see
+```
+#### Example
+```js
+noop()
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
+```
---
@@ -6499,32 +8671,36 @@ Array
-## `parent`
+## `notNested`
-# parent
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2526 "View in source") [Ⓣ][1]
-
-unknown
-
----
-
-
+notNested(x=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L5600 "View in source") [Ⓣ][1]
-
+Function
-
-## `path`
+#### @Since
+5.0.0
-
+#### Arguments
+1. `x=undefined` *(*)*: value to check
-# path
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2521 "View in source") [Ⓣ][1]
+#### Returns
+*(boolean)*: x isNotNested
-(Array): An array of string keys from the root to the present node
+#### Example
+```js
+isNotNested('') //=> true
+isNotNested(true) //=> true
+isNotNested(new RegExp()) //=> true
+isNotNested(new Error('eh')) //=> false
+isNotNested(null) //=> false
+```
---
@@ -6537,50 +8713,48 @@ unknown
-# paths(key=undefined, value=undefined, longest=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2814 "View in source") [Ⓣ][1]
+paths(key=undefined, value=undefined, [longest=undefined])
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L5283 "View in source") [Ⓣ][1]
(Function): gathers dot.prop from any value, with a prefixed/base key
-### @notes
-
-* had `onlyLongest` & `asString` but can just .join(',') to match
-
-#### Since
-4.0.0
-
-#### Arguments
-1. `key=undefined` *(Primitive)*:
-2. `value=undefined` *(Traversable)*:
-3. `longest=undefined` *(|boolean)*:
-
-#### Returns
-*(*)*: paths
-
----
-
-
+#### @see
-
+* deps/traverse
-
+#### @notes
-## `post`
+* had `onlyLongest` & `asString` but can just .join(',') to match
+
-
+#### @todos
-# post(fn=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2621 "View in source") [Ⓣ][1]
+- [ ] should build a trie if doing this
+
-(Function): Call this function after each of the children are traversed.
+#### @Since
+4.0.0
#### Arguments
-1. `fn=undefined` *(Function)*:
+1. `key=undefined` *(Primitive)*: prefixing key for the paths, root path/key
+2. `value=undefined` *(Traversable)*: traversable value to extract paths from
+3. `[longest=undefined]` *(|boolean)*: optionally filter to keep only longest/deepest paths
#### Returns
-*(any)*:
+*(*)*: paths[]
+
+#### Example
+```js
+dotPropPaths('', { oh: { eh: true } })
+//=> ['oh.eh']
+dotPropPaths('moose', { oh: { eh: true } })
+//=> ['moose.oh.eh']
+
+```
---
@@ -6589,119 +8763,105 @@ unknown
-## `pre`
+## `pooler`
-# pre(fn=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2613 "View in source") [Ⓣ][1]
+pooler.addPoolingTo(CopyConstructor=undefined, pooler=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L4358 "View in source") [Ⓣ][1]
+
+(Function): Augments `CopyConstructor` to be a poolable class, augmenting only the class
+itself *(statically)* not adding any prototypical fields. Any CopyConstructor
+you give this may have a `poolSize` property, and will look for a
+prototypical `destructor` on instances.
+
-(Function): Call this function before each of the children are traversed.
+#### @Since
+5.0.0
#### Arguments
-1. `fn=undefined` *(Function)*:
+1. `CopyConstructor=undefined` *(Function|Object)*: Constructor that can be used to reset.
+2. `pooler=undefined` *(Function)*: Customizable pooler.
#### Returns
-*(any)*:
+*(Object)*: enhanced constructor, decorated with pooler
----
+#### Example
+```js
+class Eh {}
+addPoolingTo(Eh) // can optionally pass in pooler as second arg
+//=> Eh.instancePool = []
+//=> Eh.getPooled = pooler || singleArgumentPooler
+//=> Eh.poolSize = 10
+//=> Eh.release = standardReleaser
-
+```
+---
-## `prepend`
-
-
+pooler.oneArgumentPooler(copyFieldsFrom=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L4320 "View in source") [Ⓣ][1]
-# prepend(value=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L5641 "View in source") [Ⓣ][1]
+(Function): Static poolers. Several custom versions for each potential number of
+arguments. A completely generic pooler is easy to implement, but would
+require accessing the `arguments` object. In each of these, `this` refers to
+the Class itself, not an instance. If any others are needed, simply add them
+here, or in their own files.
-(Function): inserts the value at the **beginning** of the Set
-#### Since
-0.4.0
+#### @Since
+5.0.0
#### Arguments
-1. `value=undefined` *(any)*: any value to add to **beginning** the store
+1. `copyFieldsFrom=undefined` *(Object)*: obj with instance pool
#### Returns
-*(ChainedSet)*: @chainable
+*(Object)*: instance of Klass
#### Example
```js
-const people = new ChainedSet()
-people.add('sue').prepend('first')
-
-for (let name of people) console.log(name)
-//=> first, sue
+class Eh {}
+addPoolingTo(Eh)
+const eh = Eh.getPooled() //=> oneArgumentPooler(Eh)
+eh.release()
```
---
-
-
-
-
-## `prototype[iterator]`
-
-🔬 Tests: iteration
-
-# prototype[iterator]()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L391 "View in source") [Ⓣ][1]
-
-(generator): Iterator for looping values in the store
-
+pooler.standardReleaser(instance=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L4282 "View in source") [Ⓣ][1]
-### @see
+(Function): call destructor on a pooled instance, put it back in the pool
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-### @notes
+#### @Since
+5.0.0
-* assigned to a variable so buble ignores it
-
-#### Since
-0.5.0
+#### Arguments
+1. `instance=undefined` *(Object)*: call destructor
#### Returns
-*(Object)*: {value: undefined | any, done: true | false}
-
-#### Example
-```js
-const chain = new Chain().set('eh', 1)
-for (var [key, val] of chain) console.log({ [key]: val })
-//=> {eh: 1}
+*(void)*:
-```
-#### Example
-```js
-*[Symbol.iterator](): void { for (const item of this.store) yield item }
-```
#### Example
```js
-const { ChainedSet } = require('chain-able')
-const set = new ChainedSet()
-set.add('eh')
-
-for (const arr of set) {
- const [key, val] = arr
-
- key
- //=> 0
-
- val
- //=> 'eh'
-
- arr.length
- //=> 2
-}
+class Eh {}
+addPoolingTo(Eh)
+const eh = Eh.getPooled()
+eh.release()
```
---
@@ -6712,45 +8872,27 @@ for (const arr of set) {
-## `prototype[primitive]`
+## `pooler.// const pooler`
-# prototype[primitive](hint=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L646 "View in source") [Ⓣ][1]
-
-Function
-
+🔬 Tests: pooler
-### @see
+pooler.// const pooler
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L3 "View in source") [Ⓣ][1]
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-#### Since
-1.0.2
+Object
-#### Arguments
-1. `hint=undefined` *(string)*: enum[default, string, number]
-#### Returns
-*(Primitive)*:
+#### @see
-#### Example
-```js
-const chain = new Chain()
-chain.toNumber = () => 1 + chain
-//=> 1
-chain + 1
-//=>
+* react-pooler
-```
-#### Example
-```js
-const chain = new Chain()
-chain.toString = () => 'eh'
-chain + ''
-//=> 'eh'
+#### @symb
-```
+🎱
---
@@ -6763,16 +8905,19 @@ chain + ''
-# reduce(map=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L1337 "View in source") [Ⓣ][1]
+reduce(map=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2117 "View in source") [Ⓣ][1]
(Function): Map -> Object
-### @see
+#### @see
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-#### Since
+* ArrayFrom
+
+#### @Since
4.0.0
#### Arguments
@@ -6800,23 +8945,28 @@ reduce(map)
-
-
-## `reduce.prototype`
+reduce.clean(obj=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L10754 "View in source") [Ⓣ][1]
-
+(Function): goes through the maps, and the map values, reduces them to array then to an object using the reduced values
-# reduce.prototype.clean(obj=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L7692 "View in source") [Ⓣ][1]
-(Function): goes through the maps, and the map values, reduces them to array then to an object using the reduced values
+#### @see
+* reduce
+* isObjWithKeys
+* isNotEmptyArray
+* isReal
+* http://underscorejs.org/#reduce
-### @see
+#### @todos
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
+- [ ] seems to be overkill with reducing mapping just copy & ignore or delete?
+
#### Arguments
1. `obj=undefined` *(Object): object to clean, usually .entries()*
@@ -6850,20 +9000,23 @@ clean(map.entries())
-# regexp(value=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L906 "View in source") [Ⓣ][1]
+regexp(x=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L1558 "View in source") [Ⓣ][1]
(Function): Checks if `value` is classified as a `RegExp` object.
-### @see
+#### @see
+
+* https://github.com/lodash/lodash/blob/master/isRegExp.js
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-#### Since
+#### @Since
0.1.0
#### Arguments
-1. `value=undefined` *(*)*: The value to check.
+1. `x=undefined` *(*)*: The value to check.
#### Returns
*(boolean)*: Returns `true` if `value` is a regexp, else `false`.
@@ -6885,58 +9038,14 @@ isRegExp('/abc/')
-## `remove`
-
-
-
-# remove(stopHere=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2577 "View in source") [Ⓣ][1]
-
-(Function): Remove the current element from the output. If the node is in an Array it will be spliced off. Otherwise it will be deleted from its parent.
-
-#### Arguments
-1. `stopHere=undefined` *(boolean)*:
-
-#### Returns
-*(void)*:
-
----
-
-
-
-
-
-
-
-## `return`
-
-
-
-# return(node_=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2494 "View in source") [Ⓣ][1]
-
-Function
-
-#### Arguments
-1. `node_=undefined` *(any)*:
-
-#### Returns
-*(State)*: see types
-
----
-
-
-
-
-
-
-
## `schema`
-# schema(obj=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L3686 "View in source") [Ⓣ][1]
+schema(obj=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L6462 "View in source") [Ⓣ][1]
(Function): handles: 1. recursively building nestable schemas, 2. creating MethodChains for all types 3. carrying over the inheritable properties 4. @modifies @injects @decorates .add(customValidators)
@@ -6950,16 +9059,12 @@ Function
-
-
-## `schema.prototype`
-
-
-
-# schema.prototype.typeListFactory(fullKey=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L3357 "View in source") [Ⓣ][1]
+schema.typeListFactory(fullKey=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L6121 "View in source") [Ⓣ][1]
Function
@@ -6987,20 +9092,23 @@ isStringOrNumber(Object)
-# schema.prototype.typeValidator(input=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L3615 "View in source") [Ⓣ][1]
+schema.typeValidator(input=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L6388 "View in source") [Ⓣ][1]
(Function): build a recursive schema for all around runtime type safety
-### @see
+#### @see
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
+* is
-### @symb
+#### @symb
🛂
-#### Since
+
+#### @Since
4.0.0-beta.1
#### Arguments
@@ -7050,12 +9158,15 @@ var isValid = typeValidator(1)
-# schemaFactory(property=undefined, nestedSchema=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L3573 "View in source") [Ⓣ][1]
+schemaFactory(property=undefined, nestedSchema=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L6346 "View in source") [Ⓣ][1]
(Function): pass the property & schema in, get a nestable typeValidator out
-#### Since
+
+#### @Since
4.0.0-alpha.1
#### Arguments
@@ -7104,12 +9215,15 @@ input = {
-# scopedEncase(fnToEncase=undefined, [type=undefined], [specification=undefined])
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L3979 "View in source") [Ⓣ][1]
+scopedEncase(fnToEncase=undefined, [type=undefined], [specification=undefined])
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L6812 "View in source") [Ⓣ][1]
Function
-#### Since
+
+#### @Since
4.0.0-beta.1
#### Arguments
@@ -7141,12 +9255,15 @@ const encased = scopedEncase(fnToEncase).onValid(onValid).onInvalid(onInvalid)
-# set(x=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L140 "View in source") [Ⓣ][1]
+set(x=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L719 "View in source") [Ⓣ][1]
(Function): Checks if `value` is classified as a `Set` object.
-#### Since
+
+#### @Since
4.3.0
#### Arguments
@@ -7176,12 +9293,15 @@ isSet(new WeakSet())
-# set$$2(key=undefined, [prop=undefined], [value=undefined])
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L1620 "View in source") [Ⓣ][1]
+set$$2(key=undefined, [prop=undefined], [value=undefined])
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2566 "View in source") [Ⓣ][1]
Function
-#### Since
+
+#### @Since
4.0.0
#### Arguments
@@ -7204,12 +9324,15 @@ Function
-# setChosen(keyToSet=undefined, valueToSet=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L5311 "View in source") [Ⓣ][1]
+setChosen(keyToSet=undefined, valueToSet=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L8214 "View in source") [Ⓣ][1]
(Function): when fn is a full method, not an extended shorthand
-#### Since
+
+#### @Since
0.5.0
#### Arguments
@@ -7248,59 +9371,38 @@ parent.get('oh')
-# simpleKindOf(x=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L984 "View in source") [Ⓣ][1]
+simpleKindOf(x=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L1705 "View in source") [Ⓣ][1]
(Function): when Array -> 'array' when null -> 'null' else `typeof x`
-#### Arguments
-1. `x=undefined` *(any)*:
-
-#### Returns
-*(string)*: type
-
----
-
-
-
-
-
-
-
-## `state`
-
-
-# state
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2505 "View in source") [Ⓣ][1]
+#### @todos
-(Object): Each method that takes a callback has a context *(its this object)* with these attributes:
-
-
-### @classProps
-
-* {isRoot} @alias isNotRoot Whether or not the present node is a leaf node (has no children)
+- [ ] `type.split(' ').pop().replace(/\s\[\]/g, '').toLowerCase()`
----
-
-
-
-
-
-
-## `stop`
-
-
-
-# stop()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2629 "View in source") [Ⓣ][1]
+#### @Since
+4.0.0
-Function
+#### Arguments
+1. `x=undefined` *(any)*: value for type
#### Returns
-*(void)*:
+*(string)*: type
+
+
+split at space, replace brackets and space, lowercase
+#### Example
+```js
+simpleKindOf([]) //=> 'array'
+simpleKindOf(null) //=> 'null'
+simpleKindOf({}) //=> 'object'
+
+```
---
@@ -7313,13 +9415,15 @@ Function
-# test
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L6373 "View in source") [Ⓣ][1]
+test
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L9134 "View in source") [Ⓣ][1]
unknown
-### @todos
+#### @todos
- [ ] replace to-test
@@ -7335,8 +9439,10 @@ unknown
-# this.extend()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L4436 "View in source") [Ⓣ][1]
+this.extend()
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L7330 "View in source") [Ⓣ][1]
Function
@@ -7363,18 +9469,23 @@ chain
-🌊 Types: deps.d
+* 🌊 Types: deps.d
+* 🌊 Types: deps.encase.d
+* 🌊 Types: deps.reduce.d
-# toArr(ar=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L1514 "View in source") [Ⓣ][1]
+toArr(ar=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2361 "View in source") [Ⓣ][1]
(Function): anything into an array
-### @sig
+#### @sig
* => Array
-#### Since
+
+#### @Since
0.0.1
#### Arguments
@@ -7424,17 +9535,20 @@ toarr('').concat(toarr(false)).concat(toarr(null))
-# toTest(matchable=undefined, [arg1=undefined], [arg2=undefined])
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L6868 "View in source") [Ⓣ][1]
+toTest(matchable=undefined, [arg1=undefined], [arg2=undefined])
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L9647 "View in source") [Ⓣ][1]
(Function): like matcher, but .isMatch
-### @notes
+#### @notes
* as else-if for easier ternary uglification
-#### Since
+
+#### @Since
3.0.0
#### Arguments
@@ -7482,36 +9596,20 @@ matcher({ test: x => x === 'kinga' }, 'nope')
-# traverse(obj=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L4 "View in source") [Ⓣ][1]
-
-Function
-
-#### Arguments
-1. `obj=undefined` *(Traversable)*: object to traverse
-
-#### Example
-```js
-traverse({})
-//=> new Traverse(obj)
-
-```
----
-
-
-
-
-
-# traverse([useThis=false])
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L7127 "View in source") [Ⓣ][1]
+traverse([useThis=false])
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L9954 "View in source") [Ⓣ][1]
(Function): traverse `this`, or `this.entries`
-### @see
+#### @see
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-#### Since
+* TraverseChain
+* js-traverse
+
+#### @Since
1.0.2
#### Arguments
@@ -7532,109 +9630,23 @@ TAKE FROM TRAVERSECHAIN
-## `traverse.prototype`
-
-
-
-* 🌊 Types: TraverseChain.d
-* 🌊 Types: traverse.d
-
-# traverse.prototype.eq(a=undefined, b=undefined, [loose=false])
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L6030 "View in source") [Ⓣ][1]
-
-(Function): deep traversal of nodes to compare any data types does not check reference, only value equality
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-
-### @symb
-
-⚖️
-#### Since
-3.0.0
-
-#### Arguments
-1. `a=undefined` *(any)*: compare a with b
-2. `b=undefined` *(any)*: compare b with a
-3. `[loose=false]` *(boolean)*: whether to do looser equals check
-
-#### Returns
-*(boolean)*: isEqual
-
-#### Example
-```js
-eq(1, 1)
-//=> true
-
-eq(true, false)
-//=> false
-
-eq({}, {})
-//=> true
-
-```
-#### Example
-```js
-eq(
- { d: new Date(0, 0, 0, 0), x: [1, 2, 3] },
- { d: new Date(0, 0, 0, 0), x: [1, 2, 3] }
-)
-//=> true
-
-eq([new RegExp('x')], [/x/])
-//=> true
-
-eq([new String('x')], ['x'])
-//=> true
-
-eq([new Boolean(false)], [false])
-//=> true
-
-eq([undefined], [null]) || eq(undefined, null)
-//=> false
-
-```
-#### Example
-```js
-var xs = [1, 2, 3, 4]
-delete xs[2]
-
-var ys = Object.create(Array.prototype)
-ys[0] = 1
-ys[1] = 2
-ys[3] = 4
-
-eq(xs, ys)
-//=> true
-
-eq(xs, [1, 2, undefined, 4])
-//=> false
-
-```
----
-
-
-
-
-
-
-
## `traversed`
-# traversed()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L7075 "View in source") [Ⓣ][1]
+traversed()
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L9889 "View in source") [Ⓣ][1]
(Function): value traversed in traverse
-### @see
+#### @see
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-#### Since
+* TraverseChain.traverse
+
+#### @Since
1.0.0
#### Returns
@@ -7703,43 +9715,19 @@ const eh = {
-## `tryCatch`
-
-
-
-# tryCatch(call=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L3863 "View in source") [Ⓣ][1]
-
-Function
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-#### Arguments
-1. `call=undefined` *(Function)*:
-
-#### Returns
-*(*)*: validation/encased function call result
-
----
-
-
-
-
-
-
-
## `typedOnCall`
-# typedOnCall(arg=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L4013 "View in source") [Ⓣ][1]
+typedOnCall(arg=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L6846 "View in source") [Ⓣ][1]
(Function): this is the actual built function
-#### Since
+
+#### @Since
4.0.0-beta.1
#### Arguments
@@ -7767,8 +9755,10 @@ const encased = encase(fnToEncase)
-# types(name=undefined, parent=undefined, built=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L4051 "View in source") [Ⓣ][1]
+types(name=undefined, parent=undefined, built=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L6896 "View in source") [Ⓣ][1]
Function
@@ -7788,43 +9778,25 @@ Function
-## `update`
-
-
-
-# update(x=undefined, stopHere=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2556 "View in source") [Ⓣ][1]
-
-(Function): Set a new value for the present node.
-All the elements in value will be recursively traversed unless stopHere is true.
-
-#### Arguments
-1. `x=undefined` *(Function)*:
-2. `stopHere=undefined` *(boolean)*:
-
-#### Returns
-*(void)*:
-
----
-
-
-
-
+## `util`
-## `updateState`
-
-
+util.assign
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L7 "View in source") [Ⓣ][1]
-# updateState()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2653 "View in source") [Ⓣ][1]
+Function
-(Function): updates if needed:
-#### Returns
-*(void)*:
+#### @see
+* react-object-assign
+* ramda-assign
+* lodash-assign
+* esdiscuss-object-assign
+* mozilla-object-assign
---
@@ -7837,8 +9809,10 @@ All the elements in value will be recursively traversed unless stopHere is true.
-# validators(validators=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L3271 "View in source") [Ⓣ][1]
+validators(validators=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L6044 "View in source") [Ⓣ][1]
(Function): library of validators to use by name
@@ -7853,85 +9827,14 @@ All the elements in value will be recursively traversed unless stopHere is true.
-## `values`
-
-
-
-# values()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L31 "View in source") [Ⓣ][1]
-
-(Function): spreads the entries from ChainedMap.store.values allocates a new array, adds the values from the iterator
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-
-### @notes
-
-* look at Chainable.constructor to ensure not to use `new Array...`
-* moved from ChainedMap and ChainedSet to Chainable @2.0.2
-* this was [...] & Array.from(this.store.values())
-
-#### Since
-0.4.0
-
-#### Returns
-*(*): toArr(this.store.values())*
-
-#### Example
-```js
-const chain = new Chain()
-chain.set('eh', 1)
-chain.values()
-//=> [1]
-
-```
----
-
-
-
-
-
-
-
-## `when`
-
-
-
-# when(condition=undefined, [trueBrancher=Function], [falseBrancher=Function])
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L458 "View in source") [Ⓣ][1]
-
-(Function): when the condition is true, trueBrancher is called, else, falseBrancher is called
-
-#### Arguments
-1. `condition=undefined` *(boolean|string)*: when string, checks this.get
-2. `[trueBrancher=Function]` *(Function)*: called when true
-3. `[falseBrancher=Function]` *(Function)*: called when false
-
-#### Returns
-*(Chainable)*: @chainable
-
-#### Example
-```js
-const prod = process.env.NODE_ENV === 'production'
-chains.when(prod, c => c.set('prod', true), c => c.set('prod', false))
-
-```
----
-
-
-
-
-
-
-
## `while`
-# while()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2883 "View in source") [Ⓣ][1]
+while()
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L3550 "View in source") [Ⓣ][1]
Function
@@ -7961,4 +9864,4 @@ Function
- [1]: #cm "Jump back to the TOC."
+ [1]: #chainable "Jump back to the TOC."
diff --git a/docs/docdown/compose/DotProp.md b/docs/docdown/compose/DotProp.md
index 8c491bd..2f951a0 100644
--- a/docs/docdown/compose/DotProp.md
+++ b/docs/docdown/compose/DotProp.md
@@ -4,38 +4,38 @@
-## `DotProp.prototype`
-* `DotProp.prototype.get`
-* `DotProp.prototype.set`
+## `DotProp`
+* `DotProp.get`
+* `DotProp.set`
-## `Observe.prototype`
-* `Observe.prototype.exports`
+## `Observe`
+* `Observe.exports`
## `delete`
-* `delete`
+* `delete`
## `dot`
-* `dot`
-* `dot`
+* `dot`
+* `dot`
## `has`
-* `has`
+* `has`
@@ -45,26 +45,30 @@
-## `DotProp.prototype`
+## `DotProp`
-# DotProp.prototype.get(key=undefined, [fallback=undefined])
+DotProp.get(key=undefined, [fallback=undefined])
+
+
[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/compose/DotProp.js#L199 "View in source") [Ⓣ][1]
(Function): dot-prop enabled get
-### @see
+#### @see
-* fluents/chain able/blob/master/src/deps/dot/delete.js
-* fluents/chain able/blob/master/src/deps/is/dot.js
+* ChainedMap.get
+* deps/dot
+* deps/is/dot
-### @todos
+#### @todos
- [ ] dot-prop on non-store instance.property when using nested chains...
-#### Since
+
+#### @Since
3.0.1
#### Arguments
@@ -99,17 +103,20 @@ chain.get(['moose', 'simple'])
-# DotProp.prototype.set
+DotProp.set
+
+
[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/compose/DotProp.js#L141 "View in source") [Ⓣ][1]
unknown
-### @see
+#### @see
+
+* TargetedMap.set
+* .dot
-* fluents/chain able/blob/master/src/deps/dot/delete.js
-* fluents/chain able/blob/master/src/deps/is/dot.js
-#### Since
+#### @Since
3.0.1
#### Example
@@ -128,29 +135,30 @@ chain.set('moose.simple', 1)
-## `Observe.prototype`
+## `Observe`
🔬 Tests: DotProp
-# Observe.prototype.exports(Chain=undefined)
+Observe.exports(Target=undefined)
+
+
[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/compose/DotProp.js#L88 "View in source") [Ⓣ][1]
Function
-### @see
+#### @see
-* fluents/chain able/blob/master/src/deps/dot/delete.js
-* fluents/chain able/blob/master/src/deps/is/dot.js
+* deps/dot
-### @extends
+#### @extends
ChainedMap
#### Arguments
-1. `Chain=undefined` *(Class|Composable)*: composable class
+1. `Target=undefined` *(Class|Composable)*: composable class
#### Returns
*(DotProp)*: class
@@ -200,17 +208,20 @@ chain.get(['moose', 'canada', 'igloo'])
-# delete
+delete
+
+
[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/compose/DotProp.js#L255 "View in source") [Ⓣ][1]
unknown
-### @see
+#### @see
+
+* deps/dot
+* deps/is/dot
-* fluents/chain able/blob/master/src/deps/dot/delete.js
-* fluents/chain able/blob/master/src/deps/is/dot.js
-#### Since
+#### @Since
3.0.1
#### Example
@@ -242,12 +253,15 @@ chain.has('moose.canada')
-# dot
+dot
+
+
[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/compose/DotProp.js#L4 "View in source") [Ⓣ][1]
unknown
-#### Since
+
+#### @Since
2.0.0
---
@@ -256,17 +270,19 @@ unknown
-# dot([useDot=undefined])
+dot([useDot=undefined])
+
+
[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/compose/DotProp.js#L116 "View in source") [Ⓣ][1]
Function
-### @see
+#### @see
+
+* deps/meta
-* fluents/chain able/blob/master/src/deps/dot/delete.js
-* fluents/chain able/blob/master/src/deps/is/dot.js
-#### Since
+#### @Since
3.0.1
#### Arguments
@@ -297,17 +313,20 @@ toArr(chain.store.keys())
-# has
+has
+
+
[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/compose/DotProp.js#L222 "View in source") [Ⓣ][1]
unknown
-### @see
+#### @see
+
+* deps/dot
+* deps/is/dot
-* fluents/chain able/blob/master/src/deps/dot/delete.js
-* fluents/chain able/blob/master/src/deps/is/dot.js
-#### Since
+#### @Since
3.0.1
#### Example
@@ -325,4 +344,4 @@ chain.has('one.two')
- [1]: #dotprop.prototype "Jump back to the TOC."
+ [1]: #dotprop "Jump back to the TOC."
diff --git a/docs/docdown/compose/Observe.md b/docs/docdown/compose/Observe.md
index 77c8d78..4193854 100644
--- a/docs/docdown/compose/Observe.md
+++ b/docs/docdown/compose/Observe.md
@@ -4,9 +4,9 @@
-## `Observe.prototype`
-* `Observe.prototype.`
-* `Observe.prototype.exports`
+## `Observe`
+* `Observe.`
+* `Observe.exports`
@@ -16,17 +16,27 @@
-## `Observe.prototype`
+## `Observe`
-# Observe.prototype.observe(properties=undefined, fn=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/compose/Observe.js#L46 "View in source") [Ⓣ][1]
+Observe.observe(properties=undefined, fn=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/compose/Observe.js#L48 "View in source") [Ⓣ][1]
(Function): observe properties when they change
-### @todos
+#### @see
+
+* traversers/eq
+* toarr
+* matcher
+*
+* examples/playground/TodoStore
+
+#### @todos
- [ ] gotta update `data` if `deleting` too...
- [ ] un-observe
@@ -75,23 +85,40 @@ chain
🔬 Tests: observe
-# Observe.prototype.exports(Chain=undefined)
+Observe.exports(Target=undefined)
+
+
[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/compose/Observe.js#L38 "View in source") [Ⓣ][1]
(Function): > subscribe to changes ❗ called only on **change** observers are only called when data they subscribe to changes
-### @extends
+#### @see
+
+* ChainedMap
+* DotProp
+* deps/matcher
+* deps/traversers/eq
+* deps/traverse
+* DotProp
+* reactivex
+* awesome-observables
+* building-observables
+* observer-pattern
+* observable-air
+
+#### @extends
* ChainedMap
* DotProp
-#### Since
+
+#### @Since
3.0.1
#### Arguments
-1. `Chain=undefined` *(Class|Composable)*: composable class
+1. `Target=undefined` *(Class|Composable)*: composable class
#### Returns
*(Observe)*: class
@@ -112,4 +139,4 @@ new DotProp()
- [1]: #observe.prototype "Jump back to the TOC."
+ [1]: #observe "Jump back to the TOC."
diff --git a/docs/docdown/compose/Shorthands.md b/docs/docdown/compose/Shorthands.md
index 124f920..e7b42b4 100644
--- a/docs/docdown/compose/Shorthands.md
+++ b/docs/docdown/compose/Shorthands.md
@@ -4,31 +4,31 @@
-## `ShorthandChain.prototype`
-* `ShorthandChain.prototype.return`
-* `ShorthandChain.prototype.setIfEmpty`
-* `ShorthandChain.prototype.wrap`
+## `ShorthandChain`
+* `ShorthandChain.return`
+* `ShorthandChain.setIfEmpty`
+* `ShorthandChain.wrap`
-## `Shorthands.prototype`
-* `Shorthands.prototype.exports`
+## `Shorthands`
+* `Shorthands.exports`
## `debug`
-* `debug`
+* `debug`
## `isUndefined`
-* `isUndefined`
+* `isUndefined`
@@ -38,16 +38,19 @@
-## `ShorthandChain.prototype`
+## `ShorthandChain`
-# ShorthandChain.prototype.return(value=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/compose/Shorthands.js#L175 "View in source") [Ⓣ][1]
+ShorthandChain.return(value=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/compose/Shorthands.js#L176 "View in source") [Ⓣ][1]
(Function): returns any value passed in return a value at the end of a chain regardless
-#### Since
+
+#### @Since
3.0.0
#### Arguments
@@ -73,12 +76,19 @@ console.log(saveAndDebug(process.env))
-# ShorthandChain.prototype.setIfEmpty(name=undefined, value=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/compose/Shorthands.js#L149 "View in source") [Ⓣ][1]
+ShorthandChain.setIfEmpty(name=undefined, value=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/compose/Shorthands.js#L150 "View in source") [Ⓣ][1]
(Function): sets a value **only** when .has is false aka set if the value has not been set
-#### Since
+
+#### @see
+
+* ChainedMapBase.set
+
+#### @Since
1.0.2
#### Arguments
@@ -124,12 +134,15 @@ chain.when(!chain.has('eh'), instance => instance.set('eh', false))
-# ShorthandChain.prototype.wrap(fn=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/compose/Shorthands.js#L208 "View in source") [Ⓣ][1]
+ShorthandChain.wrap(fn=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/compose/Shorthands.js#L209 "View in source") [Ⓣ][1]
(Function): wrap a value, if it's a Function call it, return this aka execute something and return this
-#### Since
+
+#### @Since
2.0.0
#### Arguments
@@ -170,26 +183,40 @@ new Chain()
-## `Shorthands.prototype`
+## `Shorthands`
🔬 Tests: shorthands
-# Shorthands.prototype.exports(SuperClass=undefined)
+Shorthands.exports(Target=undefined)
+
+
[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/compose/Shorthands.js#L30 "View in source") [Ⓣ][1]
Function
-### @extends
+#### @see
+
+* ChainedMap
+* DotProp
+* deps/matcher
+* deps/traversers/eq
+* deps/traverse
+* DotProp
+* reactivex
+* awesome-observables
+* building-observables
+
+#### @extends
* ChainedMap
* DotProp
#### Arguments
-1. `SuperClass=undefined` *(Class|Composable)*: composable class
+1. `Target=undefined` *(Class|Composable)*: composable class
#### Returns
*(Shorthands)*: class
@@ -214,13 +241,15 @@ new DotProp()
-# debug([should=true])
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/compose/Shorthands.js#L103 "View in source") [Ⓣ][1]
+debug([should=true])
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/compose/Shorthands.js#L104 "View in source") [Ⓣ][1]
(Function): sets on store not this.set for easier extension
-### @notes
+#### @notes
* is inherited by any chain with a parent with .meta.debug
@@ -256,12 +285,15 @@ chain.entries()
-# isUndefined
+isUndefined
+
+
[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/compose/Shorthands.js#L4 "View in source") [Ⓣ][1]
unknown
-#### Since
+
+#### @Since
2.0.0
---
@@ -272,4 +304,4 @@ unknown
- [1]: #shorthandchain.prototype "Jump back to the TOC."
+ [1]: #shorthandchain "Jump back to the TOC."
diff --git a/docs/docdown/compose/Transform.md b/docs/docdown/compose/Transform.md
index 5a9e0d6..d2d531e 100644
--- a/docs/docdown/compose/Transform.md
+++ b/docs/docdown/compose/Transform.md
@@ -4,25 +4,25 @@
-## `TransformChain.prototype`
-* `TransformChain.prototype.`
-* `TransformChain.prototype.remap`
-* `TransformChain.prototype.set`
-* `TransformChain.prototype.transform`
+## `TransformChain`
+* `TransformChain.`
+* `TransformChain.remap`
+* `TransformChain.set`
+* `TransformChain.transform`
## `exports`
-* `exports`
+* `exports`
## `traverse`
-* `traverse`
+* `traverse`
@@ -32,23 +32,30 @@
-## `TransformChain.prototype`
+## `TransformChain`
🔬 Tests: TransformChain
-
+
+
+
[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/compose/Transform.js#L8 "View in source") [Ⓣ][1]
Map
-### @symb
+#### @see
+
+* deps/traverse
+* TraverseChain
+
+#### @symb
🤖
-### @extends
+#### @extends
ChainedMap
@@ -58,16 +65,23 @@ ChainedMap
-
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/compose/Transform.js#L183 "View in source") [Ⓣ][1]
+
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/compose/Transform.js#L210 "View in source") [Ⓣ][1]
(Function): remap properties from `1` to another, for example, apis with inconsistent naming
-### @symb
+#### @see
+
+* TransformChain.transform
+
+#### @symb
🗺
-#### Since
+
+#### @Since
1.0.0
#### Arguments
@@ -100,12 +114,19 @@ chain
-
+
+
+
[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/compose/Transform.js#L124 "View in source") [Ⓣ][1]
Function
-#### Since
+
+#### @see
+
+*
+
+#### @Since
1.0.0
#### Arguments
@@ -122,17 +143,20 @@ Function
-
+
+
+
[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/compose/Transform.js#L106 "View in source") [Ⓣ][1]
Function
-### @todos
+#### @todos
- [ ] dot-prop here
-#### Since
+
+#### @Since
1.0.2
#### Arguments
@@ -182,13 +206,15 @@ const { created_at } = chain.entries()
-# exports(SuperClass=undefined)
+exports(Target=undefined)
+
+
[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/compose/Transform.js#L18 "View in source") [Ⓣ][1]
Function
#### Arguments
-1. `SuperClass=undefined` *(Class|Composable)*: composable class
+1. `Target=undefined` *(Class|Composable)*: composable class
#### Returns
*(TransformChain)*: class
@@ -211,12 +237,20 @@ compose(class {})
-# traverse([useThis=false])
+traverse([useThis=false])
+
+
[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/compose/Transform.js#L56 "View in source") [Ⓣ][1]
(Function): traverse `this`, or `this.entries`
-#### Since
+
+#### @see
+
+* TraverseChain
+* js-traverse
+
+#### @Since
1.0.2
#### Arguments
@@ -237,4 +271,4 @@ TAKE FROM TRAVERSECHAIN
- [1]: #transformchain.prototype "Jump back to the TOC."
+ [1]: #transformchain "Jump back to the TOC."
diff --git a/docs/docdown/compose/compose.md b/docs/docdown/compose/compose.md
index fba866c..32e8931 100644
--- a/docs/docdown/compose/compose.md
+++ b/docs/docdown/compose/compose.md
@@ -4,8 +4,8 @@
-## `compose.prototype`
-* `compose.prototype.compose`
+## `compose`
+* `compose.compose`
@@ -15,7 +15,7 @@
-## `compose.prototype`
+## `compose`
@@ -23,16 +23,28 @@
🔬 Tests: compose
-# compose.prototype.compose([target=ChainedMap], [extensions=[Observe,Shorthands,Transform,DotProp]])
+compose.compose([target=ChainedMap], [extensions=[Observe,Shorthands,Transform,DotProp]])
+
+
[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/compose/compose.js#L70 "View in source") [Ⓣ][1]
(Function): compose chains all the way up from Chainable
-### @symb
+#### @see
+
+* https://formidable.com/blog/2017/infinite-state-composition-with-freactal/
+* https://blog.javascripting.com/2016/02/02/encapsulation-in-redux/
+* https://www.barbarianmeetscoding.com/blog/2016/01/04/safer-javascript-object-composition-with-traits-and-traits-dot-js/
+* https://medium.com/javascript-scene/why-learn-functional-programming-in-javascript-composing-software-ea13afc7a257
+* https://hackernoon.com/javascript-functional-composition-for-every-day-use-22421ef65a10
+* https://github.com/stoeffel/awesome-fp-js
+
+#### @symb
🎼
-#### Since
+
+#### @Since
3.0.0
#### Arguments
@@ -87,4 +99,4 @@ yes instanceof Winning && yes.winning
- [1]: #compose.prototype "Jump back to the TOC."
+ [1]: #compose "Jump back to the TOC."
diff --git a/docs/docdown/deps/argumentor.md b/docs/docdown/deps/argumentor.md
index 1178b7a..4f9ea25 100644
--- a/docs/docdown/deps/argumentor.md
+++ b/docs/docdown/deps/argumentor.md
@@ -4,8 +4,8 @@
-## `exports`
-* `exports`
+## `argumentor`
+* `argumentor`
@@ -15,16 +15,25 @@
-## `exports`
+## `argumentor`
-# exports()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/argumentor.js#L23 "View in source") [Ⓣ][1]
+argumentor()
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/argumentor.js#L25 "View in source") [Ⓣ][1]
(Function): turns arguments into an array, used as a util, for opt
-#### Since
+
+#### @see
+
+* https://github.com/aretecode/awesome-deopt
+* https://github.com/petkaantonov/bluebird/wiki/Optimization-killers
+* deps/util/lengthFromZero
+
+#### @Since
3.0.0
#### Returns
@@ -49,4 +58,4 @@ eh(0, 1, 10, 100)
- [1]: #exports "Jump back to the TOC."
+ [1]: #argumentor "Jump back to the TOC."
diff --git a/docs/docdown/deps/array/concat.md b/docs/docdown/deps/array/concat.md
new file mode 100644
index 0000000..438303d
--- /dev/null
+++ b/docs/docdown/deps/array/concat.md
@@ -0,0 +1,61 @@
+# concat.js API documentation
+
+
+
+
+
+## `concat`
+* `concat`
+
+
+
+
+
+
+
+
+
+## `concat`
+
+
+
+concat(one=undefined, two=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/array/concat.js#L27 "View in source") [Ⓣ][1]
+
+(Function): concat two values, coerce to arrays
+
+
+#### @Since
+4.0.0
+
+#### Arguments
+1. `one=undefined` *(*|Array)*: toArr1
+2. `two=undefined` *(*|Array)*: toArr2
+
+#### Returns
+*(Array)*: [one, two]
+
+#### Example
+```js
+concat([1], [2]) //=> [1, 2]
+concat([1], 2) //=> [1, 2]
+concat(1, 2) //=> [1, 2]
+concat(new Set([1]), 2) //=> [1, 2]
+
+// kind of weird...
+concat(null, 2) //=> [2]
+concat(undefined, 2) //=> [2]
+concat(1, null) //=> [1, null]
+
+```
+---
+
+
+
+
+
+
+
+ [1]: #concat "Jump back to the TOC."
diff --git a/docs/docdown/deps/array/insertAtIndex.md b/docs/docdown/deps/array/insertAtIndex.md
new file mode 100644
index 0000000..7d9f92d
--- /dev/null
+++ b/docs/docdown/deps/array/insertAtIndex.md
@@ -0,0 +1,60 @@
+# insertAtIndex.js API documentation
+
+
+
+
+
+## `exports`
+* `exports`
+
+
+
+
+
+
+
+
+
+## `exports`
+
+
+
+exports(arr=undefined, index=undefined, val=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/array/insertAtIndex.js#L26 "View in source") [Ⓣ][1]
+
+(Function): put a value at any index in an array
+
+
+#### @see
+
+* http://stackoverflow.com/questions/7032550/javascript-insert-an-array-inside-another-array
+* http://stackoverflow.com/questions/1348178/a-better-way-to-splice-an-array-into-an-array-in-javascript/41465578#41465578
+* http://stackoverflow.com/questions/38060705/replace-element-at-specific-position-in-an-array-without-mutating-it
+
+#### @Since
+? was in insert-at-index dep...
+
+#### Arguments
+1. `arr=undefined` *(Array)*: array to put value in at index
+2. `index=undefined` *(number)*: index to put valu eat
+3. `val=undefined` *(*)*: value to put at index
+
+#### Returns
+*(*)*: array with new value at index
+
+#### Example
+```js
+insertAtIndex(['zero-1', 'one-2'], 1, 1) //=> ['zero-1', 1, 'one-two']
+
+```
+---
+
+
+
+
+
+
+
+ [1]: #exports "Jump back to the TOC."
diff --git a/docs/docdown/deps/array/uniq.md b/docs/docdown/deps/array/uniq.md
index 9005e92..b501676 100644
--- a/docs/docdown/deps/array/uniq.md
+++ b/docs/docdown/deps/array/uniq.md
@@ -2,10 +2,60 @@
+
+
+## `uniqFilter`
+* `uniqFilter`
+
+
+
+
+
+## `uniqFilter`
+
+
+
+uniqFilter(value=undefined, index=undefined, arr=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/array/uniq.js#L18 "View in source") [Ⓣ][1]
+
+Function
+
+
+#### @see
+
+* mozilla-array-filter
+
+#### @Since
+0.1.0
+
+#### Arguments
+1. `value=undefined` *(*)*: value in array iteration
+2. `index=undefined` *(number)*: current index
+3. `arr=undefined` *(Array)*: array being iterated, `thisArg` when using .filter
+
+#### Returns
+*(Array)*: arr
+
+#### Example
+```js
+var list = [1, 2, 3, 1, 2, 3, 1, 2, 3]
+
+list.filter(uniq)
+//=> [1, 2, 3]
+
+```
+---
+
+
+
+
+
- [1]: # "Jump back to the TOC."
+ [1]: #uniqfilter "Jump back to the TOC."
diff --git a/docs/docdown/deps/cache/pooler.md b/docs/docdown/deps/cache/pooler.md
new file mode 100644
index 0000000..6370e12
--- /dev/null
+++ b/docs/docdown/deps/cache/pooler.md
@@ -0,0 +1,165 @@
+# pooler.js API documentation
+
+
+
+
+
+## `pooler`
+* `pooler.addPoolingTo`
+* `pooler.oneArgumentPooler`
+* `pooler.standardReleaser`
+
+
+
+
+
+## `pooler.DEFAULT_POOLER`
+* `pooler.DEFAULT_POOLER`
+
+
+
+
+
+
+
+
+
+## `pooler`
+
+
+
+pooler.addPoolingTo(CopyConstructor=undefined, pooler=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/cache/pooler.js#L109 "View in source") [Ⓣ][1]
+
+(Function): Augments `CopyConstructor` to be a poolable class, augmenting only the class
+itself *(statically)* not adding any prototypical fields. Any CopyConstructor
+you give this may have a `poolSize` property, and will look for a
+prototypical `destructor` on instances.
+
+
+#### @Since
+5.0.0
+
+#### Arguments
+1. `CopyConstructor=undefined` *(Function|Object)*: Constructor that can be used to reset.
+2. `pooler=undefined` *(Function)*: Customizable pooler.
+
+#### Returns
+*(Object)*: enhanced constructor, decorated with pooler
+
+#### Example
+```js
+class Eh {}
+addPoolingTo(Eh) // can optionally pass in pooler as second arg
+//=> Eh.instancePool = []
+//=> Eh.getPooled = pooler || singleArgumentPooler
+//=> Eh.poolSize = 10
+//=> Eh.release = standardReleaser
+
+```
+---
+
+
+
+
+
+pooler.oneArgumentPooler(copyFieldsFrom=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/cache/pooler.js#L60 "View in source") [Ⓣ][1]
+
+(Function): Static poolers. Several custom versions for each potential number of
+arguments. A completely generic pooler is easy to implement, but would
+require accessing the `arguments` object. In each of these, `this` refers to
+the Class itself, not an instance. If any others are needed, simply add them
+here, or in their own files.
+
+
+#### @Since
+5.0.0
+
+#### Arguments
+1. `copyFieldsFrom=undefined` *(Object)*: obj with instance pool
+
+#### Returns
+*(Object)*: instance of Klass
+
+#### Example
+```js
+class Eh {}
+addPoolingTo(Eh)
+const eh = Eh.getPooled() //=> oneArgumentPooler(Eh)
+eh.release()
+
+```
+---
+
+
+
+
+
+pooler.standardReleaser(instance=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/cache/pooler.js#L21 "View in source") [Ⓣ][1]
+
+(Function): call destructor on a pooled instance, put it back in the pool
+
+
+#### @Since
+5.0.0
+
+#### Arguments
+1. `instance=undefined` *(Object)*: call destructor
+
+#### Returns
+*(void)*:
+
+#### Example
+```js
+class Eh {}
+addPoolingTo(Eh)
+const eh = Eh.getPooled()
+eh.release()
+
+```
+---
+
+
+
+
+
+
+
+## `pooler.DEFAULT_POOLER`
+
+
+
+🔬 Tests: pooler
+
+pooler.DEFAULT_POOLER
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/cache/pooler.js#L7 "View in source") [Ⓣ][1]
+
+Object
+
+
+#### @see
+
+* react-pooler
+
+#### @symb
+
+🎱
+---
+
+
+
+
+
+
+
+ [1]: #pooler "Jump back to the TOC."
diff --git a/docs/docdown/deps/cache/scoped.md b/docs/docdown/deps/cache/scoped.md
index 38ed4a4..a3fcfc7 100644
--- a/docs/docdown/deps/cache/scoped.md
+++ b/docs/docdown/deps/cache/scoped.md
@@ -2,10 +2,36 @@
+
+
+## `scoped`
+* ``
+
+
+
+
+
+## `scoped`
+
+
+
+
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/cache/scoped.js#L100 "View in source") [Ⓣ][1]
+
+unknown
+
+---
+
+
+
+
+
- [1]: # "Jump back to the TOC."
+ [1]: #scoped "Jump back to the TOC."
diff --git a/docs/docdown/deps/camel-case.md b/docs/docdown/deps/camel-case.md
index 47ef511..2b44454 100644
--- a/docs/docdown/deps/camel-case.md
+++ b/docs/docdown/deps/camel-case.md
@@ -5,7 +5,7 @@
## `exports`
-* `exports`
+* `exports`
@@ -19,17 +19,20 @@
-# exports(str=undefined)
+exports(str=undefined)
+
+
[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/camel-case.js#L22 "View in source") [Ⓣ][1]
(Function): camelCase
-### @todos
+#### @todos
- [ ] s.charAt(0).toLowerCase() + string.slice(1)
-#### Since
+
+#### @Since
0.2.0
#### Arguments
diff --git a/docs/docdown/deps/class-names.md b/docs/docdown/deps/class-names.md
deleted file mode 100644
index e3f72e0..0000000
--- a/docs/docdown/deps/class-names.md
+++ /dev/null
@@ -1,45 +0,0 @@
-# class-names.js API documentation
-
-
-
-
-
-## `exports`
-* `exports`
-
-
-
-
-
-
-
-
-
-## `exports`
-
-
-
-# exports(_c)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/class-names.js#L6 "View in source") [Ⓣ][1]
-
-
-
-#### Arguments
-1. `_c` *(Object)*:
-
-#### Returns
-*(string)*:
-
-#### Example
-```js
-get className() {return classNames(this)}
-```
----
-
-
-
-
-
-
-
- [1]: #exports "Jump back to the TOC."
diff --git a/docs/docdown/deps/clean.md b/docs/docdown/deps/clean.md
deleted file mode 100644
index f49a210..0000000
--- a/docs/docdown/deps/clean.md
+++ /dev/null
@@ -1,44 +0,0 @@
-# clean.js API documentation
-
-
-
-
-
-## `exports`
-* `exports`
-
-
-
-
-
-
-
-
-
-## `exports`
-
-
-
-# exports(obj)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/clean.js#L17 "View in source") [Ⓣ][1]
-
-
-
-#### Since
-4.0.0 <- moved as a dep function
-
-#### Arguments
-1. `obj` *(Object): object to clean, usually .entries()*
-
-#### Returns
-*(Object)*:
-
----
-
-
-
-
-
-
-
- [1]: #exports "Jump back to the TOC."
diff --git a/docs/docdown/deps/concat.md b/docs/docdown/deps/concat.md
index a514a9c..026da3a 100644
--- a/docs/docdown/deps/concat.md
+++ b/docs/docdown/deps/concat.md
@@ -2,10 +2,60 @@
+
+
+## `concat`
+* `concat`
+
+
+
+
+
+## `concat`
+
+
+
+concat(one=undefined, two=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/concat.js#L27 "View in source") [Ⓣ][1]
+
+(Function): conat two values, coerce to arrays
+
+
+#### @Since
+4.0.0
+
+#### Arguments
+1. `one=undefined` *(*|Array)*: toArr1
+2. `two=undefined` *(*|Array)*: toArr2
+
+#### Returns
+*(Array)*: [one, two]
+
+#### Example
+```js
+concat([1], [2]) //=> [1, 2]
+concat([1], 2) //=> [1, 2]
+concat(1, 2) //=> [1, 2]
+concat(new Set([1]), 2) //=> [1, 2]
+
+// kind of weird...
+concat(null, 2) //=> [2]
+concat(undefined, 2) //=> [2]
+concat(1, null) //=> [1, null]
+
+```
+---
+
+
+
+
+
- [1]: # "Jump back to the TOC."
+ [1]: #concat "Jump back to the TOC."
diff --git a/docs/docdown/deps/conditional/all.md b/docs/docdown/deps/conditional/all.md
index f1568f3..b252628 100644
--- a/docs/docdown/deps/conditional/all.md
+++ b/docs/docdown/deps/conditional/all.md
@@ -4,8 +4,8 @@
-## `conditional.prototype`
-* `conditional.prototype.all`
+## `conditional`
+* `conditional.all`
@@ -15,20 +15,39 @@
-## `conditional.prototype`
+## `conditional`
-# conditional.prototype.all(predicate=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/conditional/all.js#L19 "View in source") [Ⓣ][1]
+conditional.all(predicate=undefined, array=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/conditional/all.js#L26 "View in source") [Ⓣ][1]
(Function): map all values in an array to see if all match
+Returns `true` if all elements of the list match the predicate, `false` if there are any that don't.
-#### Since
+
+#### @see
+
+* ramda-all
+* fp/curry
+
+#### @todos
+
+- [ ] `not(some)` ?
+
+
+#### @sig
+
+(a -> Boolean) -> [a] -> Boolean
+
+#### @Since
4.0.1
#### Arguments
1. `predicate=undefined` *(Function)*: match the value
+2. `array=undefined` *(Array)*: to match against predicate
#### Returns
*(boolean)*: all match predicate
@@ -51,4 +70,4 @@ const allBoolean = all(x => typeof x === 'boolean'q)
- [1]: #conditional.prototype "Jump back to the TOC."
+ [1]: #conditional "Jump back to the TOC."
diff --git a/docs/docdown/deps/conditional/and.md b/docs/docdown/deps/conditional/and.md
index 61cfd67..a7cb100 100644
--- a/docs/docdown/deps/conditional/and.md
+++ b/docs/docdown/deps/conditional/and.md
@@ -4,8 +4,8 @@
-## `conditional.prototype`
-* `conditional.prototype.exports`
+## `conditional`
+* `conditional.and`
@@ -15,16 +15,19 @@
-## `conditional.prototype`
+## `conditional`
-# conditional.prototype.exports(left=undefined, right=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/conditional/and.js#L23 "View in source") [Ⓣ][1]
+conditional.and(left=undefined, right=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/conditional/and.js#L29 "View in source") [Ⓣ][1]
(Function): first fn & second fn
-#### Since
+
+#### @Since
4.0.1
#### Arguments
@@ -56,4 +59,4 @@ both([1])
- [1]: #conditional.prototype "Jump back to the TOC."
+ [1]: #conditional "Jump back to the TOC."
diff --git a/docs/docdown/deps/is/eqeq.md b/docs/docdown/deps/conditional/eqeq.md
similarity index 100%
rename from docs/docdown/deps/is/eqeq.md
rename to docs/docdown/deps/conditional/eqeq.md
diff --git a/docs/docdown/deps/conditional/includes/all.md b/docs/docdown/deps/conditional/includes/all.md
index 4bbad8c..2ce7c3f 100644
--- a/docs/docdown/deps/conditional/includes/all.md
+++ b/docs/docdown/deps/conditional/includes/all.md
@@ -4,22 +4,22 @@
-## `arrayHasAll`
-* `arrayHasAll`
+## `arrayIncludesAll`
+* `arrayIncludesAll`
## `includesAll`
-* `includesAll`
+* `includesAll`
-## `strHasAll`
-* `strHasAll`
+## `stringIncludesAll`
+* `stringIncludesAll`
@@ -29,15 +29,21 @@
-## `arrayHasAll`
+## `arrayIncludesAll`
-# arrayHasAll(needles=undefined, haystack=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/conditional/includes/all.js#L24 "View in source") [Ⓣ][1]
+arrayIncludesAll(needles=undefined, haystack=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/conditional/includes/all.js#L28 "View in source") [Ⓣ][1]
Function
+
+#### @see
+
+* stringIncludesAll
#### Arguments
1. `needles=undefined` *(string[])*:
2. `haystack=undefined` *(string[])*:
@@ -57,18 +63,38 @@ Function
-# includesAll(needle=undefined, haystack=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/conditional/includes/all.js#L39 "View in source") [Ⓣ][1]
+includesAll(needle=undefined, haystack=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/conditional/includes/all.js#L54 "View in source") [Ⓣ][1]
Function
+
+#### @see
+
+* arrayIncludesAll
+* stringIncludesAll
+
+#### @Since
+4.0.0
+
#### Arguments
-1. `needle=undefined` *(string|string[])*:
-2. `haystack=undefined` *(string[])*:
+1. `needle=undefined` *(string|string[])*: everything in haystack is in this
+2. `haystack=undefined` *(string[])*: everything in this is in the needle
#### Returns
*(boolean)*:
+#### Example
+```js
+/// 'canada' and 'can' are both in it, so true
+includesAll('canada', ['canada', 'can'])
+includesAll(['eh'], 'e') //=> true
+includesAll(['eh'], 'nope') //=> false
+includesAll('eh', ['no', 'eh']) //=> false
+
+```
---
@@ -77,12 +103,14 @@ Function
-## `strHasAll`
+## `stringIncludesAll`
-# strHasAll(needle=undefined, haystack=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/conditional/includes/all.js#L9 "View in source") [Ⓣ][1]
+stringIncludesAll(needle=undefined, haystack=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/conditional/includes/all.js#L13 "View in source") [Ⓣ][1]
Function
@@ -93,6 +121,10 @@ Function
#### Returns
*(boolean)*:
+#### Example
+```js
+
+```
---
@@ -101,4 +133,4 @@ Function
- [1]: #arrayhasall "Jump back to the TOC."
+ [1]: #arrayincludesall "Jump back to the TOC."
diff --git a/docs/docdown/deps/conditional/includes/any.md b/docs/docdown/deps/conditional/includes/any.md
index 2281ee2..ad473d0 100644
--- a/docs/docdown/deps/conditional/includes/any.md
+++ b/docs/docdown/deps/conditional/includes/any.md
@@ -5,21 +5,21 @@
## `arrayHasAny`
-* `arrayHasAny`
+* `arrayHasAny`
## `includesAny`
-* `includesAny`
+* `includesAny`
## `strHasAny`
-* `strHasAny`
+* `strHasAny`
@@ -33,11 +33,17 @@
-# arrayHasAny(needles=undefined, haystack=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/conditional/includes/any.js#L27 "View in source") [Ⓣ][1]
+arrayHasAny(needles=undefined, haystack=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/conditional/includes/any.js#L26 "View in source") [Ⓣ][1]
Function
+
+#### @see
+
+* strHasAny
#### Arguments
1. `needles=undefined` *(string[])*:
2. `haystack=undefined` *(string[])*:
@@ -57,11 +63,18 @@ Function
-# includesAny(needle=undefined, haystack=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/conditional/includes/any.js#L47 "View in source") [Ⓣ][1]
+includesAny(needle=undefined, haystack=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/conditional/includes/any.js#L52 "View in source") [Ⓣ][1]
Function
+
+#### @see
+
+* arrayHasAny
+* strHasAny
#### Arguments
1. `needle=undefined` *(string|string[])*:
2. `haystack=undefined` *(string[])*:
@@ -69,6 +82,14 @@ Function
#### Returns
*(boolean)*:
+#### Example
+```js
+includesAny('eh', 'e') //=> true
+includesAny('eh', 'eh') //=> true
+includesAny(['eh'], 'e') //=> true
+includesAny(['eh'], 'nope') //=> false
+
+```
---
@@ -81,8 +102,10 @@ Function
-# strHasAny(needle=undefined, haystack=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/conditional/includes/any.js#L9 "View in source") [Ⓣ][1]
+strHasAny(needle=undefined, haystack=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/conditional/includes/any.js#L10 "View in source") [Ⓣ][1]
Function
diff --git a/docs/docdown/deps/is/pureObj.md b/docs/docdown/deps/conditional/includes/flipped.md
similarity index 81%
rename from docs/docdown/deps/is/pureObj.md
rename to docs/docdown/deps/conditional/includes/flipped.md
index b4f10f1..4c526ab 100644
--- a/docs/docdown/deps/is/pureObj.md
+++ b/docs/docdown/deps/conditional/includes/flipped.md
@@ -1,4 +1,4 @@
-# pureObj.js API documentation
+# flipped.js API documentation
diff --git a/docs/docdown/deps/conditional/includes/includes.md b/docs/docdown/deps/conditional/includes/includes.md
index c865ca9..b4fcab0 100644
--- a/docs/docdown/deps/conditional/includes/includes.md
+++ b/docs/docdown/deps/conditional/includes/includes.md
@@ -2,10 +2,61 @@
+
+
+## `includes`
+* `includes.includes`
+
+
+
+
+
+## `includes`
+
+
+
+includes.includes(haystack=undefined, needle=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/conditional/includes/includes.js#L21 "View in source") [Ⓣ][1]
+
+Function
+
+
+#### @see
+
+* mozilla-bitwise-not
+* conditional/includes/flipped
+
+#### @todos
+
+- [ ] `~haystack.indexOf(needle)`
+
+#### Arguments
+1. `haystack=undefined` *(Array|string)*: haystack includes needle
+2. `needle=undefined` *(*|string)*: needle in haystack
+
+#### Returns
+*(boolean)*: needle in haystack
+
+#### Example
+```js
+includes('eh', 'e') //=> true
+includes('eh', 'nope') //=> false
+includes(['eh'], 'eh') //=> true
+includes(['eh'], 'nope') //=> false
+
+```
+---
+
+
+
+
+
- [1]: # "Jump back to the TOC."
+ [1]: #includes "Jump back to the TOC."
diff --git a/docs/docdown/deps/conditional/index.md b/docs/docdown/deps/conditional/index.md
new file mode 100644
index 0000000..c767ad2
--- /dev/null
+++ b/docs/docdown/deps/conditional/index.md
@@ -0,0 +1,37 @@
+# index.js API documentation
+
+
+
+
+
+## `conditional.conditional`
+* `conditional.conditional`
+
+
+
+
+
+
+
+
+
+## `conditional.conditional`
+
+
+
+conditional.conditional
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/conditional/index.js#L13 "View in source") [Ⓣ][1]
+
+Object
+
+---
+
+
+
+
+
+
+
+ [1]: #conditional.conditional "Jump back to the TOC."
diff --git a/docs/docdown/deps/conditional/not.md b/docs/docdown/deps/conditional/not.md
index 3f95750..89f8480 100644
--- a/docs/docdown/deps/conditional/not.md
+++ b/docs/docdown/deps/conditional/not.md
@@ -4,8 +4,8 @@
-## `conditional.prototype`
-* `conditional.prototype.exports`
+## `conditional`
+* `conditional.not`
@@ -15,23 +15,33 @@
-## `conditional.prototype`
+## `conditional`
-# conditional.prototype.exports(fn=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/conditional/not.js#L20 "View in source") [Ⓣ][1]
+conditional.not(fn=undefined, x=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/conditional/not.js#L31 "View in source") [Ⓣ][1]
(Function): return a negated function
+A function wrapping a call to the given function in a `!` operation.
+It will:
+
+* return `true` when the underlying function would return a false-y value,
+
+* and `false` when it would return a truth-y one.
-#### Since
+
+#### @Since
4.0.1
#### Arguments
1. `fn=undefined` *(Function)*: any function
+2. `x=undefined` *(*)*: value to pass to function
#### Returns
-*(Function)*: !Function
+*(Function): !Function(x)*
#### Example
```js
@@ -53,4 +63,4 @@ falsed()
- [1]: #conditional.prototype "Jump back to the TOC."
+ [1]: #conditional "Jump back to the TOC."
diff --git a/docs/docdown/deps/conditional/or.md b/docs/docdown/deps/conditional/or.md
index fa6b7bf..7969ce3 100644
--- a/docs/docdown/deps/conditional/or.md
+++ b/docs/docdown/deps/conditional/or.md
@@ -4,8 +4,8 @@
-## `conditional.prototype`
-* `conditional.prototype.exports`
+## `conditional`
+* `conditional.or`
@@ -15,28 +15,34 @@
-## `conditional.prototype`
+## `conditional`
-# conditional.prototype.exports(left=undefined, right=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/conditional/or.js#L23 "View in source") [Ⓣ][1]
+conditional.or(left=undefined, right=undefined, x=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/conditional/or.js#L33 "View in source") [Ⓣ][1]
-(Function): first fn || second fn
+(Function): first fn || second fn, curried
-#### Since
+
+#### @Since
4.0.1
#### Arguments
1. `left=undefined` *(Function)*: first fn
2. `right=undefined` *(Function)*: second fn
+3. `x=undefined` *(*)*: value to pass into left & right, curried
#### Returns
*(boolean)*: one of the functions return truthy
#### Example
```js
-const either = or(x => x === false, x => x === true)
+const { isTrue, isFalse } = require('chain-able')
+
+const either = or(isFalse, isTrue)
either([true])
//=> true
@@ -47,6 +53,9 @@ either([new Boolean(true)])
either([1])
//=> false
+// because curried
+or(isTrue, isFalse, true) //=> true
+
```
---
@@ -56,4 +65,4 @@ either([1])
- [1]: #conditional.prototype "Jump back to the TOC."
+ [1]: #conditional "Jump back to the TOC."
diff --git a/docs/docdown/deps/conditional/some.md b/docs/docdown/deps/conditional/some.md
index 4217860..26fde46 100644
--- a/docs/docdown/deps/conditional/some.md
+++ b/docs/docdown/deps/conditional/some.md
@@ -4,8 +4,8 @@
-## `conditional.prototype`
-* `conditional.prototype.some`
+## `conditional`
+* `conditional.some`
@@ -15,23 +15,27 @@
-## `conditional.prototype`
+## `conditional`
-# conditional.prototype.some(predicate=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/conditional/some.js#L23 "View in source") [Ⓣ][1]
+conditional.some(predicate=undefined, arr=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/conditional/some.js#L29 "View in source") [Ⓣ][1]
-(Function): map all values in an array to see if **some** match
+(Function): map all values in an array to see if **some** match, curried
-#### Since
+
+#### @Since
4.0.1
#### Arguments
1. `predicate=undefined` *(Function)*: match the value
+2. `arr=undefined` *(Array|any)*: values to match on the predicate
#### Returns
-*(boolean)*: all match predicate
+*(boolean)*: **some** match predicate
#### Example
```js
@@ -54,4 +58,4 @@ const someBoolean = some(x => typeof x === 'boolean'q)
- [1]: #conditional.prototype "Jump back to the TOC."
+ [1]: #conditional "Jump back to the TOC."
diff --git a/docs/docdown/deps/uniq.md b/docs/docdown/deps/construct/map.md
similarity index 82%
rename from docs/docdown/deps/uniq.md
rename to docs/docdown/deps/construct/map.md
index 9005e92..2bf4eff 100644
--- a/docs/docdown/deps/uniq.md
+++ b/docs/docdown/deps/construct/map.md
@@ -1,4 +1,4 @@
-# uniq.js API documentation
+# map.js API documentation
diff --git a/docs/docdown/deps/prefix.md b/docs/docdown/deps/construct/regexp.md
similarity index 81%
rename from docs/docdown/deps/prefix.md
rename to docs/docdown/deps/construct/regexp.md
index 25d578a..214d545 100644
--- a/docs/docdown/deps/prefix.md
+++ b/docs/docdown/deps/construct/regexp.md
@@ -1,4 +1,4 @@
-# prefix.js API documentation
+# regexp.js API documentation
diff --git a/docs/docdown/deps/primitives/true.md b/docs/docdown/deps/construct/set.md
similarity index 82%
rename from docs/docdown/deps/primitives/true.md
rename to docs/docdown/deps/construct/set.md
index 7d1b9a9..e2a6d32 100644
--- a/docs/docdown/deps/primitives/true.md
+++ b/docs/docdown/deps/construct/set.md
@@ -1,4 +1,4 @@
-# true.js API documentation
+# set.js API documentation
diff --git a/docs/docdown/deps/define.md b/docs/docdown/deps/define.md
index 4ec9f2f..8b0d246 100644
--- a/docs/docdown/deps/define.md
+++ b/docs/docdown/deps/define.md
@@ -5,7 +5,7 @@
## `exports`
-* `exports`
+* `exports`
@@ -19,12 +19,15 @@
-# exports(obj=undefined, name=undefined, descriptor=undefined)
+exports(obj=undefined, name=undefined, descriptor=undefined)
+
+
[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/define.js#L19 "View in source") [Ⓣ][1]
(Function): default to configurable and enumerable, unless configured otherwise
-#### Since
+
+#### @Since
4.0.0
#### Arguments
diff --git a/docs/docdown/deps/dopemerge/dopemerge.md b/docs/docdown/deps/dopemerge/dopemerge.md
index f836f2f..d050f09 100644
--- a/docs/docdown/deps/dopemerge/dopemerge.md
+++ b/docs/docdown/deps/dopemerge/dopemerge.md
@@ -4,12 +4,11 @@
-## `dopemerge.prototype`
-* `dopemerge.prototype.cloneIfNeeded`
-* `dopemerge.prototype.defaultArrayMerge`
-* `dopemerge.prototype.dopemerge`
-* `dopemerge.prototype.emptyTarget`
-* `dopemerge.prototype.isMergeableObj`
+## `dopemerge`
+* `dopemerge.cloneIfNeeded`
+* `dopemerge.defaultArrayMerge`
+* `dopemerge.dopemerge`
+* `dopemerge.isMergeableObj`
@@ -19,21 +18,25 @@
-## `dopemerge.prototype`
+## `dopemerge`
-# dopemerge.prototype.cloneIfNeeded(value=undefined, optsArg=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/dopemerge/dopemerge.js#L90 "View in source") [Ⓣ][1]
+dopemerge.cloneIfNeeded(value=undefined, optsArg=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/dopemerge/dopemerge.js#L71 "View in source") [Ⓣ][1]
(Function): Defaults to `false`.
If `clone` is `true` then both `x` and `y` are recursively cloned as part of the merge.
-### @see
+#### @see
-* kyle a mathews/deepmerge
-#### Since
+* emptyTarget
+* isMergeableObj
+
+#### @Since
2.0.0
#### Arguments
@@ -60,15 +63,18 @@ cloneIfNeeded(obj, { clone: false }) === obj
-# dopemerge.prototype.defaultArrayMerge(target=undefined, source=undefined, optsArg=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/dopemerge/dopemerge.js#L129 "View in source") [Ⓣ][1]
+dopemerge.defaultArrayMerge(target=undefined, source=undefined, optsArg=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/dopemerge/dopemerge.js#L110 "View in source") [Ⓣ][1]
(Function): The merge will also merge arrays and array values by default.
However, there are nigh-infinite valid ways to merge arrays,
and you may want to supply your own.
You can do this by passing an `arrayMerge` function as an option.
-#### Since
+
+#### @Since
2.0.0
#### Arguments
@@ -105,16 +111,18 @@ merge([1, 2, 3], [3, 2, 1], { arrayMerge: concatMerge })
🌊 Types: _dopemergelater.d
-# dopemerge.prototype.dopemerge(obj1=undefined, obj2=undefined, opts=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/dopemerge/dopemerge.js#L67 "View in source") [Ⓣ][1]
+dopemerge.dopemerge(obj1=undefined, obj2=undefined, opts=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/dopemerge/dopemerge.js#L58 "View in source") [Ⓣ][1]
(Function): Merge the enumerable attributes of two objects deeply. Merge two objects `x` and `y` deeply, returning a new merged object with the elements from both `x` and `y`. If an element at the same key is present for both `x` and `y`, the value from
`y` will appear in the result. Merging creates a new object, so that neither `x` or `y` are be modified. However, child objects on `x` or `y` are copied over - if you want to copy all values, you must pass `true` to the clone option.
-### @see
+#### @see
-* kyle a mathews/deepmerge
+* deepmerge
#### Arguments
1. `obj1=undefined` *(*)*: left
2. `obj2=undefined` *(*)*: right
@@ -176,41 +184,15 @@ merge(x, y)
-# dopemerge.prototype.emptyTarget(val=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/dopemerge/dopemerge.js#L61 "View in source") [Ⓣ][1]
-
-(Function): make a new empty Array or Object for cloning
-
-#### Since
-2.0.0
-
-#### Arguments
-1. `val=undefined` *(*)*: array or object to return an empty one of
-
-#### Returns
-*(*)*: depending on the data type of val
-
-#### Example
-```js
-emptyTarget({ eh: true })
-//=> {}
-
-emptyTarget([1])
-//=> []
-
-```
----
-
-
-
-
-
-# dopemerge.prototype.isMergeableObj(x=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/dopemerge/dopemerge.js#L41 "View in source") [Ⓣ][1]
+dopemerge.isMergeableObj(x=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/dopemerge/dopemerge.js#L42 "View in source") [Ⓣ][1]
(Function): 1: not null object `2`: object toString is not a date or regex
-#### Since
+
+#### @Since
2.0.0
#### Arguments
@@ -242,4 +224,4 @@ isMergeableObj(/eh/)
- [1]: #dopemerge.prototype "Jump back to the TOC."
+ [1]: #dopemerge "Jump back to the TOC."
diff --git a/docs/docdown/deps/dopemerge/emptyTarget.md b/docs/docdown/deps/dopemerge/emptyTarget.md
new file mode 100644
index 0000000..29fe4c1
--- /dev/null
+++ b/docs/docdown/deps/dopemerge/emptyTarget.md
@@ -0,0 +1,56 @@
+# emptyTarget.js API documentation
+
+
+
+
+
+## `dopemerge`
+* `dopemerge.emptyTarget`
+
+
+
+
+
+
+
+
+
+## `dopemerge`
+
+
+
+dopemerge.emptyTarget(val=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/dopemerge/emptyTarget.js#L22 "View in source") [Ⓣ][1]
+
+(Function): make a new empty Array or Object for cloning
+
+
+#### @Since
+2.0.0
+
+#### Arguments
+1. `val=undefined` *(*)*: array or object to return an empty one of
+
+#### Returns
+*(*)*: depending on the data type of val
+
+#### Example
+```js
+emptyTarget({ eh: true })
+//=> {}
+
+emptyTarget([1])
+//=> []
+
+```
+---
+
+
+
+
+
+
+
+ [1]: #dopemerge "Jump back to the TOC."
diff --git a/docs/docdown/deps/dopemerge/map.md b/docs/docdown/deps/dopemerge/map.md
index 2bf4eff..331743f 100644
--- a/docs/docdown/deps/dopemerge/map.md
+++ b/docs/docdown/deps/dopemerge/map.md
@@ -2,10 +2,62 @@
+
+
+## `dopemerge`
+* `dopemerge.exports`
+
+
+
+
+
+## `dopemerge`
+
+
+
+dopemerge.exports(obj1=undefined, obj2=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/dopemerge/map.js#L32 "View in source") [Ⓣ][1]
+
+(Function): merge maps & sets
+
+
+#### @todos
+
+- [ ] easy clone
+
+#### Arguments
+1. `obj1=undefined` *(Map|Set)*: merge with `2`
+2. `obj2=undefined` *(Map|Set)*: merge with `1`
+
+#### Returns
+*(*)*: merged
+
+#### Example
+```js
+var targetMap = new Map()
+targetMap.set('true', false)
+targetMap.set('obj', { obj: [] })
+targetMap.set('arr', [1])
+var srcMap = new Map()
+srcMap.set('true', true)
+srcMap.set('obj', { obj: [Symbol] })
+srcMap.set('arr', [2])
+srcMap.set('emptyArr', [])
+var mergedMap = dopemergeMap(targetMap, srcMap, { clone: true })
+
+```
+---
+
+
+
+
+
- [1]: # "Jump back to the TOC."
+ [1]: #dopemerge "Jump back to the TOC."
diff --git a/docs/docdown/deps/dot/delete.md b/docs/docdown/deps/dot/delete.md
index a0a1434..1ba2195 100644
--- a/docs/docdown/deps/dot/delete.md
+++ b/docs/docdown/deps/dot/delete.md
@@ -2,10 +2,59 @@
+
+
+## `dot`
+* `dot.dot.delete`
+
+
+
+
+
+## `dot`
+
+
+
+dot.dot.delete(obj=undefined, path=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/dot/delete.js#L26 "View in source") [Ⓣ][1]
+
+(Function): delete a path on an object
+
+
+#### @extends
+
+
+
+
+#### @Since
+3.0.0
+
+#### Arguments
+1. `obj=undefined` *(Object)*: the object to DELETE the nested property from.
+2. `path=undefined` *(Array|Dottable|string)*: dot-prop-path to use
+
+#### Returns
+*(void)*:
+
+#### Example
+```js
+dot.get({ a: { b: 2 } }, 'a.b') //=> 2
+dot.get({ a: { b: 2 } }, ['a', 'b']) //=> 2
+dot.get({ c: { b: 2 } }, ['a', 'b']) //=> undefined
+
+```
+---
+
+
+
+
+
- [1]: # "Jump back to the TOC."
+ [1]: #dot "Jump back to the TOC."
diff --git a/docs/docdown/deps/dot/escape.md b/docs/docdown/deps/dot/escape.md
index 1dd358e..1a1be80 100644
--- a/docs/docdown/deps/dot/escape.md
+++ b/docs/docdown/deps/dot/escape.md
@@ -2,10 +2,41 @@
+
+
+## `dot`
+* `dot.escapeDot`
+
+
+
+
+
+## `dot`
+
+
+
+dot.escapeDot
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/dot/escape.js#L8 "View in source") [Ⓣ][1]
+
+unknown
+
+
+#### @extends
+
+
+
+---
+
+
+
+
+
- [1]: # "Jump back to the TOC."
+ [1]: #dot "Jump back to the TOC."
diff --git a/docs/docdown/deps/dot/get.md b/docs/docdown/deps/dot/get.md
index b235fbe..9528780 100644
--- a/docs/docdown/deps/dot/get.md
+++ b/docs/docdown/deps/dot/get.md
@@ -2,10 +2,60 @@
+
+
+## `dot`
+* `dot.dot.get`
+
+
+
+
+
+## `dot`
+
+
+
+dot.dot.get(obj=undefined, path=undefined, fallback=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/dot/get.js#L27 "View in source") [Ⓣ][1]
+
+Function
+
+
+#### @extends
+
+
+
+
+#### @Since
+3.0.0
+
+#### Arguments
+1. `obj=undefined` *(Object)*: the object to retrieve the nested property from.
+2. `path=undefined` *(Array|Dottable|string)*: dot-prop-path to use
+3. `fallback=undefined` *(*)*: use when there is no value at specified path
+
+#### Returns
+*(*)*: value at path or fallback
+
+#### Example
+```js
+dot.get({ a: { b: 2 } }, 'a.b') //=> 2
+dot.get({ a: { b: 2 } }, ['a', 'b']) //=> 2
+dot.get({ c: { b: 2 } }, ['a', 'b']) //=> undefined
+
+```
+---
+
+
+
+
+
- [1]: # "Jump back to the TOC."
+ [1]: #dot "Jump back to the TOC."
diff --git a/docs/docdown/deps/dot/has.md b/docs/docdown/deps/dot/has.md
index 9a98c3a..f0d74f9 100644
--- a/docs/docdown/deps/dot/has.md
+++ b/docs/docdown/deps/dot/has.md
@@ -2,10 +2,59 @@
+
+
+## `dot`
+* `dot.dot.has`
+
+
+
+
+
+## `dot`
+
+
+
+dot.dot.has(obj=undefined, path=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/dot/has.js#L23 "View in source") [Ⓣ][1]
+
+Function
+
+
+#### @extends
+
+
+
+
+#### @Since
+3.0.0
+
+#### Arguments
+1. `obj=undefined` *(Object)*: the object to retrieve the nested property from.
+2. `path=undefined` *(Array|Dottable|string)*: dot-prop-path to use
+
+#### Returns
+*(boolean)*: has at path
+
+#### Example
+```js
+dot.has({ a: { b: 2 } }, 'a.b') //=> true
+dot.has({ a: { b: 2 } }, ['a', 'b']) //=> true
+dot.has({ c: { b: 2 } }, ['a', 'b']) //=> undefined
+
+```
+---
+
+
+
+
+
- [1]: # "Jump back to the TOC."
+ [1]: #dot "Jump back to the TOC."
diff --git a/docs/docdown/deps/dot/paths.md b/docs/docdown/deps/dot/paths.md
index 38428f1..10e1f87 100644
--- a/docs/docdown/deps/dot/paths.md
+++ b/docs/docdown/deps/dot/paths.md
@@ -5,7 +5,7 @@
## `exports`
-* `exports`
+* `exports`
@@ -19,27 +19,48 @@
-# exports(key=undefined, value=undefined, longest=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/dot/paths.js#L16 "View in source") [Ⓣ][1]
+exports(key=undefined, value=undefined, [longest=undefined])
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/dot/paths.js#L32 "View in source") [Ⓣ][1]
(Function): gathers dot.prop from any value, with a prefixed/base key
-### @notes
+#### @see
+
+* deps/traverse
+
+#### @notes
* had `onlyLongest` & `asString` but can just .join(',') to match
-#### Since
+
+#### @todos
+
+- [ ] should build a trie if doing this
+
+
+#### @Since
4.0.0
#### Arguments
-1. `key=undefined` *(Primitive)*:
-2. `value=undefined` *(Traversable)*:
-3. `longest=undefined` *(|boolean)*:
+1. `key=undefined` *(Primitive)*: prefixing key for the paths, root path/key
+2. `value=undefined` *(Traversable)*: traversable value to extract paths from
+3. `[longest=undefined]` *(|boolean)*: optionally filter to keep only longest/deepest paths
#### Returns
-*(*)*: paths
+*(*)*: paths[]
+
+#### Example
+```js
+dotPropPaths('', { oh: { eh: true } })
+//=> ['oh.eh']
+
+dotPropPaths('moose', { oh: { eh: true } })
+//=> ['moose.oh.eh']
+```
---
diff --git a/docs/docdown/deps/dot/segments.md b/docs/docdown/deps/dot/segments.md
index 050c0c3..dd439e4 100644
--- a/docs/docdown/deps/dot/segments.md
+++ b/docs/docdown/deps/dot/segments.md
@@ -4,8 +4,15 @@
+## `dot`
+* `dot.dotPropSegments`
+
+
+
+
+
## `while`
-* `while`
+* `while`
@@ -15,12 +22,50 @@
+## `dot`
+
+
+
+dot.dotPropSegments(path=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/dot/segments.js#L22 "View in source") [Ⓣ][1]
+
+Function
+
+
+#### @Since
+4.0.0
+
+#### Arguments
+1. `path=undefined` *(string|string[])*: dot-prop-path
+
+#### Returns
+*(*)*: array path
+
+#### Example
+```js
+dotPropSegments('eh.oh') //=> ['eh', 'oh']
+dotPropSegments(['eh', 'oh']) //=> ['eh', 'oh']
+dotPropSegments('ehoh') //=> ['ehoh']
+
+```
+---
+
+
+
+
+
+
+
## `while`
-# while()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/dot/segments.js#L30 "View in source") [Ⓣ][1]
+while()
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/dot/segments.js#L46 "View in source") [Ⓣ][1]
Function
@@ -50,4 +95,4 @@ Function
- [1]: #while "Jump back to the TOC."
+ [1]: #dot "Jump back to the TOC."
diff --git a/docs/docdown/deps/encase/encase.md b/docs/docdown/deps/encase/encase.md
index f62ac1c..60d7247 100644
--- a/docs/docdown/deps/encase/encase.md
+++ b/docs/docdown/deps/encase/encase.md
@@ -4,8 +4,8 @@
-## `exports`
-* `exports`
+## `encase`
+* `encase.exports`
@@ -15,16 +15,28 @@
-## `exports`
+## `encase`
-# exports(call=undefined, [encaser=tryCatch])
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/encase/encase.js#L33 "View in source") [Ⓣ][1]
+encase.exports(call=undefined, [encaser=tryCatch])
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/encase/encase.js#L31 "View in source") [Ⓣ][1]
Function
-#### Since
+
+#### @see
+
+* lodash-attempt
+* fluture-encase
+
+#### @symb
+
+🛡
+
+#### @Since
4.0.0
#### Arguments
@@ -64,4 +76,4 @@ api.call(true)
- [1]: #exports "Jump back to the TOC."
+ [1]: #encase "Jump back to the TOC."
diff --git a/docs/docdown/deps/encase/tryCatch.md b/docs/docdown/deps/encase/tryCatch.md
index 3abc7f1..f062985 100644
--- a/docs/docdown/deps/encase/tryCatch.md
+++ b/docs/docdown/deps/encase/tryCatch.md
@@ -4,8 +4,8 @@
-## `exports`
-* `exports`
+## `encase`
+* `encase.exports`
@@ -15,15 +15,26 @@
-## `exports`
+## `encase`
-# exports(call=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/encase/tryCatch.js#L9 "View in source") [Ⓣ][1]
+encase.exports(call=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/encase/tryCatch.js#L14 "View in source") [Ⓣ][1]
Function
+
+#### @see
+
+* https://github.com/fluture-js/Fluture#encase
+
+#### @todos
+
+- [ ] could curry
+
#### Arguments
1. `call=undefined` *(Function)*:
@@ -38,4 +49,4 @@ Function
- [1]: #exports "Jump back to the TOC."
+ [1]: #encase "Jump back to the TOC."
diff --git a/docs/docdown/deps/encase/withSpecification.md b/docs/docdown/deps/encase/withSpecification.md
index 9d50694..6aae573 100644
--- a/docs/docdown/deps/encase/withSpecification.md
+++ b/docs/docdown/deps/encase/withSpecification.md
@@ -2,10 +2,63 @@
+
+
+## `encase`
+* `encase.withSpecification`
+
+
+
+
+
+## `encase`
+
+
+
+encase.withSpecification(specification=undefined, call=undefined, onInvalid=undefined, onInvalid=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/encase/withSpecification.js#L26 "View in source") [Ⓣ][1]
+
+(Function): a special encased wrapper with no try catch but same api
+
+
+#### @see
+
+* fp/curry
+
+#### @Since
+4.0.0
+
+#### Arguments
+1. `specification=undefined` *(Function)*: match
+2. `call=undefined` *(Function)*: cb to determine valid or invalid
+3. `onInvalid=undefined` *(Function)*: cb when invalid
+4. `onInvalid=undefined` *(Function)*: cb when valid
+
+#### Returns
+*(Function)*: a lot of functions...
+
+#### Example
+```js
+const onInvalid = console.error
+const onValid = console.debug
+const onCall = console.log
+const encased = withSpecification(x => true)(onCall)(onValid, onInvalid)
+
+encased(1, 2, 3) //=> onCall (did not throw)
+
+```
+---
+
+
+
+
+
- [1]: # "Jump back to the TOC."
+ [1]: #encase "Jump back to the TOC."
diff --git a/docs/docdown/deps/primitives/false.md b/docs/docdown/deps/expressions/above.md
similarity index 82%
rename from docs/docdown/deps/primitives/false.md
rename to docs/docdown/deps/expressions/above.md
index 6fecc40..2157746 100644
--- a/docs/docdown/deps/primitives/false.md
+++ b/docs/docdown/deps/expressions/above.md
@@ -1,4 +1,4 @@
-# false.js API documentation
+# above.js API documentation
diff --git a/docs/docdown/deps/expressions/below.md b/docs/docdown/deps/expressions/below.md
new file mode 100644
index 0000000..df7fc66
--- /dev/null
+++ b/docs/docdown/deps/expressions/below.md
@@ -0,0 +1,11 @@
+# below.js API documentation
+
+
+
+
+
+
+
+
+
+ [1]: # "Jump back to the TOC."
diff --git a/docs/docdown/deps/expressions/between.md b/docs/docdown/deps/expressions/between.md
new file mode 100644
index 0000000..e6d295d
--- /dev/null
+++ b/docs/docdown/deps/expressions/between.md
@@ -0,0 +1,53 @@
+# between.js API documentation
+
+
+
+
+
+## `between`
+* `between`
+
+
+
+
+
+
+
+
+
+## `between`
+
+
+
+between(x=undefined, min=undefined, max=undefined, greaterThanOrEqualTo=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/expressions/between.js#L15 "View in source") [Ⓣ][1]
+
+Function
+
+#### Arguments
+1. `x=undefined` *(number)*: number between
+2. `min=undefined` *(number)*: minimum
+3. `max=undefined` *(number)*: maximum
+4. `greaterThanOrEqualTo=undefined` *(boolean): strictly between, not equal to *(left right)**
+
+#### Returns
+*(boolean)*: x >= min && x <= max
+
+#### Example
+```js
+between(100, 0, 200) //=> true
+between(100, 100, 100) //=> true
+between(100, 10, 99) //=> false
+
+```
+---
+
+
+
+
+
+
+
+ [1]: #between "Jump back to the TOC."
diff --git a/docs/docdown/deps/escape-string-regex.md b/docs/docdown/deps/expressions/bitwiseMathOperator.md
similarity index 75%
rename from docs/docdown/deps/escape-string-regex.md
rename to docs/docdown/deps/expressions/bitwiseMathOperator.md
index 05ff141..b9e74da 100644
--- a/docs/docdown/deps/escape-string-regex.md
+++ b/docs/docdown/deps/expressions/bitwiseMathOperator.md
@@ -1,4 +1,4 @@
-# escape-string-regex.js API documentation
+# bitwiseMathOperator.js API documentation
diff --git a/docs/docdown/deps/expressions/even.md b/docs/docdown/deps/expressions/even.md
new file mode 100644
index 0000000..431e9f1
--- /dev/null
+++ b/docs/docdown/deps/expressions/even.md
@@ -0,0 +1,60 @@
+# even.js API documentation
+
+
+
+
+
+## `exports`
+* `exports`
+
+
+
+
+
+
+
+
+
+## `exports`
+
+
+
+exports(x=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/expressions/even.js#L24 "View in source") [Ⓣ][1]
+
+(Function): isEven
+
+
+#### @extends
+
+
+
+#### Arguments
+1. `x=undefined` *(any|number)*: value to check
+
+#### Returns
+*(boolean)*: isEven
+
+#### Example
+```js
+isEven(1)
+//=> false
+isEven(2)
+//=> true
+
+var rando = Math.floor(Math.random(0, 10000))
+isEven(rando) !== isOdd(rando)
+//=> true
+
+```
+---
+
+
+
+
+
+
+
+ [1]: #exports "Jump back to the TOC."
diff --git a/docs/docdown/deps/expressions/expressions.md b/docs/docdown/deps/expressions/expressions.md
new file mode 100644
index 0000000..f2a4afd
--- /dev/null
+++ b/docs/docdown/deps/expressions/expressions.md
@@ -0,0 +1,11 @@
+# expressions.js API documentation
+
+
+
+
+
+
+
+
+
+ [1]: # "Jump back to the TOC."
diff --git a/docs/docdown/deps/expressions/increment.md b/docs/docdown/deps/expressions/increment.md
new file mode 100644
index 0000000..127ef2d
--- /dev/null
+++ b/docs/docdown/deps/expressions/increment.md
@@ -0,0 +1,11 @@
+# increment.js API documentation
+
+
+
+
+
+
+
+
+
+ [1]: # "Jump back to the TOC."
diff --git a/docs/docdown/deps/expressions/index.md b/docs/docdown/deps/expressions/index.md
new file mode 100644
index 0000000..5ac127d
--- /dev/null
+++ b/docs/docdown/deps/expressions/index.md
@@ -0,0 +1,11 @@
+# index.js API documentation
+
+
+
+
+
+
+
+
+
+ [1]: # "Jump back to the TOC."
diff --git a/docs/docdown/deps/expressions/odd.md b/docs/docdown/deps/expressions/odd.md
new file mode 100644
index 0000000..b971d9a
--- /dev/null
+++ b/docs/docdown/deps/expressions/odd.md
@@ -0,0 +1,60 @@
+# odd.js API documentation
+
+
+
+
+
+## `exports`
+* `exports`
+
+
+
+
+
+
+
+
+
+## `exports`
+
+
+
+exports(x=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/expressions/odd.js#L20 "View in source") [Ⓣ][1]
+
+(Function): isOdd
+
+
+#### @see
+
+*
+
+#### @extends
+
+
+
+#### Arguments
+1. `x=undefined` *(any|number)*: value to check
+
+#### Returns
+*(boolean)*: isOdd
+
+#### Example
+```js
+isOdd(1)
+//=> true
+isOdd(2)
+//=> false
+
+```
+---
+
+
+
+
+
+
+
+ [1]: #exports "Jump back to the TOC."
diff --git a/docs/docdown/deps/fp/always.md b/docs/docdown/deps/fp/always.md
new file mode 100644
index 0000000..503daa3
--- /dev/null
+++ b/docs/docdown/deps/fp/always.md
@@ -0,0 +1,73 @@
+# always.js API documentation
+
+
+
+
+
+## `fp`
+* `fp.`
+
+
+
+
+
+
+
+
+
+## `fp`
+
+
+
+🌊 Types: fp.d
+
+🔬 Tests: always
+
+fp.exports(value=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/fp/always.js#L22 "View in source") [Ⓣ][1]
+
+(Function): Returns a function that always returns the given value. Note that for
+non-primitives the value returned is a reference to the original value.
+
+
+This function is known as `const`, `constant`, or `K` *(for K combinator)* in
+other languages and libraries.
+
+
+#### @see
+
+* ramda-constant-docs-issue
+* ramda-always
+* lodash-constant
+* underscore-constant
+
+#### @sig
+
+a -> (* -> a)
+
+#### @Since
+v5.0.0
+
+#### Arguments
+1. `value=undefined` *(*)*: The value to wrap in a function
+
+#### Returns
+*(Function)*: A Function :: * -> val.
+
+#### Example
+```js
+var t = always('Tee')
+t() //=> 'Tee'
+
+```
+---
+
+
+
+
+
+
+
+ [1]: #fp "Jump back to the TOC."
diff --git a/docs/docdown/deps/fp/arity.md b/docs/docdown/deps/fp/arity.md
new file mode 100644
index 0000000..ceb9601
--- /dev/null
+++ b/docs/docdown/deps/fp/arity.md
@@ -0,0 +1,63 @@
+# arity.js API documentation
+
+
+
+
+
+## `fp`
+* `fp.exports`
+
+
+
+
+
+
+
+
+
+## `fp`
+
+
+
+fp.exports(n=undefined, fn=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/fp/arity.js#L17 "View in source") [Ⓣ][1]
+
+(Function): just for `.length` of a function?
+
+
+#### @see
+
+* mozilla-func-arity
+
+#### @todos
+
+- [ ] keeping this means change uglify...
+
+
+#### @Since
+5.0.0
+
+#### Arguments
+1. `n=undefined` *(number)*: number of arguments
+2. `fn=undefined` *(Function)*: function to wrap
+
+#### Returns
+*(Function)*: function with params
+
+#### Example
+```js
+const wan = one => console.log(one)
+ arity(1, wan)
+ => function(one => wan(one))
+```
+---
+
+
+
+
+
+
+
+ [1]: #fp "Jump back to the TOC."
diff --git a/docs/docdown/deps/insert-at-index.md b/docs/docdown/deps/fp/callDestructure.md
similarity index 77%
rename from docs/docdown/deps/insert-at-index.md
rename to docs/docdown/deps/fp/callDestructure.md
index 3b28de7..55fae32 100644
--- a/docs/docdown/deps/insert-at-index.md
+++ b/docs/docdown/deps/fp/callDestructure.md
@@ -1,4 +1,4 @@
-# insert-at-index.js API documentation
+# callDestructure.js API documentation
diff --git a/docs/docdown/deps/fp/construct.md b/docs/docdown/deps/fp/construct.md
new file mode 100644
index 0000000..d2d0c4f
--- /dev/null
+++ b/docs/docdown/deps/fp/construct.md
@@ -0,0 +1,96 @@
+# construct.js API documentation
+
+
+
+
+
+## `fp`
+* `fp.`
+
+
+
+
+
+
+
+
+
+## `fp`
+
+
+
+fp.constructN(n=undefined, Klass=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/fp/construct.js#L47 "View in source") [Ⓣ][1]
+
+(Function): Wraps a constructor function inside a curried function that can be called
+with the same arguments and returns the same type. The arity of the function
+returned is specified to allow using variadic constructor functions.
+
+
+#### @see
+
+* ramda-construct
+* isNumberPrimitive
+
+#### @sig
+
+Number -> (* -> {*}) -> (* -> {*})
+
+#### @symb
+
+👷
+
+#### @extends
+
+* undefined
+* undefined
+
+
+
+#### @Since
+5.0.0-beta.4
+
+#### Arguments
+1. `n=undefined` *(number): The arity of the constructor function. *(aka, number of args)**
+2. `Klass=undefined` *(Function): The constructor function to wrap. *(class to do `new Klass` on)**
+
+#### Returns
+*(Function)*: A wrapped, curried constructor function.
+
+#### Example
+```js
+// Variadic Constructor function
+function Salad() {
+ this.ingredients = arguments
+}
+
+Salad.prototype.recipe = function() {
+ var instructions = R.map(
+ ingredient => 'Add a dollop of ' + ingredient,
+ this.ingredients
+ )
+ return R.join('\n', instructions)
+}
+
+var ThreeLayerSalad = R.constructN(3, Salad)
+
+// Notice we no longer need the 'new' keyword, and the constructor is curried for 3 arguments.
+var salad = ThreeLayerSalad('Mayonnaise')('Potato Chips')('Ketchup')
+
+console.log(salad.recipe())
+// Add a dollop of Mayonnaise
+// Add a dollop of Potato Chips
+// Add a dollop of Ketchup
+
+```
+---
+
+
+
+
+
+
+
+ [1]: #fp "Jump back to the TOC."
diff --git a/docs/docdown/deps/fp/constructInit.md b/docs/docdown/deps/fp/constructInit.md
new file mode 100644
index 0000000..bebbdc3
--- /dev/null
+++ b/docs/docdown/deps/fp/constructInit.md
@@ -0,0 +1,11 @@
+# constructInit.js API documentation
+
+
+
+
+
+
+
+
+
+ [1]: # "Jump back to the TOC."
diff --git a/docs/docdown/deps/fp/curry.md b/docs/docdown/deps/fp/curry.md
new file mode 100644
index 0000000..9c2e51f
--- /dev/null
+++ b/docs/docdown/deps/fp/curry.md
@@ -0,0 +1,164 @@
+# curry.js API documentation
+
+
+
+
+
+## `fp`
+* `fp.`
+* `fp.`
+
+
+
+
+
+
+
+
+
+## `fp`
+
+
+
+🌊 Types: fp.d
+
+🔬 Tests: curry
+
+fp._curryN(length=undefined, received=undefined, fn=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/fp/curry.js#L45 "View in source") [Ⓣ][1]
+
+(Function): Returns a curried equivalent of the provided function, with the specified
+arity. The curried function has two unusual capabilities. First, its
+arguments needn't be provided one at a time. If `g` is `R.curryN(3, f)`, the
+following are equivalent:
+
+
+ * `g(1)(2)(3)`
+ * `g(1)(2, 3)`
+ * `g(1, 2)(3)`
+ * `g(1, 2, 3)`
+
+
+Secondly, the special placeholder value [`R.__`](#__) may be used to specify
+"gaps", allowing partial application of any combination of arguments,
+regardless of their positions. If `g` is as above and `_` is [`R.__`](#__),
+the following are equivalent:
+
+
+ * `g(1, 2, 3)`
+ * `g(_, 2, 3)(1)`
+ * `g(_, _, 3)(1)(2)`
+ * `g(_, _, 3)(1, 2)`
+ * `g(_, 2)(1)(3)`
+ * `g(_, 2)(1, 3)`
+ * `g(_, 2)(_, 3)(1)`
+
+
+#### @see
+
+* ramda-curry
+* lodash-curry
+* ramda-uncurry
+
+#### @sig
+
+Number -> (* -> a) -> (* -> a)
+
+#### @Since
+5.0.0-beta.1
+
+#### Arguments
+1. `length=undefined` *(Number)*: The arity of the curried function.
+2. `received=undefined` *(Array)*: An array of arguments received thus far.
+3. `fn=undefined` *(Function)*: The function to curry.
+
+#### Returns
+*(Function)*: A new, curried function.
+
+#### Example
+```js
+var sumArgs = (...args) => R.sum(args)
+
+var curriedAddFourNumbers = R.curryN(4, sumArgs)
+var f = curriedAddFourNumbers(1, 2)
+var g = f(3)
+g(4) //=> 10
+
+```
+---
+
+
+
+
+
+fp.exports(length=undefined, fn=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/fp/curry.js#L139 "View in source") [Ⓣ][1]
+
+(Function): Returns a curried equivalent of the provided function, with the specified
+arity. The curried function has two unusual capabilities. First, its
+arguments needn't be provided one at a time. If `g` is `R.curryN(3, f)`, the
+following are equivalent:
+
+
+ * `g(1)(2)(3)`
+ * `g(1)(2, 3)`
+ * `g(1, 2)(3)`
+ * `g(1, 2, 3)`
+
+
+Secondly, the special placeholder value [`R.__`](#__) may be used to specify
+"gaps", allowing partial application of any combination of arguments,
+regardless of their positions. If `g` is as above and `_` is [`R.__`](#__),
+the following are equivalent:
+
+
+ * `g(1, 2, 3)`
+ * `g(_, 2, 3)(1)`
+ * `g(_, _, 3)(1)(2)`
+ * `g(_, _, 3)(1, 2)`
+ * `g(_, 2)(1)(3)`
+ * `g(_, 2)(1, 3)`
+ * `g(_, 2)(_, 3)(1)`
+
+
+#### @see
+
+* ramda
+
+#### @sig
+
+Number -> (* -> a) -> (* -> a)
+
+#### @Since
+v0.5.0
+
+#### Arguments
+1. `length=undefined` *(Number)*: The arity for the returned function.
+2. `fn=undefined` *(Function)*: The function to curry.
+
+#### Returns
+*(Function)*: A new, curried function.
+
+#### Example
+```js
+var sumArgs = (...args) => R.sum(args)
+
+var curriedAddFourNumbers = R.curryN(4, sumArgs)
+var f = curriedAddFourNumbers(1, 2)
+var g = f(3)
+g(4) //=> 10
+
+```
+---
+
+
+
+
+
+
+
+ [1]: #fp "Jump back to the TOC."
diff --git a/docs/docdown/deps/fp/first.md b/docs/docdown/deps/fp/first.md
new file mode 100644
index 0000000..56ca229
--- /dev/null
+++ b/docs/docdown/deps/fp/first.md
@@ -0,0 +1,73 @@
+# first.js API documentation
+
+
+
+
+
+## `fp`
+* `fp.`
+
+
+
+
+
+
+
+
+
+## `fp`
+
+
+
+fp.exports(x=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/fp/first.js#L33 "View in source") [Ⓣ][1]
+
+(Function): Returns the first element of the given list or string. In some libraries
+this function is named `first`.
+
+
+#### @see
+
+* https://github.com/lodash/lodash/blob/master/head.js
+* https://github.com/ramda/ramda/blob/master/src/head.js
+*
+
+#### @todos
+
+- [ ] could just pipe nth
+
+
+#### @extends
+
+
+
+
+#### @Since
+v5.0.0
+
+#### Arguments
+1. `x=undefined` *(*)*: Array or Object find the last key of
+
+#### Returns
+*(*)*: value at last index
+
+#### Example
+```js
+first(['fi', 'fo', 'fum']) //=> 'fi'
+first([]) //=> undefined
+
+first('abc') //=> 'a'
+first('') //=> ''
+
+```
+---
+
+
+
+
+
+
+
+ [1]: #fp "Jump back to the TOC."
diff --git a/docs/docdown/deps/fp/firstIndex.md b/docs/docdown/deps/fp/firstIndex.md
new file mode 100644
index 0000000..f33a8b0
--- /dev/null
+++ b/docs/docdown/deps/fp/firstIndex.md
@@ -0,0 +1,67 @@
+# firstIndex.js API documentation
+
+
+
+
+
+## `fp`
+* `fp.firstIndex`
+
+
+
+
+
+
+
+
+
+## `fp`
+
+
+
+fp.firstIndex(x=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/fp/firstIndex.js#L22 "View in source") [Ⓣ][1]
+
+(Function): get first index in a list
+
+
+#### @see
+
+* deps/fp/first
+
+#### @notes
+
+* works for strings too eh
+
+
+#### @extends
+
+
+
+
+#### @Since
+5.0.0-beta.2
+
+#### Arguments
+1. `x=undefined` *(*|Array|Object|string)*: item to find the first index of
+
+#### Returns
+*(*)*: first index, usually number/string
+
+#### Example
+```js
+firstIndex([0, 'one']) //=> 0
+firstIndex({ one: 1, two: 2 }) //=> 'one'
+
+```
+---
+
+
+
+
+
+
+
+ [1]: #fp "Jump back to the TOC."
diff --git a/docs/docdown/deps/fp/flip.md b/docs/docdown/deps/fp/flip.md
new file mode 100644
index 0000000..42a5d94
--- /dev/null
+++ b/docs/docdown/deps/fp/flip.md
@@ -0,0 +1,82 @@
+# flip.js API documentation
+
+
+
+
+
+## `fp`
+* `fp.`
+
+
+
+
+
+
+
+
+
+## `fp`
+
+
+
+🌊 Types: fp.d
+
+* 🔬 Tests: flip
+* 🔬 Tests: flip2
+
+fp.exports(fn=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/fp/flip.js#L33 "View in source") [Ⓣ][1]
+
+(Function): flip the fn args: Creates a function that invokes `func` with arguments reversed.
+
+
+#### @see
+
+* ramda-flip
+* lodash-flip
+* fp/reverse
+
+#### @todos
+
+- [ ] could also just call with fn.apply([b, a]), and have flipN
+
+
+#### @sig
+
+((a, b, c, ...) -> z) -> (b -> a -> c -> ... -> z)
+
+#### @symb
+
+🙃
+
+#### @Since
+5.0.0-beta.4
+
+#### Arguments
+1. `fn=undefined` *(Function)*: The function to invoke with its first two parameters reversed.
+
+#### Returns
+*(*)*: The result of invoking `fn` with its first two parameters' order reversed.
+
+#### Example
+```js
+var mergeThree = (a, b, c) => [].concat(a, b, c)
+mergeThree(1, 2, 3) //=> [1, 2, 3]
+flip(mergeThree)(1, 2, 3) //=> [3, 2, 1]
+
+const flipped = flip((...args) => args)
+flipped('a', 'b', 'c', 'd')
+// => ['d', 'c', 'b', 'a']
+
+```
+---
+
+
+
+
+
+
+
+ [1]: #fp "Jump back to the TOC."
diff --git a/docs/docdown/deps/fp/flip2.md b/docs/docdown/deps/fp/flip2.md
new file mode 100644
index 0000000..d70ba77
--- /dev/null
+++ b/docs/docdown/deps/fp/flip2.md
@@ -0,0 +1,81 @@
+# flip2.js API documentation
+
+
+
+
+
+## `fp`
+* `fp.exports`
+
+
+
+
+
+
+
+
+
+## `fp`
+
+
+
+🌊 Types: fp.d
+
+🔬 Tests: flip2
+
+fp.exports(fn=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/fp/flip2.js#L34 "View in source") [Ⓣ][1]
+
+(Function): Returns a new function much like the supplied one, except that the first two
+arguments' order is reversed.
+
+
+#### @see
+
+* fp/flip
+
+#### @todos
+
+- [ ] flipN
+
+
+#### @symb
+
+🙃🙃
+
+#### @extends
+
+
+
+
+#### @Since
+5.0.0-beta.4
+
+#### Arguments
+1. `fn=undefined` *(Function)*: The function to invoke with its first two parameters reversed.
+
+#### Returns
+*(*)*: The result of invoking `fn` with its first two parameters' order reversed.
+
+#### Example
+```js
+var mergeThree = (a, b, c) => [].concat(a, b, c)
+mergeThree(1, 2, 3) //=> [1, 2, 3]
+flip(mergeThree)(1, 2, 3) //=> [2, 1, 3]
+
+const flipped = flip((...args) => args)
+flipped('a', 'b', 'c', 'd')
+// => ['b', 'a', 'c', 'd']
+
+```
+---
+
+
+
+
+
+
+
+ [1]: #fp "Jump back to the TOC."
diff --git a/docs/docdown/deps/fp/fp.md b/docs/docdown/deps/fp/fp.md
new file mode 100644
index 0000000..790e8be
--- /dev/null
+++ b/docs/docdown/deps/fp/fp.md
@@ -0,0 +1,55 @@
+# fp.js API documentation
+
+
+
+
+
+## `fp.exports`
+* `fp.exports`
+
+
+
+
+
+
+
+
+
+## `fp.exports`
+
+
+
+🌊 Types: fp.d
+
+* 🔬 Tests: always
+* 🔬 Tests: construct
+* 🔬 Tests: curry
+* 🔬 Tests: firstLast
+* 🔬 Tests: flip
+* 🔬 Tests: flip2
+* 🔬 Tests: path
+* 🔬 Tests: pipe
+* 🔬 Tests: remove
+* 🔬 Tests: replace
+* 🔬 Tests: reverse
+
+fp.exports
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/fp/fp.js#L31 "View in source") [Ⓣ][1]
+
+Object
+
+
+#### @symb
+
+🐏
+---
+
+
+
+
+
+
+
+ [1]: #fp.exports "Jump back to the TOC."
diff --git a/docs/docdown/deps/fp/hasInMatching.md b/docs/docdown/deps/fp/hasInMatching.md
new file mode 100644
index 0000000..be8a123
--- /dev/null
+++ b/docs/docdown/deps/fp/hasInMatching.md
@@ -0,0 +1,74 @@
+# hasInMatching.js API documentation
+
+
+
+
+
+## `is`
+* `is.hasInMatching`
+
+
+
+
+
+
+
+
+
+## `is`
+
+
+
+is.hasInMatching(predicate=undefined, obj=undefined, prop=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/fp/hasInMatching.js#L30 "View in source") [Ⓣ][1]
+
+(Function): isIn + hasIn ...and also allows a predicate/matcher/specification
+
+
+#### @see
+
+* https://github.com/ramda/ramda/blob/master/src/propOr.js
+
+#### @todos
+
+- [ ] surely would be better with focusing on a prop, then applying predicate, lense? :s
+- [ ] is it better in fp/ or is/ ? needs some definitions
+
+
+#### @extends
+
+* undefined
+* undefined
+* undefined
+
+
+
+#### @Since
+5.0.0-beta.4
+
+#### Arguments
+1. `predicate=undefined` *(Object)*: predicate match the property against this
+2. `obj=undefined` *(Object)*: object to check
+3. `prop=undefined` *(any)*: property to check in object
+
+#### Returns
+*(boolean)*: obj[prop] hasIn & satisfies
+
+#### Example
+```js
+hasIn({}, 'eh') //=> false
+hasIn(null, 'eh') //=> false
+hasIn({ eh: true }, 'eh') //=> true
+
+```
+---
+
+
+
+
+
+
+
+ [1]: #is "Jump back to the TOC."
diff --git a/docs/docdown/deps/fp/includesCount.md b/docs/docdown/deps/fp/includesCount.md
new file mode 100644
index 0000000..56dfd30
--- /dev/null
+++ b/docs/docdown/deps/fp/includesCount.md
@@ -0,0 +1,62 @@
+# includesCount.js API documentation
+
+
+
+
+
+## `getIncludesCount`
+* `getIncludesCount`
+
+
+
+
+
+
+
+
+
+## `getIncludesCount`
+
+
+
+getIncludesCount(haystack=undefined, needle=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/fp/includesCount.js#L19 "View in source") [Ⓣ][1]
+
+(Function): getIncludesCount, how many times a needle occurrs in a haystack
+
+
+#### @see
+
+* mozilla-occurrences
+* mozilla-array-occurrences
+
+#### @Since
+5.0.0-beta.4
+
+#### Arguments
+1. `haystack=undefined` *(Array|string)*: haystack to look in
+2. `needle=undefined` *(Matchable|string)*: needle to find
+
+#### Returns
+*(number)*: occurrs/includes times/count
+
+#### Example
+```js
+getIncludesCount('1 00 1', '1') //=> 2
+getIncludesCount([1, 1, 0, 0], 1) //=> 2
+getIncludesCount([0], 1) //=> 0
+getIncludesCount('', 1) //=> 0
+getIncludesCount(null, 1) //=> 0
+
+```
+---
+
+
+
+
+
+
+
+ [1]: #getincludescount "Jump back to the TOC."
diff --git a/docs/docdown/deps/fp/index.md b/docs/docdown/deps/fp/index.md
new file mode 100644
index 0000000..5ac127d
--- /dev/null
+++ b/docs/docdown/deps/fp/index.md
@@ -0,0 +1,11 @@
+# index.js API documentation
+
+
+
+
+
+
+
+
+
+ [1]: # "Jump back to the TOC."
diff --git a/docs/docdown/deps/fp/invoke.md b/docs/docdown/deps/fp/invoke.md
new file mode 100644
index 0000000..f2c44ef
--- /dev/null
+++ b/docs/docdown/deps/fp/invoke.md
@@ -0,0 +1,11 @@
+# invoke.js API documentation
+
+
+
+
+
+
+
+
+
+ [1]: # "Jump back to the TOC."
diff --git a/docs/docdown/deps/fp/isPlaceholder.md b/docs/docdown/deps/fp/isPlaceholder.md
new file mode 100644
index 0000000..9ebdf23
--- /dev/null
+++ b/docs/docdown/deps/fp/isPlaceholder.md
@@ -0,0 +1,11 @@
+# isPlaceholder.js API documentation
+
+
+
+
+
+
+
+
+
+ [1]: # "Jump back to the TOC."
diff --git a/docs/docdown/deps/fp/last.md b/docs/docdown/deps/fp/last.md
new file mode 100644
index 0000000..512ba7c
--- /dev/null
+++ b/docs/docdown/deps/fp/last.md
@@ -0,0 +1,79 @@
+# last.js API documentation
+
+
+
+
+
+## `fp`
+* `fp.`
+
+
+
+
+
+
+
+
+
+## `fp`
+
+
+
+🌊 Types: fp.d
+
+* 🔬 Tests: always
+* 🔬 Tests: construct
+* 🔬 Tests: curry
+* 🔬 Tests: firstLast
+* 🔬 Tests: flip
+* 🔬 Tests: flip2
+* 🔬 Tests: path
+* 🔬 Tests: pipe
+* 🔬 Tests: remove
+* 🔬 Tests: replace
+* 🔬 Tests: reverse
+
+fp.exports(x=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/fp/last.js#L33 "View in source") [Ⓣ][1]
+
+(Function): Returns the last element of the given list or string.
+
+
+#### @see
+
+*
+
+#### @extends
+
+
+
+
+#### @Since
+5.0.0-beta.2
+
+#### Arguments
+1. `x=undefined` *(*)*: list to get last index of
+
+#### Returns
+*(*)*:
+
+#### Example
+```js
+last(['fi', 'fo', 'fum']) //=> 'fum'
+last([]) //=> undefined
+
+last('abc') //=> 'c'
+last('') //=> ''
+
+```
+---
+
+
+
+
+
+
+
+ [1]: #fp "Jump back to the TOC."
diff --git a/docs/docdown/deps/fp/lastIndex.md b/docs/docdown/deps/fp/lastIndex.md
new file mode 100644
index 0000000..e42ce50
--- /dev/null
+++ b/docs/docdown/deps/fp/lastIndex.md
@@ -0,0 +1,67 @@
+# lastIndex.js API documentation
+
+
+
+
+
+## `fp`
+* `fp.lastIndex`
+
+
+
+
+
+
+
+
+
+## `fp`
+
+
+
+fp.lastIndex(x=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/fp/lastIndex.js#L23 "View in source") [Ⓣ][1]
+
+(Function): get last index in a list
+
+
+#### @see
+
+* deps/fp/last
+
+#### @notes
+
+* works for strings too eh
+
+
+#### @extends
+
+
+
+
+#### @Since
+5.0.0-beta.2
+
+#### Arguments
+1. `x=undefined` *(*|Array|Object|string)*: item to find the last index of
+
+#### Returns
+*(*)*: last index, usually number/string
+
+#### Example
+```js
+lastIndex([0, 'one']) //=> 1
+lastIndex({ one: 1, two: 2 }) //=> 'two'
+
+```
+---
+
+
+
+
+
+
+
+ [1]: #fp "Jump back to the TOC."
diff --git a/docs/docdown/deps/fp/mapWhere.md b/docs/docdown/deps/fp/mapWhere.md
new file mode 100644
index 0000000..941403b
--- /dev/null
+++ b/docs/docdown/deps/fp/mapWhere.md
@@ -0,0 +1,60 @@
+# mapWhere.js API documentation
+
+
+
+
+
+## `fp`
+* `fp.mapWhere`
+
+
+
+
+
+
+
+
+
+## `fp`
+
+
+
+fp.mapWhere(obj=undefined, predicate=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/fp/mapWhere.js#L26 "View in source") [Ⓣ][1]
+
+(Function): Creates an array of values by running each property of `object` thru
+`iteratee`. The iteratee is invoked with three arguments: *(value, key, object)*.
+
+
+#### @see
+
+* https://github.com/lodash/lodash/blob/master/map.js
+
+#### @Since
+5.0.0
+
+#### Arguments
+1. `obj=undefined` *(Object)*: The object to iterate over.
+2. `predicate=undefined` *(Function)*: The function invoked per iteration.
+
+#### Returns
+*(Array)*: Returns the new mapped array.
+
+#### Example
+```js
+const square = n => n * n
+map({ a: 4, b: 8 }, square)
+// => [16, 64] (iteration order is not guaranteed)
+
+```
+---
+
+
+
+
+
+
+
+ [1]: #fp "Jump back to the TOC."
diff --git a/docs/docdown/deps/fp/path.md b/docs/docdown/deps/fp/path.md
new file mode 100644
index 0000000..73602f8
--- /dev/null
+++ b/docs/docdown/deps/fp/path.md
@@ -0,0 +1,63 @@
+# path.js API documentation
+
+
+
+
+
+## `fp`
+* `fp.`
+
+
+
+
+
+
+
+
+
+## `fp`
+
+
+
+fp.exports(path=undefined, obj=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/fp/path.js#L27 "View in source") [Ⓣ][1]
+
+(Function): Retrieve the value at a given path.
+
+
+#### @see
+
+* https://github.com/ramda/ramda/blob/master/src/path.js
+* R.prop
+
+#### @sig
+
+[Idx] -> {a} -> a | Undefined
+
+#### @Since
+v5.0.0
+
+#### Arguments
+1. `path=undefined` *(Array)*: The path to use.
+2. `obj=undefined` *(Object)*: The object to retrieve the nested property from.
+
+#### Returns
+*(*)*: The data at `path`.
+
+#### Example
+```js
+R.path(['a', 'b'], { a: { b: 2 } }) //=> 2
+R.path(['a', 'b'], { c: { b: 2 } }) //=> undefined
+
+```
+---
+
+
+
+
+
+
+
+ [1]: #fp "Jump back to the TOC."
diff --git a/docs/docdown/deps/fp/pipe.md b/docs/docdown/deps/fp/pipe.md
new file mode 100644
index 0000000..6468450
--- /dev/null
+++ b/docs/docdown/deps/fp/pipe.md
@@ -0,0 +1,91 @@
+# pipe.js API documentation
+
+
+
+
+
+## `fp`
+* `fp.`
+
+
+
+
+
+
+
+
+
+## `fp`
+
+
+
+🌊 Types: fp.d
+
+🔬 Tests: pipe
+
+fp.exports(first=undefined, rest=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/fp/pipe.js#L46 "View in source") [Ⓣ][1]
+
+(Function): Performs left-to-right function composition. The leftmost function may have
+any arity; the remaining functions must be unary.
+In some libraries this function is named `sequence`.
+
+
+#### @see
+
+* R.compose
+* https://github.com/ramda/ramda/blob/master/src/pipe.js
+* https://github.com/ramda/ramda/blob/master/test/pipe.js
+
+#### @sig
+
+(((a, b, ..., n) -> o), (o -> p), ..., (x -> y), (y -> z)) -> ((a, b, ..., n) -> z)
+
+#### @symb
+
+R.pipe(f, g, h)(a, b) = h(g(f(a, b)))
+
+#### @extends
+
+
+
+
+#### @Since
+v5.0.0
+
+#### Arguments
+1. `first=undefined` *(Function)*: function first
+2. `rest=undefined` *(...Function)*: function next
+
+#### Returns
+*(Function)*:
+
+#### Example
+```js
+var f = R.pipe(Math.pow, R.negate, R.inc)
+f(3, 4) // -(3^4) + 1
+
+```
+#### Example
+```js
+var x = v => v + 'x'
+var y = v => v + 'y'
+var z = v => v + 'z'
+
+const xyz = pipe(x, y, z)
+/// starts with w, adds x, then y, then z
+const wxyz = xyz('w')
+//=> 'wxyz'
+
+```
+---
+
+
+
+
+
+
+
+ [1]: #fp "Jump back to the TOC."
diff --git a/docs/docdown/deps/fp/pipeTwo.md b/docs/docdown/deps/fp/pipeTwo.md
new file mode 100644
index 0000000..be1ddc5
--- /dev/null
+++ b/docs/docdown/deps/fp/pipeTwo.md
@@ -0,0 +1,69 @@
+# pipeTwo.js API documentation
+
+
+
+
+
+## `fp`
+* `fp.`
+
+
+
+
+
+
+
+
+
+## `fp`
+
+
+
+🌊 Types: fp.d
+
+🔬 Tests: pipe
+
+fp.exports(f=undefined, g=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/fp/pipeTwo.js#L28 "View in source") [Ⓣ][1]
+
+(Function): Performs left-to-right function composition. ONLY CAN PIPE `2` ARGUMENTS
+
+
+#### @see
+
+* https://github.com/ramda/ramda/blob/master/src/pipe.js
+* https://github.com/ramda/ramda/blob/master/test/pipe.js
+
+#### @notes
+
+* The result of pipe is not automatically curried.
+* This is a variation, is the internal version with only 2 functions, for now
+
+
+#### @Since
+v5.0.0
+
+#### Arguments
+1. `f=undefined` *(...Function)*: function first
+2. `g=undefined` *(...Function)*: function next
+
+#### Returns
+*(Function)*:
+
+#### Example
+```js
+var f = R.pipe(Math.pow, R.negate)
+f(3, 4) // -(3^4) + 1
+
+```
+---
+
+
+
+
+
+
+
+ [1]: #fp "Jump back to the TOC."
diff --git a/docs/docdown/deps/fp/prop.md b/docs/docdown/deps/fp/prop.md
new file mode 100644
index 0000000..440182e
--- /dev/null
+++ b/docs/docdown/deps/fp/prop.md
@@ -0,0 +1,61 @@
+# prop.js API documentation
+
+
+
+
+
+## `fp`
+* `fp.`
+
+
+
+
+
+
+
+
+
+## `fp`
+
+
+
+🌊 Types: fp.d
+
+fp.exports(p=undefined, obj=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/fp/prop.js#L26 "View in source") [Ⓣ][1]
+
+(Function): Returns a function that when supplied an object returns the indicated
+property of that object, if it exists.
+
+
+#### @sig
+
+s -> {s: a} -> a | Undefined
+
+#### @Since
+v5.0.0
+
+#### Arguments
+1. `p=undefined` *(String)*: The property name
+2. `obj=undefined` *(Object)*: The object to query
+
+#### Returns
+*(*)*: The value at `obj.p`.
+
+#### Example
+```js
+R.prop('x', { x: 100 }) //=> 100
+R.prop('x', {}) //=> undefined
+
+```
+---
+
+
+
+
+
+
+
+ [1]: #fp "Jump back to the TOC."
diff --git a/docs/docdown/deps/fp/remove.md b/docs/docdown/deps/fp/remove.md
new file mode 100644
index 0000000..dbe41a0
--- /dev/null
+++ b/docs/docdown/deps/fp/remove.md
@@ -0,0 +1,11 @@
+# remove.js API documentation
+
+
+
+
+
+
+
+
+
+ [1]: # "Jump back to the TOC."
diff --git a/docs/docdown/deps/fp/replace.md b/docs/docdown/deps/fp/replace.md
new file mode 100644
index 0000000..d94c38c
--- /dev/null
+++ b/docs/docdown/deps/fp/replace.md
@@ -0,0 +1,71 @@
+# replace.js API documentation
+
+
+
+
+
+## `fp`
+* `fp.`
+
+
+
+
+
+
+
+
+
+## `fp`
+
+
+
+🌊 Types: fp.d
+
+🔬 Tests: replace
+
+fp.exports(pattern=undefined, replacement=undefined, str=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/fp/replace.js#L30 "View in source") [Ⓣ][1]
+
+(Function): Replace a substring or regex match in a string with a replacement.
+
+
+#### @see
+
+* ramda-replace
+* lodash-replace
+
+#### @sig
+
+RegExp|String -> String -> String -> String
+
+#### @Since
+v5.0.0
+
+#### Arguments
+1. `pattern=undefined` *(RegExp|String)*: A regular expression or a substring to match.
+2. `replacement=undefined` *(String)*: The string to replace the matches with.
+3. `str=undefined` *(String)*: The String to do the search and replacement in.
+
+#### Returns
+*(String)*: The result.
+
+#### Example
+```js
+replace('foo', 'bar', 'foo foo foo') //=> 'bar foo foo'
+replace(/foo/, 'bar', 'foo foo foo') //=> 'bar foo foo'
+
+// Use the "g" (global) flag to replace all occurrences:
+replace(/foo/g, 'bar', 'foo foo foo') //=> 'bar bar bar'
+
+```
+---
+
+
+
+
+
+
+
+ [1]: #fp "Jump back to the TOC."
diff --git a/docs/docdown/deps/fp/reverse.md b/docs/docdown/deps/fp/reverse.md
new file mode 100644
index 0000000..5408cb1
--- /dev/null
+++ b/docs/docdown/deps/fp/reverse.md
@@ -0,0 +1,70 @@
+# reverse.js API documentation
+
+
+
+
+
+## `fp`
+* `fp.`
+
+
+
+
+
+
+
+
+
+## `fp`
+
+
+
+fp.exports(x=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/fp/reverse.js#L30 "View in source") [Ⓣ][1]
+
+(Function): Returns a new list or string with the elements or characters in reverse
+order.
+
+
+#### @see
+
+* ramda-reverse
+* stack-overflow-10-ways-to-reverse-string
+
+#### @symb
+
+⬅️
+
+#### @Since
+5.0.0-beta.5
+
+#### Arguments
+1. `x=undefined` *(Array|String): *(list)** string or array to reverse
+
+#### Returns
+*(*)*:
+
+#### Example
+```js
+reverse([1, 2, 3]) //=> [3, 2, 1]
+reverse([1, 2]) //=> [2, 1]
+reverse([1]) //=> [1]
+reverse([]) //=> []
+
+reverse('abc') //=> 'cba'
+reverse('ab') //=> 'ba'
+reverse('a') //=> 'a'
+reverse('') //=> ''
+
+```
+---
+
+
+
+
+
+
+
+ [1]: #fp "Jump back to the TOC."
diff --git a/docs/docdown/deps/gc.md b/docs/docdown/deps/gc.md
index b12f9ed..adb06cb 100644
--- a/docs/docdown/deps/gc.md
+++ b/docs/docdown/deps/gc.md
@@ -5,7 +5,7 @@
## `markForGarbageCollection`
-* `markForGarbageCollection`
+* `markForGarbageCollection`
@@ -19,18 +19,31 @@
-# markForGarbageCollection(obj=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/gc.js#L41 "View in source") [Ⓣ][1]
+markForGarbageCollection(obj=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/gc.js#L42 "View in source") [Ⓣ][1]
(Function): remove all methods, mark for garbage collection
-### @todos
+#### @see
+
+* https://stackoverflow.com/questions/1947995/when-should-i-use-delete-vs-setting-elements-to-null-in-javascript
+* https://v8project.blogspot.ca/2015/08/getting-garbage-collection-for-free.html
+* https://github.com/natewatson999/js-gc
+* https://github.com/siddMahen/node-gc
+* http://buildnewgames.com/garbage-collector-friendly-code/
+* https://stackoverflow.com/questions/27597335/ensuring-object-can-be-garbage-collected
+* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_Management
+
+#### @todos
- [ ] blacklist = [] param
- [ ] put all GC events into a cached map and debounce the operation
-#### Since
+
+#### @Since
4.0.0
#### Arguments
diff --git a/docs/docdown/deps/is/JSON.md b/docs/docdown/deps/is/JSON.md
new file mode 100644
index 0000000..e4f897e
--- /dev/null
+++ b/docs/docdown/deps/is/JSON.md
@@ -0,0 +1,55 @@
+# JSON.js API documentation
+
+
+
+
+
+## `isJSON`
+* `isJSON`
+
+
+
+
+
+
+
+
+
+## `isJSON`
+
+
+
+isJSON(x=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/is/JSON.js#L57 "View in source") [Ⓣ][1]
+
+(Function): isJSON, without tryCatch
+
+#### Arguments
+1. `x=undefined` *(*)*: value to check
+
+#### Returns
+*(boolean)*: x isJSON
+
+#### Example
+```js
+isJSON('{}')
+// => true
+
+isJSON('')
+// => false
+
+isJSON('[]')
+// => true
+
+```
+---
+
+
+
+
+
+
+
+ [1]: #isjson "Jump back to the TOC."
diff --git a/docs/docdown/deps/is/arguments.md b/docs/docdown/deps/is/arguments.md
new file mode 100644
index 0000000..b58036a
--- /dev/null
+++ b/docs/docdown/deps/is/arguments.md
@@ -0,0 +1,66 @@
+# arguments.js API documentation
+
+
+
+
+
+## `isArguments`
+* `isArguments`
+
+
+
+
+
+
+
+
+
+## `isArguments`
+
+
+
+isArguments(x=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/is/arguments.js#L18 "View in source") [Ⓣ][1]
+
+(Function): check if toString on object is Arguments
+
+
+#### @see
+
+* is/toS
+* mozilla-func-arguments
+* node-deep-equals-is-arguments
+* lodash-is-arguments
+* underscore-is-arguments
+
+#### @Since
+4.0.0
+
+#### Arguments
+1. `x=undefined` *(*|Object)*: value to check if isArguments
+
+#### Returns
+*(boolean)*: isArguments
+
+#### Example
+```js
+isArguments({})(
+ //=> false
+ function() {
+ isArguments(arguments)
+ //=> true
+ }
+)()
+
+```
+---
+
+
+
+
+
+
+
+ [1]: #isarguments "Jump back to the TOC."
diff --git a/docs/docdown/deps/is/array.md b/docs/docdown/deps/is/array.md
index fd0efc8..d16d266 100644
--- a/docs/docdown/deps/is/array.md
+++ b/docs/docdown/deps/is/array.md
@@ -4,8 +4,8 @@
-## `isArray`
-* `isArray`
+## `is`
+* `is.isArray`
@@ -15,18 +15,36 @@
-## `isArray`
+## `is`
-# exports
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/is/array.js#L7 "View in source") [Ⓣ][1]
+is.isArray(arg=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/is/array.js#L8 "View in source") [Ⓣ][1]
Function
-#### Since
+
+#### @see
+
+* mozilla-isarray
+
+#### @todos
+
+- [ ] is-arraylike https://github.com/facebook/immutable-js/blob/master/src/utils/isArrayLike.js
+
+
+#### @Since
3.0.0
+#### Arguments
+1. `arg=undefined` *(*)*:
+
+#### Returns
+*(boolean): isArray(arg)*
+
---
@@ -35,4 +53,4 @@ Function
- [1]: #isarray "Jump back to the TOC."
+ [1]: #is "Jump back to the TOC."
diff --git a/docs/docdown/deps/is/arrayOf.md b/docs/docdown/deps/is/arrayOf.md
new file mode 100644
index 0000000..847cf1b
--- /dev/null
+++ b/docs/docdown/deps/is/arrayOf.md
@@ -0,0 +1,56 @@
+# arrayOf.js API documentation
+
+
+
+
+
+## `is`
+* `is.exports`
+
+
+
+
+
+
+
+
+
+## `is`
+
+
+
+is.exports(predicate=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/is/arrayOf.js#L23 "View in source") [Ⓣ][1]
+
+(Function): every item in an array matches predicate
+
+
+#### @Since
+4.0.0 was in validatorBuilder
+
+#### Arguments
+1. `predicate=undefined` *(Function)*: test to pass on every item in an array
+
+#### Returns
+*(boolean)*: all match predicate
+
+#### Example
+```js
+isArrayOf(isTrue)([true, true]) //=> true
+isArrayOf(isEmpty)(['']) //=> true
+
+isArrayOf(isBoolean)([true, false, 1, 2, 0]) //=> false
+isArrayOf(isString)(['string', Number]) //=> false
+
+```
+---
+
+
+
+
+
+
+
+ [1]: #is "Jump back to the TOC."
diff --git a/docs/docdown/deps/is/async.md b/docs/docdown/deps/is/async.md
index e612ab0..6c0c81d 100644
--- a/docs/docdown/deps/is/async.md
+++ b/docs/docdown/deps/is/async.md
@@ -4,8 +4,8 @@
-## `is.prototype`
-* `is.prototype.isAsync`
+## `is`
+* `is.isAsync`
@@ -15,16 +15,23 @@
-## `is.prototype`
+## `is`
-# is.prototype.exports(x=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/is/async.js#L23 "View in source") [Ⓣ][1]
+is.exports(x=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/is/async.js#L24 "View in source") [Ⓣ][1]
Function
-#### Since
+
+#### @see
+
+* is/toS
+
+#### @Since
4.0.0-beta.2
#### Arguments
@@ -52,4 +59,4 @@ isAsync(function() {})
- [1]: #is.prototype "Jump back to the TOC."
+ [1]: #is "Jump back to the TOC."
diff --git a/docs/docdown/deps/is/asyncish.md b/docs/docdown/deps/is/asyncish.md
index 114ebc8..2c3987d 100644
--- a/docs/docdown/deps/is/asyncish.md
+++ b/docs/docdown/deps/is/asyncish.md
@@ -4,8 +4,8 @@
-## `is.prototype`
-* `is.prototype.isAsyncish`
+## `is`
+* `is.isAsyncish`
@@ -15,23 +15,26 @@
-## `is.prototype`
+## `is`
-# is.prototype.exports(x=undefined)
+is.isAsyncish(x=undefined)
+
+
[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/is/asyncish.js#L29 "View in source") [Ⓣ][1]
(Function): async function or promise
-### @extends
+#### @extends
* undefined
* undefined
-#### Since
+
+#### @Since
4.0.0-beta.2
#### Arguments
@@ -42,14 +45,11 @@
#### Example
```js
-isAsyncish(async function() {})
-//=> true
-isAsyncish(new Promise(r => r()))
-//=> true
+isAsyncish(async function() {}) //=> true
+isAsyncish(new Promise(r => r())) //=> true
-isAsyncish({})
-//=> false
-isAsyncish(function() {})
+isAsyncish({}) //=> false
+isAsyncish(function() {}) //=> false
```
---
@@ -60,4 +60,4 @@ isAsyncish(function() {})
- [1]: #is.prototype "Jump back to the TOC."
+ [1]: #is "Jump back to the TOC."
diff --git a/docs/docdown/deps/is/boolean.md b/docs/docdown/deps/is/boolean.md
index 388a134..e0c82a9 100644
--- a/docs/docdown/deps/is/boolean.md
+++ b/docs/docdown/deps/is/boolean.md
@@ -4,8 +4,8 @@
-## `is.prototype`
-* `is.prototype.isBoolean`
+## `is`
+* `is.isBoolean`
@@ -15,32 +15,31 @@
-## `is.prototype`
+## `is`
-# is.prototype.exports(x=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/is/boolean.js#L33 "View in source") [Ⓣ][1]
+is.exports(x=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/is/boolean.js#L32 "View in source") [Ⓣ][1]
-(Function): Checks if `value` is classified as a boolean primitive or object.
+(Function): Checks if `value` is classified as a boolean primitive OR object.
-### @see
+#### @see
-* fluents/chain able/blob/master/src/deps/is/to s.js
+* is/toS
-### @notes
-
-* could also have typeof x === 'boolean' || (/true|false/).test(x)
-
-
-### @extends
+#### @extends
* undefined
* undefined
+* undefined
+
-#### Since
+#### @Since
3.0.0
#### Arguments
@@ -69,4 +68,4 @@ isBoolean('')
- [1]: #is.prototype "Jump back to the TOC."
+ [1]: #is "Jump back to the TOC."
diff --git a/docs/docdown/deps/is/booleanPrimitive.md b/docs/docdown/deps/is/booleanPrimitive.md
new file mode 100644
index 0000000..e3ee731
--- /dev/null
+++ b/docs/docdown/deps/is/booleanPrimitive.md
@@ -0,0 +1,76 @@
+# booleanPrimitive.js API documentation
+
+
+
+
+
+## `is`
+* `is.isBooleanPrimitive`
+
+
+
+
+
+
+
+
+
+## `is`
+
+
+
+is.exports(x=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/is/booleanPrimitive.js#L33 "View in source") [Ⓣ][1]
+
+(Function): Checks if `value` is classified as a boolean primitive NOT object.
+
+
+#### @see
+
+* is/toS
+
+#### @notes
+
+* could also have typeof x === 'boolean' || (/true|false/).test(x)
+
+
+#### @extends
+
+* undefined
+* undefined
+
+
+
+#### @Since
+5.0.0-beta.4
+
+#### Arguments
+1. `x=undefined` *(*)*: value
+
+#### Returns
+*(boolean)*: isBooleanPrimitive
+
+#### Example
+```js
+isBooleanPrimitive(false)
+//=> true
+isBooleanPrimitive(new Boolean(1))
+//=> false
+
+isBooleanPrimitive(1)
+//=> false
+isBooleanPrimitive('')
+//=> false
+
+```
+---
+
+
+
+
+
+
+
+ [1]: #is "Jump back to the TOC."
diff --git a/docs/docdown/deps/is/browser.md b/docs/docdown/deps/is/browser.md
new file mode 100644
index 0000000..6094eca
--- /dev/null
+++ b/docs/docdown/deps/is/browser.md
@@ -0,0 +1,58 @@
+# browser.js API documentation
+
+
+
+
+
+## `is`
+* `is.isBrowser`
+
+
+
+
+
+
+
+
+
+## `is`
+
+
+
+is.isBrowser()
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/is/browser.js#L15 "View in source") [Ⓣ][1]
+
+(Function): check typeof window
+
+
+#### @see
+
+* utils/localGlobal
+
+#### @extends
+
+
+
+
+#### @Since
+5.0.0-beta.1
+
+#### Returns
+*(boolean)*: is in browser, or has global window
+
+#### Example
+```js
+isBrowser() //=> true | false
+
+```
+---
+
+
+
+
+
+
+
+ [1]: #is "Jump back to the TOC."
diff --git a/docs/docdown/deps/is/buffer.md b/docs/docdown/deps/is/buffer.md
new file mode 100644
index 0000000..ba86a5c
--- /dev/null
+++ b/docs/docdown/deps/is/buffer.md
@@ -0,0 +1,60 @@
+# buffer.js API documentation
+
+
+
+
+
+## `is`
+* `is.exports`
+
+
+
+
+
+
+
+
+
+## `is`
+
+
+
+is.exports(x=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/is/buffer.js#L23 "View in source") [Ⓣ][1]
+
+(Function): isBuffer, global Buffer
+
+
+#### @see
+
+* https://github.com/feross/is-buffer
+
+#### @Since
+5.0.0-beta.1
+
+#### Arguments
+1. `x=undefined` *(*|Buffer)*: value to check if Buffer
+
+#### Returns
+*(boolean)*: x is Buffer
+
+
+If you need to support Safari `5-7` *(8-10 yr-old browser)*,
+
+#### Example
+```js
+isBuffer({}) //=> false
+isBuffer(new Buffer('eh')) //=> true
+
+```
+---
+
+
+
+
+
+
+
+ [1]: #is "Jump back to the TOC."
diff --git a/docs/docdown/deps/is/circular.md b/docs/docdown/deps/is/circular.md
new file mode 100644
index 0000000..e8caf02
--- /dev/null
+++ b/docs/docdown/deps/is/circular.md
@@ -0,0 +1,115 @@
+# circular.js API documentation
+
+
+
+
+
+## `errorKeywords`
+* `errorKeywords`
+
+
+
+
+
+## `is`
+* `is.exports`
+
+
+
+
+
+
+
+
+
+## `errorKeywords`
+
+
+
+errorKeywords
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/is/circular.js#L7 "View in source") [Ⓣ][1]
+
+unknown
+
+---
+
+
+
+
+
+
+
+## `is`
+
+
+
+is.exports(obj=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/is/circular.js#L50 "View in source") [Ⓣ][1]
+
+(Function): check if a value is circular
+
+
+#### @notes
+
+* is slow try catch json
+* if (isFunction(obj)) { throw new Error('cannot determine if function is circular')}
+
+
+#### @todos
+
+- [ ] find the circular property...
+
+
+#### @symb
+
+🔘
+
+#### @Since
+5.0.0-beta.4
+
+#### Arguments
+1. `obj=undefined` *(*|Object)*: object to check if is circular
+
+#### Returns
+*(boolean)*: isCircular / hasCircular
+
+#### Example
+```js
+const a = {}
+a.b = a
+isCircular(a) //=> true
+
+const a = {}
+a.b = {
+ c: a,
+}
+isCircular(a) //=> true
+
+const a = {}
+a.b = {
+ c: 4,
+}
+isCircular(a) //=> false
+
+const a = []
+a.push(a)
+isCircular(a) //=> true
+
+isCircular({}) //=> false
+isCircular('hi') //=> false
+isCircular(undefined) //=> false
+
+```
+---
+
+
+
+
+
+
+
+ [1]: #errorkeywords "Jump back to the TOC."
diff --git a/docs/docdown/deps/is/date.md b/docs/docdown/deps/is/date.md
index e387449..29267a6 100644
--- a/docs/docdown/deps/is/date.md
+++ b/docs/docdown/deps/is/date.md
@@ -4,8 +4,8 @@
-## `is.prototype`
-* `is.prototype.isDate`
+## `is`
+* `is.isDate`
@@ -15,21 +15,24 @@
-## `is.prototype`
+## `is`
-# is.prototype.exports(x=undefined)
+is.exports(x=undefined)
+
+
[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/is/date.js#L36 "View in source") [Ⓣ][1]
Function
-### @extends
+#### @extends
-#### Since
+
+#### @Since
3.0.0
#### Arguments
@@ -72,4 +75,4 @@ class Eh extends Date()
- [1]: #is.prototype "Jump back to the TOC."
+ [1]: #is "Jump back to the TOC."
diff --git a/docs/docdown/deps/is/dot.md b/docs/docdown/deps/is/dot.md
index bd80a38..c6be634 100644
--- a/docs/docdown/deps/is/dot.md
+++ b/docs/docdown/deps/is/dot.md
@@ -2,10 +2,64 @@
+
+
+## `is`
+* `is.isDot`
+
+
+
+
+
+## `is`
+
+
+
+is.isDot(x=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/is/dot.js#L24 "View in source") [Ⓣ][1]
+
+Function
+
+
+#### @see
+
+* isArray
+* isString
+* includes
+
+#### @todos
+
+- [ ] update with conditional
+
+
+#### @Since
+3.0.0
+
+#### Arguments
+1. `x=undefined` *(*)*: value to check
+
+#### Returns
+*(boolean)*: x isDot
+
+#### Example
+```js
+isDot('eh.oh') //=> true
+isDot('eh') //=> false
+isDot(['eh', 'oh']) //=> true
+
+```
+---
+
+
+
+
+
- [1]: # "Jump back to the TOC."
+ [1]: #is "Jump back to the TOC."
diff --git a/docs/docdown/deps/is/empty.md b/docs/docdown/deps/is/empty.md
new file mode 100644
index 0000000..a3a5e06
--- /dev/null
+++ b/docs/docdown/deps/is/empty.md
@@ -0,0 +1,67 @@
+# empty.js API documentation
+
+
+
+
+
+## `is`
+* `is.`
+
+
+
+
+
+
+
+
+
+## `is`
+
+
+
+is.exports(x=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/is/empty.js#L33 "View in source") [Ⓣ][1]
+
+(Function): Returns `true` if the given value is its type's empty value;
+`false` otherwise.
+
+
+#### @see
+
+* empty
+* https://github.com/ramda/ramda/issues/1228
+
+#### @sig
+
+a -> Boolean
+
+#### @Since
+v0.1.0
+
+#### Arguments
+1. `x=undefined` *(*)*: value to check if empty
+
+#### Returns
+*(boolean)*:
+
+#### Example
+```js
+isEmpty([1, 2, 3]) //=> false
+isEmpty([]) //=> true
+isEmpty('') //=> true
+isEmpty(null) //=> false
+isEmpty({}) //=> true
+isEmpty({ length: 0 }) //=> false
+
+```
+---
+
+
+
+
+
+
+
+ [1]: #is "Jump back to the TOC."
diff --git a/docs/docdown/deps/is/enumerable.md b/docs/docdown/deps/is/enumerable.md
index d146a52..cb5e8f4 100644
--- a/docs/docdown/deps/is/enumerable.md
+++ b/docs/docdown/deps/is/enumerable.md
@@ -2,10 +2,74 @@
+
+
+## `is`
+* `is.isEnumerable`
+
+
+
+
+
+## `is`
+
+
+
+is.isEnumerable(obj=undefined, prop=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/is/enumerable.js#L32 "View in source") [Ⓣ][1]
+
+(Function): object at property is enumerable
+
+
+#### @see
+
+* mozilla-propertyisenumerable
+
+#### @todos
+
+- [ ] use fp/call
+
+
+#### @Since
+3.0.0
+
+#### Arguments
+1. `obj=undefined` *(*|Object)*:
+2. `prop=undefined` *(*|string)*:
+
+#### Returns
+*(boolean)*: obj[prop] is enumerable
+
+#### Example
+```js
+const obj = { eh: true }
+isEnumerable(obj, 'eh')
+//=> true
+
+const objPropEnumerable = isEnumerable(obj)
+objPropEnumerable('eh')
+//=> true
+
+Object.defineProperty(obj, 'length', {
+ enumerable: false,
+ value: () => Object.keys(obj).length,
+})
+isEnumerable(obj, 'length')
+//=> false
+
+```
+---
+
+
+
+
+
- [1]: # "Jump back to the TOC."
+ [1]: #is "Jump back to the TOC."
diff --git a/docs/docdown/deps/is/error.md b/docs/docdown/deps/is/error.md
index 11a1fff..afb43e2 100644
--- a/docs/docdown/deps/is/error.md
+++ b/docs/docdown/deps/is/error.md
@@ -4,8 +4,8 @@
-## `is.prototype`
-* `is.prototype.isError`
+## `is`
+* `is.isError`
@@ -15,15 +15,21 @@
-## `is.prototype`
+## `is`
-# is.prototype.exports(x=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/is/error.js#L35 "View in source") [Ⓣ][1]
+is.exports(x=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/is/error.js#L36 "View in source") [Ⓣ][1]
Function
+
+#### @Since
+4.0.0
+
#### Arguments
1. `x=undefined` *(*)*: value
@@ -64,4 +70,4 @@ class Eh extends Error()
- [1]: #is.prototype "Jump back to the TOC."
+ [1]: #is "Jump back to the TOC."
diff --git a/docs/docdown/deps/is/false.md b/docs/docdown/deps/is/false.md
index f495f93..253d3b9 100644
--- a/docs/docdown/deps/is/false.md
+++ b/docs/docdown/deps/is/false.md
@@ -4,8 +4,8 @@
-## `is.prototype`
-* `is.prototype.isFalse`
+## `is`
+* `is.isFalse`
@@ -15,16 +15,19 @@
-## `is.prototype`
+## `is`
-# is.prototype.exports(x=undefined)
+is.exports(x=undefined)
+
+
[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/is/false.js#L21 "View in source") [Ⓣ][1]
Function
-#### Since
+
+#### @Since
4.0.0-alpha.1
#### Arguments
@@ -53,4 +56,4 @@ isFalse('')
- [1]: #is.prototype "Jump back to the TOC."
+ [1]: #is "Jump back to the TOC."
diff --git a/docs/docdown/deps/is/function.md b/docs/docdown/deps/is/function.md
index 2f4e1e8..6389c56 100644
--- a/docs/docdown/deps/is/function.md
+++ b/docs/docdown/deps/is/function.md
@@ -4,8 +4,8 @@
-## `is.prototype`
-* `is.prototype.isFunction`
+## `is`
+* `is.isFunction`
@@ -15,21 +15,28 @@
-## `is.prototype`
+## `is`
-# is.prototype.exports(x=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/is/function.js#L37 "View in source") [Ⓣ][1]
+is.exports(x=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/is/function.js#L36 "View in source") [Ⓣ][1]
(Function): Checks if `value` is classified as a `Function` object.
-### @notes
+#### @see
+
+* underscore-is-function
+
+#### @notes
* || x instanceof Function
-#### Since
+
+#### @Since
3.0.0
#### Arguments
@@ -63,4 +70,4 @@ isFunction(/abc/)
- [1]: #is.prototype "Jump back to the TOC."
+ [1]: #is "Jump back to the TOC."
diff --git a/docs/docdown/deps/is/generator.md b/docs/docdown/deps/is/generator.md
index 8f0fcff..ae75023 100644
--- a/docs/docdown/deps/is/generator.md
+++ b/docs/docdown/deps/is/generator.md
@@ -5,7 +5,7 @@
## `exports`
-* `exports`
+* `exports`
@@ -19,12 +19,19 @@
-# exports(x=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/is/generator.js#L16 "View in source") [Ⓣ][1]
+exports(x=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/is/generator.js#L18 "View in source") [Ⓣ][1]
(Function): is generator function
-#### Since
+
+#### @see
+
+* kind-of
+
+#### @Since
4.0.0-beta.2
#### Arguments
diff --git a/docs/docdown/deps/is/hasIn.md b/docs/docdown/deps/is/hasIn.md
index 9771612..a1d2721 100644
--- a/docs/docdown/deps/is/hasIn.md
+++ b/docs/docdown/deps/is/hasIn.md
@@ -4,8 +4,8 @@
-## `exports`
-* `exports`
+## `is`
+* `is.exports`
@@ -15,22 +15,28 @@
-## `exports`
+## `is`
-# exports(obj=undefined, prop=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/is/hasIn.js#L12 "View in source") [Ⓣ][1]
+is.exports(obj=undefined, prop=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/is/hasIn.js#L23 "View in source") [Ⓣ][1]
-Function
+(Function): isIn, but first checks it is not null
-### @extends
+#### @extends
* undefined
* undefined
+
+#### @Since
+5.0.0
+
#### Arguments
1. `obj=undefined` *(Object)*: object to check
2. `prop=undefined` *(any)*: property to check in object
@@ -38,6 +44,13 @@ Function
#### Returns
*(boolean)*:
+#### Example
+```js
+hasIn({}, 'eh') //=> false
+hasIn(null, 'eh') //=> false
+hasIn({ eh: true }, 'eh') //=> true
+
+```
---
@@ -46,4 +59,4 @@ Function
- [1]: #exports "Jump back to the TOC."
+ [1]: #is "Jump back to the TOC."
diff --git a/docs/docdown/deps/is/in.md b/docs/docdown/deps/is/in.md
index 9dc6b4c..f2b1f63 100644
--- a/docs/docdown/deps/is/in.md
+++ b/docs/docdown/deps/is/in.md
@@ -4,8 +4,8 @@
-## `in`
-* ``
+## `is`
+* `is.isIn`
@@ -15,15 +15,34 @@
-## `in`
+## `is`
-
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/is/in.js#L7 "View in source") [Ⓣ][1]
+is.isIn(obj=undefined, prop=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/is/in.js#L20 "View in source") [Ⓣ][1]
-Function
+(Function): prop is in Object(obj)
+
+#### @Since
+5.0.0
+
+#### Arguments
+1. `obj=undefined` *(Object)*: object to check property of
+2. `prop=undefined` *(Primitive)*: property in obj
+
+#### Returns
+*(boolean)*: property
+
+#### Example
+```js
+isIn({ eh: true }, 'eh') //=> true
+isIn({ eh: true }, 'oh') //=> false
+
+```
---
@@ -32,4 +51,4 @@ Function
- [1]: #in "Jump back to the TOC."
+ [1]: #is "Jump back to the TOC."
diff --git a/docs/docdown/deps/is/index.md b/docs/docdown/deps/is/index.md
index b6088ec..2018731 100644
--- a/docs/docdown/deps/is/index.md
+++ b/docs/docdown/deps/is/index.md
@@ -4,8 +4,8 @@
-## `is.prototype.exports`
-* `is.prototype.exports`
+## `is.exports`
+* `is.exports`
@@ -15,22 +15,31 @@
-## `is.prototype.exports`
+## `is.exports`
🌊 Types: is.d
+* 🔬 Tests: empty
* 🔬 Tests: index
* 🔬 Tests: is
+* 🔬 Tests: json
+* 🔬 Tests: not-exported-in-entry
* 🔬 Tests: primitives
* 🔬 Tests: simple
-# is.prototype.exports
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/is/index.js#L37 "View in source") [Ⓣ][1]
+is.exports
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/is/index.js#L38 "View in source") [Ⓣ][1]
Object
+
+#### @see
+
+* https://github.com/lodash/lodash/issues/3237
---
@@ -39,4 +48,4 @@ Object
- [1]: #is.prototype.exports "Jump back to the TOC."
+ [1]: #is.exports "Jump back to the TOC."
diff --git a/docs/docdown/deps/is/instanceOf.md b/docs/docdown/deps/is/instanceOf.md
new file mode 100644
index 0000000..11a0f8b
--- /dev/null
+++ b/docs/docdown/deps/is/instanceOf.md
@@ -0,0 +1,67 @@
+# instanceOf.js API documentation
+
+
+
+
+
+## `instanceOf`
+* `instanceOf`
+
+
+
+
+
+
+
+
+
+## `instanceOf`
+
+
+
+instanceOf(instanceToCheckAgainst=undefined, isThisInstanceOfThat=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/is/instanceOf.js#L26 "View in source") [Ⓣ][1]
+
+Function
+
+
+#### @see
+
+* https://github.com/lodash/lodash/issues/620
+* https://github.com/ramda/ramda/commit/9d4cb895595aca3d83ce0a4b10416ae7302bd8ac
+
+#### @Since
+5.0.0-beta.4
+
+#### Arguments
+1. `instanceToCheckAgainst=undefined` *(Object)*: check the second arg against this
+2. `isThisInstanceOfThat=undefined` *(Object)*: check this against first arg
+
+#### Returns
+*(boolean)*: arg2 instanceof arg1
+
+#### Example
+```js
+const isObjInstance = instanceOf(Object)
+isObjInstance({})
+//=> true
+
+const isArrInstance = instanceOf(Array)
+isArrInstance({})
+//=> false
+
+isArrInstance(new Array())
+//=> true
+
+```
+---
+
+
+
+
+
+
+
+ [1]: #instanceof "Jump back to the TOC."
diff --git a/docs/docdown/deps/is/iteratable.md b/docs/docdown/deps/is/iteratable.md
new file mode 100644
index 0000000..e0da288
--- /dev/null
+++ b/docs/docdown/deps/is/iteratable.md
@@ -0,0 +1,66 @@
+# iteratable.js API documentation
+
+
+
+
+
+## `exports`
+* `exports`
+
+
+
+
+
+
+
+
+
+## `exports`
+
+
+
+exports(x=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/is/iteratable.js#L35 "View in source") [Ⓣ][1]
+
+(Function): is able to be iterated on
+
+
+#### @extends
+
+* undefined
+* undefined
+* undefined
+* undefined
+* undefined
+* undefined
+* undefined
+* undefined
+
+
+#### Arguments
+1. `x=undefined` *(*)*: node is iteratable
+
+#### Returns
+*(boolean)*: x isIteratable
+
+#### Example
+```js
+isIteratable([]) //=> true
+isIteratable({}) //=> true
+isIteratable(new Date()) //=> false
+isIteratable(Symbol('eh')) //=> false
+isIteratable(new Promise(r => r())) //=> false
+isIteratable(new Error('eh')) //=> false
+
+```
+---
+
+
+
+
+
+
+
+ [1]: #exports "Jump back to the TOC."
diff --git a/docs/docdown/deps/is/iterator.md b/docs/docdown/deps/is/iterator.md
index c6758be..0c16e9c 100644
--- a/docs/docdown/deps/is/iterator.md
+++ b/docs/docdown/deps/is/iterator.md
@@ -4,8 +4,8 @@
-## `is.prototype`
-* `is.prototype.isIterator`
+## `is`
+* `is.isIterator`
@@ -15,16 +15,23 @@
-## `is.prototype`
+## `is`
-# is.prototype.(x=undefined)
+is.(x=undefined)
+
+
[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/is/iterator.js#L42 "View in source") [Ⓣ][1]
Function
-#### Since
+
+#### @see
+
+* https://github.com/jonschlinkert/kind-of/pull/12
+
+#### @Since
3.0.0
#### Arguments
@@ -72,4 +79,4 @@ class Eh extends Set()
- [1]: #is.prototype "Jump back to the TOC."
+ [1]: #is "Jump back to the TOC."
diff --git a/docs/docdown/deps/is/map.md b/docs/docdown/deps/is/map.md
index 5f3cd1b..26e19cf 100644
--- a/docs/docdown/deps/is/map.md
+++ b/docs/docdown/deps/is/map.md
@@ -4,8 +4,8 @@
-## `is.prototype`
-* `is.prototype.isMap`
+## `is`
+* `is.isMap`
@@ -15,16 +15,23 @@
-## `is.prototype`
+## `is`
-# is.prototype.exports(x=undefined)
+is.exports(x=undefined)
+
+
[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/is/map.js#L43 "View in source") [Ⓣ][1]
(Function): Checks if `value` is classified as a `Map` object.
-#### Since
+
+#### @see
+
+* https://github.com/jonschlinkert/kind-of
+
+#### @Since
3.0.0
#### Arguments
@@ -72,4 +79,4 @@ class Eh extends Map()
- [1]: #is.prototype "Jump back to the TOC."
+ [1]: #is "Jump back to the TOC."
diff --git a/docs/docdown/deps/is/mapish.md b/docs/docdown/deps/is/mapish.md
index f7551d1..18582ff 100644
--- a/docs/docdown/deps/is/mapish.md
+++ b/docs/docdown/deps/is/mapish.md
@@ -4,8 +4,8 @@
-## `is.prototype`
-* `is.prototype.isMapish`
+## `is`
+* `is.isMapish`
@@ -15,21 +15,24 @@
-## `is.prototype`
+## `is`
-# is.prototype.exports(x=undefined)
+is.exports(x=undefined)
+
+
[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/is/mapish.js#L30 "View in source") [Ⓣ][1]
Function
-### @extends
+#### @extends
-#### Since
+
+#### @Since
3.0.0
#### Arguments
@@ -61,4 +64,4 @@ isMapish(1)
- [1]: #is.prototype "Jump back to the TOC."
+ [1]: #is "Jump back to the TOC."
diff --git a/docs/docdown/deps/is/match.md b/docs/docdown/deps/is/match.md
new file mode 100644
index 0000000..858d0c2
--- /dev/null
+++ b/docs/docdown/deps/is/match.md
@@ -0,0 +1,11 @@
+# match.js API documentation
+
+
+
+
+
+
+
+
+
+ [1]: # "Jump back to the TOC."
diff --git a/docs/docdown/deps/is/matcher.md b/docs/docdown/deps/is/matcher.md
index 14093e8..59968d5 100644
--- a/docs/docdown/deps/is/matcher.md
+++ b/docs/docdown/deps/is/matcher.md
@@ -4,8 +4,8 @@
-## `is.prototype`
-* `is.prototype.isMatcher`
+## `is`
+* `is.isMatcher`
@@ -15,16 +15,25 @@
-## `is.prototype`
+## `is`
-# is.prototype.exports(x=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/is/matcher.js#L25 "View in source") [Ⓣ][1]
+is.exports(x=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/is/matcher.js#L31 "View in source") [Ⓣ][1]
Function
-#### Since
+
+#### @see
+
+* is/regexp
+* is/function
+* conditionals/or
+
+#### @Since
3.0.0
#### Arguments
@@ -55,4 +64,4 @@ isMatcher('.*')
- [1]: #is.prototype "Jump back to the TOC."
+ [1]: #is "Jump back to the TOC."
diff --git a/docs/docdown/deps/is/native.md b/docs/docdown/deps/is/native.md
index 1eb42eb..f9b501b 100644
--- a/docs/docdown/deps/is/native.md
+++ b/docs/docdown/deps/is/native.md
@@ -4,8 +4,8 @@
-## `is.prototype`
-* `is.prototype.isNative`
+## `is`
+* `is.isNative`
@@ -15,16 +15,26 @@
-## `is.prototype`
+## `is`
-# is.prototype.exports(x=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/is/native.js#L19 "View in source") [Ⓣ][1]
+is.exports(x=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/is/native.js#L14 "View in source") [Ⓣ][1]
(Function): based on isNative from react-fibers, based on isNative() from Lodash
-#### Since
+
+#### @see
+
+* Function.toString
+* functiontostring-emca
+* lodash-functiontostring-issue
+* esdiscuss-functiontostring
+
+#### @Since
4.0.6
#### Arguments
@@ -50,4 +60,4 @@ isNative(function normalFunction() {})
- [1]: #is.prototype "Jump back to the TOC."
+ [1]: #is "Jump back to the TOC."
diff --git a/docs/docdown/deps/is/notEmptyArray.md b/docs/docdown/deps/is/notEmptyArray.md
index ac61556..986f8b5 100644
--- a/docs/docdown/deps/is/notEmptyArray.md
+++ b/docs/docdown/deps/is/notEmptyArray.md
@@ -4,8 +4,8 @@
-## `is.prototype`
-* `is.prototype.isNotEmptyArray`
+## `is`
+* `is.isNotEmptyArray`
@@ -15,26 +15,29 @@
-## `is.prototype`
+## `is`
-# is.prototype.exports(x=undefined)
+is.exports(x=undefined)
+
+
[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/is/notEmptyArray.js#L30 "View in source") [Ⓣ][1]
(Function): value is an Array, with at least `1` value
-### @see
+#### @see
-* fluents/chain able/blob/master/src/deps/is/obj with keys.js
-* fluents/chain able/blob/master/src/deps/is/array.js
+* is/objWithKeys
+* is/array
-### @extends
+#### @extends
-#### Since
+
+#### @Since
4.0.0-alpha.1
#### Arguments
@@ -66,4 +69,4 @@ isNotEmptyArray(new Map())
- [1]: #is.prototype "Jump back to the TOC."
+ [1]: #is "Jump back to the TOC."
diff --git a/docs/docdown/deps/is/notNested.md b/docs/docdown/deps/is/notNested.md
new file mode 100644
index 0000000..36d25fa
--- /dev/null
+++ b/docs/docdown/deps/is/notNested.md
@@ -0,0 +1,56 @@
+# notNested.js API documentation
+
+
+
+
+
+## `exports`
+* `exports`
+
+
+
+
+
+
+
+
+
+## `exports`
+
+
+
+exports(x=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/is/notNested.js#L21 "View in source") [Ⓣ][1]
+
+Function
+
+
+#### @Since
+5.0.0
+
+#### Arguments
+1. `x=undefined` *(*)*: value to check
+
+#### Returns
+*(boolean)*: x isNotNested
+
+#### Example
+```js
+isNotNested('') //=> true
+isNotNested(true) //=> true
+isNotNested(new RegExp()) //=> true
+isNotNested(new Error('eh')) //=> false
+isNotNested(null) //=> false
+
+```
+---
+
+
+
+
+
+
+
+ [1]: #exports "Jump back to the TOC."
diff --git a/docs/docdown/deps/is/notRealOrIsEmpty.md b/docs/docdown/deps/is/notRealOrIsEmpty.md
new file mode 100644
index 0000000..8cedb0f
--- /dev/null
+++ b/docs/docdown/deps/is/notRealOrIsEmpty.md
@@ -0,0 +1,44 @@
+# notRealOrIsEmpty.js API documentation
+
+
+
+
+
+## `isNotRealOrIsEmpty`
+* `isNotRealOrIsEmpty`
+
+
+
+
+
+
+
+
+
+## `isNotRealOrIsEmpty`
+
+
+
+isNotRealOrIsEmpty
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/is/notRealOrIsEmpty.js#L17 "View in source") [Ⓣ][1]
+
+Function
+
+
+#### @see
+
+* is/isReal
+* is/isEmpty
+* conditional/and
+* conditional/not
+---
+
+
+
+
+
+
+
+ [1]: #isnotrealorisempty "Jump back to the TOC."
diff --git a/docs/docdown/deps/is/null.md b/docs/docdown/deps/is/null.md
index 7d6228e..66eb977 100644
--- a/docs/docdown/deps/is/null.md
+++ b/docs/docdown/deps/is/null.md
@@ -4,8 +4,8 @@
-## `is.prototype`
-* `is.prototype.isNull`
+## `is`
+* `is.isNull`
@@ -15,16 +15,19 @@
-## `is.prototype`
+## `is`
-# is.prototype.exports(x=undefined)
+is.exports(x=undefined)
+
+
[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/is/null.js#L26 "View in source") [Ⓣ][1]
Function
-#### Since
+
+#### @Since
3.0.0
#### Arguments
@@ -58,4 +61,4 @@ isNull(1)
- [1]: #is.prototype "Jump back to the TOC."
+ [1]: #is "Jump back to the TOC."
diff --git a/docs/docdown/deps/is/nullOrUndefined.md b/docs/docdown/deps/is/nullOrUndefined.md
index d0c16b3..b79ec0d 100644
--- a/docs/docdown/deps/is/nullOrUndefined.md
+++ b/docs/docdown/deps/is/nullOrUndefined.md
@@ -4,8 +4,8 @@
-## `is.prototype`
-* `is.prototype.isNullOrUndefined`
+## `is`
+* `is.isNullOrUndefined`
@@ -15,21 +15,25 @@
-## `is.prototype`
+## `is`
-# is.prototype.exports(x=undefined)
+is.exports(x=undefined)
+
+
[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/is/nullOrUndefined.js#L41 "View in source") [Ⓣ][1]
(Function): Checks if `value` is `null` or `undefined`.
-### @see
+#### @see
-* fluents/chain able/blob/master/src/deps/is/null.js
-* fluents/chain able/blob/master/src/deps/is/undefined.js
-#### Since
+* is/null
+* is/undefined
+* https://github.com/infernojs/inferno/blob/master/packages/inferno-shared/src/index.ts#L23
+
+#### @Since
4.0.0-alpha.1
#### Arguments
@@ -67,4 +71,4 @@ isNullOrUndefined(false)
- [1]: #is.prototype "Jump back to the TOC."
+ [1]: #is "Jump back to the TOC."
diff --git a/docs/docdown/deps/is/number.md b/docs/docdown/deps/is/number.md
index ec51cfd..dc8f5ed 100644
--- a/docs/docdown/deps/is/number.md
+++ b/docs/docdown/deps/is/number.md
@@ -4,8 +4,8 @@
-## `is.prototype`
-* `is.prototype.isNumber`
+## `is`
+* `is.isNumber`
@@ -15,21 +15,24 @@
-## `is.prototype`
+## `is`
-# is.prototype.exports(x=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/is/number.js#L42 "View in source") [Ⓣ][1]
+is.exports(x=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/is/number.js#L51 "View in source") [Ⓣ][1]
Function
-### @see
+#### @see
-* fluents/chain able/blob/master/src/deps/is/real.js
+* is/real
+* http://stackoverflow.com/questions/18082/validate-decimal-numbers-in-javascript-isnumeric
-### @notes
+#### @notes
* was not needed except for abstract ==
const isObj = require('./obj')
@@ -39,7 +42,13 @@ Function
: (/^0x[0-9a-f]+$/i).test(x) ||
(/^[-+]?(?:\d+(?:\.\d*)?|\.\d+)(e[-+]?\d+)?$/).test(x))
-#### Since
+
+#### @extends
+
+
+
+
+#### @Since
3.0.0
#### Arguments
@@ -52,6 +61,8 @@ Function
```js
isNumber(1)
//=> true
+isNumber(new Number(1))
+//=> true
isNumber(Number(1))
//=> true
isNumber(NaN)
@@ -79,4 +90,4 @@ isNumber(false)
- [1]: #is.prototype "Jump back to the TOC."
+ [1]: #is "Jump back to the TOC."
diff --git a/docs/docdown/deps/is/numberPrimitive.md b/docs/docdown/deps/is/numberPrimitive.md
new file mode 100644
index 0000000..5a1c989
--- /dev/null
+++ b/docs/docdown/deps/is/numberPrimitive.md
@@ -0,0 +1,76 @@
+# numberPrimitive.js API documentation
+
+
+
+
+
+## `is`
+* `is.isNumberPrimitive`
+
+
+
+
+
+
+
+
+
+## `is`
+
+
+
+is.exports(x=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/is/numberPrimitive.js#L35 "View in source") [Ⓣ][1]
+
+Function
+
+
+#### @see
+
+* is/real
+
+#### @Since
+3.0.0
+
+#### Arguments
+1. `x=undefined` *(*)*: value
+
+#### Returns
+*(boolean)*: isNumberPrimitive
+
+#### Example
+```js
+isNumberPrimitive(1)
+//=> true
+isNumberPrimitive(Number(1))
+//=> true
+isNumberPrimitive(NaN)
+//=> true
+isNumberPrimitive(new Number(1))
+//=> false
+
+isNumberPrimitive(null)
+//=> false
+isNumberPrimitive(undefined)
+//=> false
+isNumberPrimitive(void 0)
+//=> false
+isNumberPrimitive({})
+//=> false
+isNumberPrimitive('')
+//=> false
+isNumberPrimitive(false)
+//=> false
+
+```
+---
+
+
+
+
+
+
+
+ [1]: #is "Jump back to the TOC."
diff --git a/docs/docdown/deps/is/obj.md b/docs/docdown/deps/is/obj.md
index 3a9e6b4..e36c1cc 100644
--- a/docs/docdown/deps/is/obj.md
+++ b/docs/docdown/deps/is/obj.md
@@ -4,8 +4,8 @@
-## `is.prototype`
-* `is.prototype.isObj`
+## `is`
+* `is.isObj`
@@ -15,21 +15,29 @@
-## `is.prototype`
+## `is`
-# is.prototype.exports(value=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/is/obj.js#L34 "View in source") [Ⓣ][1]
+is.exports(value=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/is/obj.js#L38 "View in source") [Ⓣ][1]
Function
-### @notes
+#### @see
+
+* http://stackoverflow.com/questions/34111902/why-do-lodashs-isobject-isplainobject-behave-differently-than-typeof-x
+* https://github.com/lodash/lodash/blob/master/isObject.js
+
+#### @notes
* Object.prototype.toString.call(val) === '[object Object]'
-#### Since
+
+#### @Since
3.0.0
#### Arguments
@@ -61,4 +69,4 @@ isObject(null)
- [1]: #is.prototype "Jump back to the TOC."
+ [1]: #is "Jump back to the TOC."
diff --git a/docs/docdown/deps/is/objLoose.md b/docs/docdown/deps/is/objLoose.md
deleted file mode 100644
index 3832328..0000000
--- a/docs/docdown/deps/is/objLoose.md
+++ /dev/null
@@ -1,72 +0,0 @@
-# objLoose.js API documentation
-
-
-
-
-
-## `is.prototype`
-* `is.prototype.isObjLoose`
-
-
-
-
-
-
-
-
-
-## `is.prototype`
-
-
-
-# is.prototype.exports(x=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/is/objLoose.js#L34 "View in source") [Ⓣ][1]
-
-Function
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/is/obj.js
-* fluents/chain able/blob/master/src/deps/is/obj with keys.js
-* fluents/chain able/blob/master/src/deps/is/obj strict.js
-* fluents/chain able/blob/master/src/deps/is/null.js
-#### Since
-3.0.0
-
-#### Arguments
-1. `x=undefined` *(*)*: value
-
-#### Returns
-*(boolean)*: isObjLoose
-
-#### Example
-```js
-isObjLoose(new Object())
-//=> true
-isObjLoose({})
-//=> true
-isObjLoose(Object.create(null))
-//=> true
-isObjLoose(null)
-//=> true
-
-isObjLoose(new Set())
-//=> false
-isObjLoose(function() {})
-//=> false
-isObjLoose('')
-//=> false
-isObjLoose(1)
-//=> false
-
-```
----
-
-
-
-
-
-
-
- [1]: #is.prototype "Jump back to the TOC."
diff --git a/docs/docdown/deps/is/objNotNull.md b/docs/docdown/deps/is/objNotNull.md
new file mode 100644
index 0000000..82450a2
--- /dev/null
+++ b/docs/docdown/deps/is/objNotNull.md
@@ -0,0 +1,87 @@
+# objNotNull.js API documentation
+
+
+
+
+
+## `is`
+* `is.isObjNotNull`
+
+
+
+
+
+
+
+
+
+## `is`
+
+
+
+is.exports(x=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/is/objNotNull.js#L34 "View in source") [Ⓣ][1]
+
+Function
+
+
+#### @see
+
+* is/obj
+* is/objWithKeys
+* is/objTypeof
+* is/null
+* is-obj
+* lodash-is-object-like
+
+#### @todos
+
+- [ ] !Array.isArray
+
+
+#### @extends
+
+
+
+
+#### @Since
+3.0.0
+
+#### Arguments
+1. `x=undefined` *(*)*: value
+
+#### Returns
+*(boolean)*: isObjNotNull
+
+#### Example
+```js
+isObjNotNull(new Object())
+//=> true
+isObjNotNull({})
+//=> true
+isObjNotNull(Object.create(null))
+//=> true
+isObjNotNull(null)
+//=> false
+
+isObjNotNull(new Set())
+//=> false
+isObjNotNull(function() {})
+//=> false
+isObjNotNull('')
+//=> false
+isObjNotNull(1)
+//=> false
+
+```
+---
+
+
+
+
+
+
+
+ [1]: #is "Jump back to the TOC."
diff --git a/docs/docdown/deps/is/objPure.md b/docs/docdown/deps/is/objPure.md
index e985fe6..b3d872f 100644
--- a/docs/docdown/deps/is/objPure.md
+++ b/docs/docdown/deps/is/objPure.md
@@ -2,10 +2,68 @@
+
+
+## `is`
+* `is.isObjPure`
+
+
+
+
+
+## `is`
+
+
+
+is.isObjPure(x=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/is/objPure.js#L34 "View in source") [Ⓣ][1]
+
+Function
+
+
+#### @extends
+
+* undefined
+* undefined
+* undefined
+* undefined
+
+
+
+#### @Since
+3.0.0
+
+#### Arguments
+1. `x=undefined` *(*)*: value to check
+
+#### Returns
+*(boolean)*: is obj & !null & !undefined & !array & !function
+
+#### Example
+```js
+isObjPure(function() {})
+//=> false
+isObjPure(null)
+//=> false
+isObjPure([])
+//=> false
+
+isObjPure({})
+//=> true
+
+```
+---
+
+
+
+
+
- [1]: # "Jump back to the TOC."
+ [1]: #is "Jump back to the TOC."
diff --git a/docs/docdown/deps/is/objStrict.md b/docs/docdown/deps/is/objStrict.md
deleted file mode 100644
index 391f298..0000000
--- a/docs/docdown/deps/is/objStrict.md
+++ /dev/null
@@ -1,82 +0,0 @@
-# objStrict.js API documentation
-
-
-
-
-
-## `is.prototype`
-* `is.prototype.isObjStrict`
-
-
-
-
-
-
-
-
-
-## `is.prototype`
-
-
-
-# is.prototype.exports(x=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/is/objStrict.js#L42 "View in source") [Ⓣ][1]
-
-Function
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/is/obj.js
-* fluents/chain able/blob/master/src/deps/is/obj with keys.js
-* fluents/chain able/blob/master/src/deps/is/obj loose.js
-* fluents/chain able/blob/master/src/deps/is/null.js
-
-### @todos
-
-- [ ] !Array.isArray
-
-
-### @extends
-
-
-
-#### Since
-3.0.0
-
-#### Arguments
-1. `x=undefined` *(*)*: value
-
-#### Returns
-*(boolean)*: isObjStrict
-
-#### Example
-```js
-isObjStrict(new Object())
-//=> true
-isObjStrict({})
-//=> true
-isObjStrict(Object.create(null))
-//=> true
-isObjStrict(null)
-//=> false
-
-isObjStrict(new Set())
-//=> false
-isObjStrict(function() {})
-//=> false
-isObjStrict('')
-//=> false
-isObjStrict(1)
-//=> false
-
-```
----
-
-
-
-
-
-
-
- [1]: #is.prototype "Jump back to the TOC."
diff --git a/docs/docdown/deps/is/objTypeof.md b/docs/docdown/deps/is/objTypeof.md
new file mode 100644
index 0000000..00a1dda
--- /dev/null
+++ b/docs/docdown/deps/is/objTypeof.md
@@ -0,0 +1,75 @@
+# objTypeof.js API documentation
+
+
+
+
+
+## `is`
+* `is.isObjLoose`
+
+
+
+
+
+
+
+
+
+## `is`
+
+
+
+is.exports(x=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/is/objTypeof.js#L34 "View in source") [Ⓣ][1]
+
+Function
+
+
+#### @see
+
+* is/obj
+* is/objWithKeys
+* is/objStrict
+* is/null
+
+#### @Since
+3.0.0
+
+#### Arguments
+1. `x=undefined` *(*)*: value
+
+#### Returns
+*(boolean)*: isObjLoose
+
+#### Example
+```js
+isObjLoose(new Object())
+//=> true
+isObjLoose({})
+//=> true
+isObjLoose(Object.create(null))
+//=> true
+isObjLoose(null)
+//=> true
+
+isObjLoose(new Set())
+//=> false
+isObjLoose(function() {})
+//=> false
+isObjLoose('')
+//=> false
+isObjLoose(1)
+//=> false
+
+```
+---
+
+
+
+
+
+
+
+ [1]: #is "Jump back to the TOC."
diff --git a/docs/docdown/deps/is/objWithKeys.md b/docs/docdown/deps/is/objWithKeys.md
index 61bd528..3b54f3a 100644
--- a/docs/docdown/deps/is/objWithKeys.md
+++ b/docs/docdown/deps/is/objWithKeys.md
@@ -4,8 +4,8 @@
-## `is.prototype`
-* `is.prototype.isObjWithKeys`
+## `is`
+* `is.isObjWithKeys`
@@ -15,28 +15,36 @@
-## `is.prototype`
+## `is`
-# is.prototype.exports(x=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/is/objWithKeys.js#L41 "View in source") [Ⓣ][1]
+is.exports(x=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/is/objWithKeys.js#L43 "View in source") [Ⓣ][1]
Function
-### @see
+#### @see
-* fluents/chain able/blob/master/src/deps/is/obj.js
-* fluents/chain able/blob/master/src/deps/is/obj with keys.js
-* fluents/chain able/blob/master/src/deps/is/obj strict.js
-* fluents/chain able/blob/master/src/deps/is/null.js
+* is/obj
+* is/objWithKeys
+* is/objStrict
+* is/null
-### @extends
+#### @todos
+- [ ] @NOTE need to be more careful, needs to check for vanilla objects, not native ones since e.g. Error has no keys
+
+#### @extends
-#### Since
+
+
+
+#### @Since
3.0.0
#### Arguments
@@ -75,4 +83,4 @@ isObjWithKeys(1)
- [1]: #is.prototype "Jump back to the TOC."
+ [1]: #is "Jump back to the TOC."
diff --git a/docs/docdown/deps/is/primitive.md b/docs/docdown/deps/is/primitive.md
new file mode 100644
index 0000000..9a92eea
--- /dev/null
+++ b/docs/docdown/deps/is/primitive.md
@@ -0,0 +1,69 @@
+# primitive.js API documentation
+
+
+
+
+
+## `is`
+* `is.exports`
+
+
+
+
+
+
+
+
+
+## `is`
+
+
+
+is.exports(x=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/is/primitive.js#L36 "View in source") [Ⓣ][1]
+
+(Function): Checks if `value` is classified as a **primitive**
+`(number|string|boolean|null|undefined)`
+
+
+#### @see
+
+* http://www.adequatelygood.com/Object-to-Primitive-Conversions-in-JavaScript.html
+* https://developer.mozilla.org/en-US/docs/Glossary/Primitive
+* http://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html
+
+#### @Since
+4.0.0 was in another file
+
+#### Arguments
+1. `x=undefined` *(*)*: The value to check.
+
+#### Returns
+*(boolean)*: x is number|string|boolean|null|undefined
+
+#### Example
+```js
+isPrimitive('abc') // => true
+isPrimitive(1) // => true
+isPrimitive('') // => true
+isPrimitive(null) // => true
+isPrimitive(undefined) // => true
+isPrimitive(void 0) // => true
+
+isPrimitive(new String('abc')) // => false
+isPrimitive([]) // => false
+isPrimitive(() => {}) // => false
+isPrimitive({}) // => false
+
+```
+---
+
+
+
+
+
+
+
+ [1]: #is "Jump back to the TOC."
diff --git a/docs/docdown/deps/is/promise.md b/docs/docdown/deps/is/promise.md
index 00b2e44..7a36919 100644
--- a/docs/docdown/deps/is/promise.md
+++ b/docs/docdown/deps/is/promise.md
@@ -4,8 +4,8 @@
-## `is.prototype`
-* `is.prototype.isPromise`
+## `is`
+* `is.isPromise`
@@ -15,16 +15,24 @@
-## `is.prototype`
+## `is`
-# is.prototype.exports(x=undefined)
+is.exports(x=undefined)
+
+
[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/is/promise.js#L38 "View in source") [Ⓣ][1]
(Function): is a Promise
-#### Since
+
+#### @see
+
+* https://github.com/jonschlinkert/kind-of/blob/master/index.js#L66
+* https://github.com/sindresorhus/promise-fun
+
+#### @Since
4.0.0-beta.2
#### Arguments
@@ -64,4 +72,4 @@ isPromise(1)
- [1]: #is.prototype "Jump back to the TOC."
+ [1]: #is "Jump back to the TOC."
diff --git a/docs/docdown/deps/is/prototypeOf.md b/docs/docdown/deps/is/prototypeOf.md
index 9b8b715..a5473a6 100644
--- a/docs/docdown/deps/is/prototypeOf.md
+++ b/docs/docdown/deps/is/prototypeOf.md
@@ -2,10 +2,68 @@
+
+
+## `is`
+* `is.isPrototypeOf`
+
+
+
+
+
+## `is`
+
+
+
+is.isPrototypeOf(haystack=undefined, needle=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/is/prototypeOf.js#L24 "View in source") [Ⓣ][1]
+
+(Function): check if arg `1` is prototype of arg `2`
+
+
+#### @see
+
+* mozilla-obj-isprototypeof
+
+#### @todos
+
+- [ ] curry2
+
+
+#### @Since
+3.0.0
+
+#### Arguments
+1. `haystack=undefined` *(*|Object)*: check needle against
+2. `needle=undefined` *(*|Object)*: is prototype of haystack
+
+#### Returns
+*(boolean)*: needle isPrototypeOf haystack
+
+#### Example
+```js
+class Eh extends Function {}
+class Canada extends Eh {}
+isPrototypeOf(Eh, Function) //=> true
+isPrototypeOf(Canada, Function) //=> true
+isPrototypeOf(Eh, Date) //=> false
+
+isPrototypeOf({}, Object) //=> true
+isPrototypeOf({}, Array) //=> false
+
+```
+---
+
+
+
+
+
- [1]: # "Jump back to the TOC."
+ [1]: #is "Jump back to the TOC."
diff --git a/docs/docdown/deps/is/real.md b/docs/docdown/deps/is/real.md
index aa9c5c6..a6d6624 100644
--- a/docs/docdown/deps/is/real.md
+++ b/docs/docdown/deps/is/real.md
@@ -4,8 +4,8 @@
-## `is.prototype`
-* `is.prototype.isReal`
+## `is`
+* `is.isReal`
@@ -15,32 +15,38 @@
-## `is.prototype`
+## `is`
-# is.prototype.exports(x=undefined)
+is.exports(x=undefined)
+
+
[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/is/real.js#L51 "View in source") [Ⓣ][1]
Function
-### @see
+#### @see
-* fluents/chain able/blob/master/src/deps/is/null.js
-* fluents/chain able/blob/master/src/deps/is/undefined.js
+* is/null
+* is/undefined
+* http://2ality.com/2013/04/quirk-implicit-conversion.html
+* https://javascriptrefined.io/nan-and-typeof-36cd6e2a4e43
+* https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/isNaN
-### @notes
+#### @notes
* eslint-disable-next-line no-self-compare
&& x !== x
-### @extends
+#### @extends
-#### Since
+
+#### @Since
3.0.0
#### Arguments
@@ -85,4 +91,4 @@ isReal(1)
- [1]: #is.prototype "Jump back to the TOC."
+ [1]: #is "Jump back to the TOC."
diff --git a/docs/docdown/deps/is/regexp.md b/docs/docdown/deps/is/regexp.md
index 1b09546..d6e5778 100644
--- a/docs/docdown/deps/is/regexp.md
+++ b/docs/docdown/deps/is/regexp.md
@@ -5,7 +5,7 @@
## `exports`
-* `exports`
+* `exports`
@@ -19,16 +19,23 @@
-# exports(value=undefined)
+exports(x=undefined)
+
+
[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/is/regexp.js#L21 "View in source") [Ⓣ][1]
(Function): Checks if `value` is classified as a `RegExp` object.
-#### Since
+
+#### @see
+
+* https://github.com/lodash/lodash/blob/master/isRegExp.js
+
+#### @Since
0.1.0
#### Arguments
-1. `value=undefined` *(*)*: The value to check.
+1. `x=undefined` *(*)*: The value to check.
#### Returns
*(boolean)*: Returns `true` if `value` is a regexp, else `false`.
diff --git a/docs/docdown/deps/is/set.md b/docs/docdown/deps/is/set.md
index f728c58..342b130 100644
--- a/docs/docdown/deps/is/set.md
+++ b/docs/docdown/deps/is/set.md
@@ -5,7 +5,7 @@
## `exports`
-* `exports`
+* `exports`
@@ -19,12 +19,15 @@
-# exports(x=undefined)
+exports(x=undefined)
+
+
[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/is/set.js#L20 "View in source") [Ⓣ][1]
(Function): Checks if `value` is classified as a `Set` object.
-#### Since
+
+#### @Since
4.3.0
#### Arguments
diff --git a/docs/docdown/deps/is/string.md b/docs/docdown/deps/is/string.md
index e9e6ea8..224c677 100644
--- a/docs/docdown/deps/is/string.md
+++ b/docs/docdown/deps/is/string.md
@@ -4,8 +4,8 @@
-## `is.prototype`
-* `is.prototype.exports`
+## `is`
+* `is.exports`
@@ -15,21 +15,30 @@
-## `is.prototype`
+## `is`
-# is.prototype.exports(x=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/is/string.js#L31 "View in source") [Ⓣ][1]
+is.exports(x=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/is/string.js#L32 "View in source") [Ⓣ][1]
(Function): Checks if `value` is classified as a `String` primitive or object.
-### @extends
+#### @see
+* https://github.com/lodash/lodash/blob/master/isString.js
+* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String
+* isStringPrimitive
+#### @extends
-#### Since
+
+
+
+#### @Since
3.0.0
#### Arguments
@@ -58,4 +67,4 @@ isString(1)
- [1]: #is.prototype "Jump back to the TOC."
+ [1]: #is "Jump back to the TOC."
diff --git a/docs/docdown/deps/is/stringOrNumber.md b/docs/docdown/deps/is/stringOrNumber.md
index bd79c8f..85fcc24 100644
--- a/docs/docdown/deps/is/stringOrNumber.md
+++ b/docs/docdown/deps/is/stringOrNumber.md
@@ -4,8 +4,8 @@
-## `is.prototype`
-* `is.prototype.exports`
+## `is`
+* `is.exports`
@@ -15,16 +15,24 @@
-## `is.prototype`
+## `is`
-# is.prototype.exports(x=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/is/stringOrNumber.js#L24 "View in source") [Ⓣ][1]
+is.exports(x=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/is/stringOrNumber.js#L25 "View in source") [Ⓣ][1]
(Function): Checks if `value` is classified as a `String` primitive or object.
-#### Since
+
+#### @see
+
+* https://github.com/infernojs/inferno/blob/master/packages/inferno-shared/src/index.ts#L23
+* https://github.com/lodash/lodash/blob/master/isString.js
+
+#### @Since
3.0.0
#### Arguments
@@ -50,4 +58,4 @@ isString(1)
- [1]: #is.prototype "Jump back to the TOC."
+ [1]: #is "Jump back to the TOC."
diff --git a/docs/docdown/deps/is/stringPrimitive.md b/docs/docdown/deps/is/stringPrimitive.md
index 6c08a0f..03dc93f 100644
--- a/docs/docdown/deps/is/stringPrimitive.md
+++ b/docs/docdown/deps/is/stringPrimitive.md
@@ -4,8 +4,8 @@
-## `is.prototype`
-* `is.prototype.exports`
+## `is`
+* `is.exports`
@@ -15,20 +15,25 @@
-## `is.prototype`
+## `is`
-# is.prototype.exports(x=undefined)
+is.exports(x=undefined)
+
+
[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/is/stringPrimitive.js#L27 "View in source") [Ⓣ][1]
(Function): Checks if `value` is classified as a `String` **primitive**.
-### @see
+#### @see
-* fluents/chain able/blob/master/src/deps/is/string.js
-#### Since
+* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String
+* https://github.com/lodash/lodash/blob/master/isString.js
+* is/string
+
+#### @Since
3.0.0
#### Arguments
@@ -57,4 +62,4 @@ isString(1)
- [1]: #is.prototype "Jump back to the TOC."
+ [1]: #is "Jump back to the TOC."
diff --git a/docs/docdown/deps/is/symbol.md b/docs/docdown/deps/is/symbol.md
index dbe801c..ae6faad 100644
--- a/docs/docdown/deps/is/symbol.md
+++ b/docs/docdown/deps/is/symbol.md
@@ -4,8 +4,8 @@
-## `is.prototype`
-* `is.prototype.exports`
+## `is`
+* `is.exports`
@@ -15,16 +15,19 @@
-## `is.prototype`
+## `is`
-# is.prototype.exports(value=undefined)
+is.exports(value=undefined)
+
+
[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/is/symbol.js#L22 "View in source") [Ⓣ][1]
(Function): Checks if `value` is classified as a `Symbol` primitive or object.
-#### Since
+
+#### @Since
4.0.0
#### Arguments
@@ -50,4 +53,4 @@ isSymbol('abc')
- [1]: #is.prototype "Jump back to the TOC."
+ [1]: #is "Jump back to the TOC."
diff --git a/docs/docdown/deps/is/toS.md b/docs/docdown/deps/is/toS.md
index bc51b80..982ab10 100644
--- a/docs/docdown/deps/is/toS.md
+++ b/docs/docdown/deps/is/toS.md
@@ -4,8 +4,8 @@
-## `is.prototype`
-* `is.prototype.exports`
+## `is`
+* `is.exports`
@@ -15,21 +15,32 @@
-## `is.prototype`
+## `is`
-# is.prototype.exports(obj=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/is/toS.js#L25 "View in source") [Ⓣ][1]
+is.exports(obj=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/is/toS.js#L34 "View in source") [Ⓣ][1]
(Function): The base implementation of `getTag` without fallbacks for buggy environments.
-### @todos
+#### @see
+
+* https://github.com/lodash/lodash/blob/master/.internal/baseGetTag.js
+* https://github.com/jonschlinkert/kind-of
+* https://github.com/substack/js-traverse/blob/master/index.js#L285
+* http://luxiyalu.com/object-prototype-tostring-call/
+
+#### @todos
- [ ] obj[Symbol.toStringTag]
+- [ ] run deopt check on this invoking see how many invocations... are needed to inline
-#### Since
+
+#### @Since
3.0.0
#### Arguments
@@ -41,10 +52,13 @@
#### Example
```js
toS({})
-//=> '[Object object]'
+//=> '[object Object]'
toS(function() {})
-//=> '[Object function]'
+//=> '[Object Function]'
+
+getTag([])
+//=> '[object Array]'
```
---
@@ -55,4 +69,4 @@ toS(function() {})
- [1]: #is.prototype "Jump back to the TOC."
+ [1]: #is "Jump back to the TOC."
diff --git a/docs/docdown/deps/is/true.md b/docs/docdown/deps/is/true.md
index 80c05fc..c49ab82 100644
--- a/docs/docdown/deps/is/true.md
+++ b/docs/docdown/deps/is/true.md
@@ -4,8 +4,8 @@
-## `is.prototype`
-* `is.prototype.isTrue`
+## `is`
+* `is.isTrue`
@@ -15,16 +15,19 @@
-## `is.prototype`
+## `is`
-# is.prototype.exports(x=undefined)
+is.exports(x=undefined)
+
+
[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/is/true.js#L21 "View in source") [Ⓣ][1]
Function
-#### Since
+
+#### @Since
4.0.0-alpha.1
#### Arguments
@@ -53,4 +56,4 @@ isTrue('')
- [1]: #is.prototype "Jump back to the TOC."
+ [1]: #is "Jump back to the TOC."
diff --git a/docs/docdown/deps/is/undefined.md b/docs/docdown/deps/is/undefined.md
index c36fad1..1729814 100644
--- a/docs/docdown/deps/is/undefined.md
+++ b/docs/docdown/deps/is/undefined.md
@@ -4,8 +4,8 @@
-## `is.prototype`
-* `is.prototype.isUndefined`
+## `is`
+* `is.isUndefined`
@@ -15,25 +15,24 @@
-## `is.prototype`
+## `is`
-# is.prototype.exports(x=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/is/undefined.js#L38 "View in source") [Ⓣ][1]
+is.exports(x=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/is/undefined.js#L36 "View in source") [Ⓣ][1]
(Function): Checks if `value` is `undefined`.
-### @see
+#### @see
-* fluents/chain able/blob/master/src/deps/is/null or undefined.js
+* is/nullOrUndefined
+* https://github.com/infernojs/inferno/blob/master/packages/inferno-shared/src/index.ts#L57
-### @notes
-
-* || typeof x === 'undefined'
-
-#### Since
+#### @Since
4.0.0-alpha.1
#### Arguments
@@ -71,4 +70,4 @@ isUndefined(false)
- [1]: #is.prototype "Jump back to the TOC."
+ [1]: #is "Jump back to the TOC."
diff --git a/docs/docdown/deps/is/undefinedLike.md b/docs/docdown/deps/is/undefinedLike.md
new file mode 100644
index 0000000..ab2c412
--- /dev/null
+++ b/docs/docdown/deps/is/undefinedLike.md
@@ -0,0 +1,65 @@
+# undefinedLike.js API documentation
+
+
+
+
+
+## `is`
+* `is.isUndefinedLike`
+
+
+
+
+
+
+
+
+
+## `is`
+
+
+
+is.exports(x=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/is/undefinedLike.js#L26 "View in source") [Ⓣ][1]
+
+(Function): Checks if `value` is `undefined` OR `"undefined"`
+
+
+#### @see
+
+* is/nullOrUndefined
+
+#### @extends
+
+
+
+
+#### @Since
+5.0.0-beta.4
+
+#### Arguments
+1. `x=undefined` *(*)*: value
+
+#### Returns
+*(boolean)*: x isUndefinedLike
+
+#### Example
+```js
+isUndefined(void 0) //=> true
+isUndefined(undefined) //=> true
+isUndefined('undefined') //=> true
+isUndefined(NaN) //=> false
+isUndefined({}) //=> false
+
+```
+---
+
+
+
+
+
+
+
+ [1]: #is "Jump back to the TOC."
diff --git a/docs/docdown/deps/is/weakMap.md b/docs/docdown/deps/is/weakMap.md
new file mode 100644
index 0000000..03a3ec4
--- /dev/null
+++ b/docs/docdown/deps/is/weakMap.md
@@ -0,0 +1,56 @@
+# weakMap.js API documentation
+
+
+
+
+
+## `isWeakMap`
+* `isWeakMap`
+
+
+
+
+
+
+
+
+
+## `isWeakMap`
+
+
+
+isWeakMap(x=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/is/weakMap.js#L21 "View in source") [Ⓣ][1]
+
+(Function): Checks if `value` is classified as a `WeakMap` object.
+
+
+#### @Since
+5.0.0-beta.4
+
+#### Arguments
+1. `x=undefined` *(*)*: The value to check.
+
+#### Returns
+*(boolean)*: Returns `true` if `value` is a weak map, else `false`.
+
+#### Example
+```js
+isWeakMap(new WeakMap())
+// => true
+
+isWeakMap(new Map())
+// => false
+
+```
+---
+
+
+
+
+
+
+
+ [1]: #isweakmap "Jump back to the TOC."
diff --git a/docs/docdown/deps/is/weakSet.md b/docs/docdown/deps/is/weakSet.md
new file mode 100644
index 0000000..538033c
--- /dev/null
+++ b/docs/docdown/deps/is/weakSet.md
@@ -0,0 +1,56 @@
+# weakSet.js API documentation
+
+
+
+
+
+## `isWeakSet`
+* `isWeakSet`
+
+
+
+
+
+
+
+
+
+## `isWeakSet`
+
+
+
+isWeakSet(x=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/is/weakSet.js#L21 "View in source") [Ⓣ][1]
+
+(Function): Checks if `value` is classified as a `isWeakSet` object.
+
+
+#### @Since
+5.0.0-beta.4
+
+#### Arguments
+1. `x=undefined` *(*)*: The value to check.
+
+#### Returns
+*(boolean)*: Returns `true` if `value` is a weak map, else `false`.
+
+#### Example
+```js
+isWeakSet(new WeakSet())
+// => true
+
+isWeakSet(new Set())
+// => false
+
+```
+---
+
+
+
+
+
+
+
+ [1]: #isweakset "Jump back to the TOC."
diff --git a/docs/docdown/deps/matcher.md b/docs/docdown/deps/matcher.md
deleted file mode 100644
index 81cfcc6..0000000
--- a/docs/docdown/deps/matcher.md
+++ /dev/null
@@ -1,94 +0,0 @@
-# matcher.js API documentation
-
-
-
-
-
-## `matcher`
-* `matcher.make`
-* `matcher.matcher`
-* `matcher.toarr`
-
-
-
-
-
-
-
-
-
-## `matcher`
-
-
-
-# matcher.make(pattern, shouldNegate, alphaOmega)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/matcher.js#L60 "View in source") [Ⓣ][1]
-
-
-
-#### Since
-3.0.0
-
-#### Arguments
-1. `pattern` *(Function|RegExp|string|string[])*: a matchable pattern
-2. `shouldNegate` *(|boolean)*: turn into a negated regex
-3. `alphaOmega` *(|boolean)*: should have regex start at the beginning and the end
-
-#### Returns
-*(*)*: matchable
-
-#### Example
-```js
-matcher.make('*')
- //=> RegExp('.*', 'i')
-```
----
-
-
-
-
-
-# matcher.matcher(inputs, patterns, shouldNegate, alphaOmega)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/matcher.js#L132 "View in source") [Ⓣ][1]
-
-
-
-#### Since
-3.0.0
-
-#### Arguments
-1. `inputs` *(string|string[])*: input to use patterns as predicates on
-2. `patterns` *(Function|RegExp|string|string[])*: predicates to match with, transformed to Matcher
-3. `shouldNegate` *(|boolean)*: should negate, passed to matcher.make
-4. `alphaOmega` *(|boolean)*: should enforce regex @beginning and end, passed to .matcher
-
-#### Returns
-*(*)*:
-
-#### Example
-```js
-matcher(['foo', 'bar', 'moo'], ['*oo', '!foo']);
- //=> ['moo']
-
- matcher(['foo', 'bar', 'moo'], ['!*oo']);
-```
----
-
-
-
-
-
-# matcher.toarr
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/matcher.js#L6 "View in source") [Ⓣ][1]
-
-
-
----
-
-
-
-
-
-
-
- [1]: #matcher "Jump back to the TOC."
diff --git a/docs/docdown/deps/matcher/any-key-val.md b/docs/docdown/deps/matcher/any-key-val.md
index 5265b1b..063f82b 100644
--- a/docs/docdown/deps/matcher/any-key-val.md
+++ b/docs/docdown/deps/matcher/any-key-val.md
@@ -5,7 +5,7 @@
## `exports`
-* `exports`
+* `exports`
@@ -21,19 +21,22 @@
🌊 Types: matcher.d
-# exports(keys=undefined, vals=undefined)
+exports(keys=undefined, vals=undefined)
+
+
[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/matcher/any-key-val.js#L27 "View in source") [Ⓣ][1]
(Function): the original simple to-test matcher for traversable,
will be merged into, or simplified as simplified into matcher
-### @todos
+#### @todos
- [ ] should use matcher,
- [ ] should inprove the callback data...
-#### Since
+
+#### @Since
2.0.0
#### Arguments
diff --git a/docs/docdown/deps/matcher/escape-string-regex.md b/docs/docdown/deps/matcher/escape-string-regex.md
index 16fe1d0..e54990e 100644
--- a/docs/docdown/deps/matcher/escape-string-regex.md
+++ b/docs/docdown/deps/matcher/escape-string-regex.md
@@ -4,8 +4,8 @@
-## `matcher.prototype`
-* `matcher.prototype.escapeStringRegExp`
+## `matcher`
+* `matcher.escapeStringRegExp`
@@ -15,21 +15,29 @@
-## `matcher.prototype`
+## `matcher`
-# matcher.prototype.exports(str=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/matcher/escape-string-regex.js#L19 "View in source") [Ⓣ][1]
+matcher.exports(str=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/matcher/escape-string-regex.js#L21 "View in source") [Ⓣ][1]
Function
-### @notes
+#### @see
+
+* escape-string-regexp
+* fp/replace
+
+#### @notes
* also as const escapeStringRegexp = require('escape-string-regexp');
-#### Since
+
+#### @Since
3.0.0
#### Arguments
@@ -53,4 +61,4 @@ new RegExp(escaped)
- [1]: #matcher.prototype "Jump back to the TOC."
+ [1]: #matcher "Jump back to the TOC."
diff --git a/docs/docdown/deps/matcher/matcher.md b/docs/docdown/deps/matcher/matcher.md
index 28e92d5..8782666 100644
--- a/docs/docdown/deps/matcher/matcher.md
+++ b/docs/docdown/deps/matcher/matcher.md
@@ -4,17 +4,17 @@
-## `matcher.prototype`
-* `matcher.prototype.make`
-* `matcher.prototype.match`
-* `matcher.prototype.matcher`
+## `matcher`
+* `matcher.make`
+* `matcher.match`
+* `matcher.matcher`
## `test`
-* `test`
+* `test`
@@ -24,16 +24,19 @@
-## `matcher.prototype`
+## `matcher`
-# matcher.prototype.make(pattern=undefined, shouldNegate=undefined, alphaOmega=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/matcher/matcher.js#L64 "View in source") [Ⓣ][1]
+matcher.make(pattern=undefined, shouldNegate=undefined, alphaOmega=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/matcher/matcher.js#L65 "View in source") [Ⓣ][1]
(Function): turn any string[], function[], or RegExp[] into a matcher
-#### Since
+
+#### @Since
3.0.0
#### Arguments
@@ -91,12 +94,20 @@ matcher.make(noName, true, true)
-# matcher.prototype.matcher(inputs=undefined, patterns=undefined, shouldNegate=undefined, alphaOmega=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/matcher/matcher.js#L140 "View in source") [Ⓣ][1]
+matcher.matcher(inputs=undefined, patterns=undefined, shouldNegate=undefined, alphaOmega=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/matcher/matcher.js#L141 "View in source") [Ⓣ][1]
(Function): same as .make but also accepts inputs, and returns an array
-#### Since
+
+#### @see
+
+* Matcher.make
+* compose/Observe
+
+#### @Since
3.0.0
#### Arguments
@@ -151,13 +162,19 @@ matcher({ test: x => x === 'kinga' }, 'nope')
🔬 Tests: matcher
-# matcher.prototype.matcher
+matcher.matcher
+
+
[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/matcher/matcher.js#L9 "View in source") [Ⓣ][1]
unknown
-### @symb
+#### @see
+
+* https://github.com/sindresorhus/matcher/blob/master/index.js
+
+#### @symb
🎯
---
@@ -172,13 +189,15 @@ unknown
-# test
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/matcher/matcher.js#L166 "View in source") [Ⓣ][1]
+test
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/matcher/matcher.js#L167 "View in source") [Ⓣ][1]
unknown
-### @todos
+#### @todos
- [ ] replace to-test
@@ -190,4 +209,4 @@ unknown
- [1]: #matcher.prototype "Jump back to the TOC."
+ [1]: #matcher "Jump back to the TOC."
diff --git a/docs/docdown/deps/matcher/to-regexp.md b/docs/docdown/deps/matcher/to-regexp.md
index d94b674..6fde861 100644
--- a/docs/docdown/deps/matcher/to-regexp.md
+++ b/docs/docdown/deps/matcher/to-regexp.md
@@ -4,8 +4,8 @@
-## `matcher.prototype`
-* `matcher.prototype.toRegExp`
+## `matcher`
+* `matcher.toRegExp`
@@ -15,17 +15,19 @@
-## `matcher.prototype`
+## `matcher`
-# matcher.prototype.exports(str=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/matcher/to-regexp.js#L21 "View in source") [Ⓣ][1]
+matcher.exports(str=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/matcher/to-regexp.js#L23 "View in source") [Ⓣ][1]
Function
-### @extends
+#### @extends
@@ -51,4 +53,4 @@ toRegExp('*')
- [1]: #matcher.prototype "Jump back to the TOC."
+ [1]: #matcher "Jump back to the TOC."
diff --git a/docs/docdown/deps/matcher/to-test.md b/docs/docdown/deps/matcher/to-test.md
index 254115a..92a7f41 100644
--- a/docs/docdown/deps/matcher/to-test.md
+++ b/docs/docdown/deps/matcher/to-test.md
@@ -4,8 +4,8 @@
-## `exports`
-* `exports`
+## `toTest`
+* `toTest`
@@ -15,21 +15,24 @@
-## `exports`
+## `toTest`
-# exports(matchable=undefined, [arg1=undefined], [arg2=undefined])
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/matcher/to-test.js#L41 "View in source") [Ⓣ][1]
+toTest(matchable=undefined, [arg1=undefined], [arg2=undefined])
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/matcher/to-test.js#L47 "View in source") [Ⓣ][1]
(Function): like matcher, but .isMatch
-### @notes
+#### @notes
* as else-if for easier ternary uglification
-#### Since
+
+#### @Since
3.0.0
#### Arguments
@@ -73,4 +76,4 @@ matcher({ test: x => x === 'kinga' }, 'nope')
- [1]: #exports "Jump back to the TOC."
+ [1]: #totest "Jump back to the TOC."
diff --git a/docs/docdown/deps/meta/ignored.md b/docs/docdown/deps/meta/ignored.md
new file mode 100644
index 0000000..ab06c0b
--- /dev/null
+++ b/docs/docdown/deps/meta/ignored.md
@@ -0,0 +1,11 @@
+# ignored.js API documentation
+
+
+
+
+
+
+
+
+
+ [1]: # "Jump back to the TOC."
diff --git a/docs/docdown/deps/meta/keymap.md b/docs/docdown/deps/meta/keymap.md
index 45df404..3af8644 100644
--- a/docs/docdown/deps/meta/keymap.md
+++ b/docs/docdown/deps/meta/keymap.md
@@ -5,7 +5,7 @@
## `access`
-* `access`
+* `access`
@@ -19,7 +19,9 @@
-# access([index=Number], [obj=undefined], [val=undefined])
+access([index=Number], [obj=undefined], [val=undefined])
+
+
[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/meta/keymap.js#L34 "View in source") [Ⓣ][1]
Function
diff --git a/docs/docdown/deps/meta/meta.md b/docs/docdown/deps/meta/meta.md
index 2204d24..529ff70 100644
--- a/docs/docdown/deps/meta/meta.md
+++ b/docs/docdown/deps/meta/meta.md
@@ -5,36 +5,36 @@
## `get`
-* `get`
+* `get`
## `getMeta`
-* `getMeta`
+* `getMeta`
## `has`
-* `has`
+* `has`
## `meta`
-* ``
-* `meta`
+* ``
+* `meta`
## `set`
-* `set`
+* `set`
@@ -48,12 +48,15 @@
-# get(key=undefined, [prop=undefined])
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/meta/meta.js#L73 "View in source") [Ⓣ][1]
+get(key=undefined, [prop=undefined])
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/meta/meta.js#L75 "View in source") [Ⓣ][1]
Function
-#### Since
+
+#### @Since
4.0.0
#### Arguments
@@ -75,12 +78,15 @@ Function
-
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/meta/meta.js#L26 "View in source") [Ⓣ][1]
+
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/meta/meta.js#L28 "View in source") [Ⓣ][1]
Function
-#### Since
+
+#### @Since
4.0.0
#### Arguments
@@ -101,12 +107,15 @@ Function
-# has(key=undefined, [prop=undefined])
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/meta/meta.js#L63 "View in source") [Ⓣ][1]
+has(key=undefined, [prop=undefined])
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/meta/meta.js#L65 "View in source") [Ⓣ][1]
Function
-#### Since
+
+#### @Since
4.0.0
#### Arguments
@@ -128,8 +137,10 @@ Function
-
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/meta/meta.js#L37 "View in source") [Ⓣ][1]
+
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/meta/meta.js#L39 "View in source") [Ⓣ][1]
unknown
@@ -139,12 +150,15 @@ unknown
-
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/meta/meta.js#L110 "View in source") [Ⓣ][1]
+
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/meta/meta.js#L112 "View in source") [Ⓣ][1]
(Function): a single easily minifiable function, dynamically setting & getting depending on arguments to avoid nested property accessing only instantiating when values are **addded**
-#### Since
+
+#### @Since
4.0.0
#### Arguments
@@ -167,12 +181,15 @@ unknown
-# set(key=undefined, [prop=undefined], [value=undefined])
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/meta/meta.js#L82 "View in source") [Ⓣ][1]
+set(key=undefined, [prop=undefined], [value=undefined])
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/meta/meta.js#L84 "View in source") [Ⓣ][1]
Function
-#### Since
+
+#### @Since
4.0.0
#### Arguments
diff --git a/docs/docdown/deps/native/arraySlice.md b/docs/docdown/deps/native/arraySlice.md
new file mode 100644
index 0000000..6d389b9
--- /dev/null
+++ b/docs/docdown/deps/native/arraySlice.md
@@ -0,0 +1,11 @@
+# arraySlice.js API documentation
+
+
+
+
+
+
+
+
+
+ [1]: # "Jump back to the TOC."
diff --git a/docs/docdown/deps/array/insert-at-index.md b/docs/docdown/deps/native/functionToString.md
similarity index 77%
rename from docs/docdown/deps/array/insert-at-index.md
rename to docs/docdown/deps/native/functionToString.md
index 3b28de7..2a49ef7 100644
--- a/docs/docdown/deps/array/insert-at-index.md
+++ b/docs/docdown/deps/native/functionToString.md
@@ -1,4 +1,4 @@
-# insert-at-index.js API documentation
+# functionToString.js API documentation
diff --git a/docs/docdown/deps/native/hasOwnProperty.md b/docs/docdown/deps/native/hasOwnProperty.md
new file mode 100644
index 0000000..54559bc
--- /dev/null
+++ b/docs/docdown/deps/native/hasOwnProperty.md
@@ -0,0 +1,11 @@
+# hasOwnProperty.js API documentation
+
+
+
+
+
+
+
+
+
+ [1]: # "Jump back to the TOC."
diff --git a/docs/docdown/deps/native/objectToString.md b/docs/docdown/deps/native/objectToString.md
new file mode 100644
index 0000000..b6b5835
--- /dev/null
+++ b/docs/docdown/deps/native/objectToString.md
@@ -0,0 +1,11 @@
+# objectToString.js API documentation
+
+
+
+
+
+
+
+
+
+ [1]: # "Jump back to the TOC."
diff --git a/docs/docdown/deps/native/propertyIsEnumerable.md b/docs/docdown/deps/native/propertyIsEnumerable.md
new file mode 100644
index 0000000..0e0c416
--- /dev/null
+++ b/docs/docdown/deps/native/propertyIsEnumerable.md
@@ -0,0 +1,11 @@
+# propertyIsEnumerable.js API documentation
+
+
+
+
+
+
+
+
+
+ [1]: # "Jump back to the TOC."
diff --git a/docs/docdown/deps/primitives/undefined.md b/docs/docdown/deps/primitives/undefined.md
deleted file mode 100644
index a9f445e..0000000
--- a/docs/docdown/deps/primitives/undefined.md
+++ /dev/null
@@ -1,11 +0,0 @@
-# undefined.js API documentation
-
-
-
-
-
-
-
-
-
- [1]: # "Jump back to the TOC."
diff --git a/docs/docdown/deps/reduce/clean.md b/docs/docdown/deps/reduce/clean.md
index 745a920..8648f75 100644
--- a/docs/docdown/deps/reduce/clean.md
+++ b/docs/docdown/deps/reduce/clean.md
@@ -4,8 +4,8 @@
-## `reduce.prototype`
-* `reduce.prototype.exports`
+## `reduce`
+* `reduce.exports`
@@ -15,19 +15,30 @@
-## `reduce.prototype`
+## `reduce`
-# reduce.prototype.exports(obj=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/reduce/clean.js#L39 "View in source") [Ⓣ][1]
+reduce.exports(obj=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/reduce/clean.js#L47 "View in source") [Ⓣ][1]
(Function): goes through the maps, and the map values, reduces them to array then to an object using the reduced values
-### @see
+#### @see
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
+* reduce
+* isObjWithKeys
+* isNotEmptyArray
+* isReal
+* http://underscorejs.org/#reduce
+
+#### @todos
+
+- [ ] seems to be overkill with reducing mapping just copy & ignore or delete?
+
#### Arguments
1. `obj=undefined` *(Object): object to clean, usually .entries()*
@@ -57,4 +68,4 @@ clean(map.entries())
- [1]: #reduce.prototype "Jump back to the TOC."
+ [1]: #reduce "Jump back to the TOC."
diff --git a/docs/docdown/deps/reduce/entries.md b/docs/docdown/deps/reduce/entries.md
index d0d4a46..264b5cb 100644
--- a/docs/docdown/deps/reduce/entries.md
+++ b/docs/docdown/deps/reduce/entries.md
@@ -5,7 +5,7 @@
## `exports`
-* `exports`
+* `exports`
@@ -19,20 +19,29 @@
-# exports(reduced=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/reduce/entries.js#L63 "View in source") [Ⓣ][1]
+exports(reduced=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/reduce/entries.js#L66 "View in source") [Ⓣ][1]
(Function): recursively reduce maps and objects that include reducable data
-### @see
+#### @see
-* fluents/chain able/blob/master/src/chained map.js
+* https://www.airpair.com/javascript/javascript-array-reduce
+* ChainedMap
-### @sig
+#### @notes
+
+* could curry, but this is super hot function
+
+
+#### @sig
reduced => object => isMap(object) -> reduced; merge(object, reduced)
-#### Since
+
+#### @Since
4.0.0
#### Arguments
diff --git a/docs/docdown/deps/reduce/objects.md b/docs/docdown/deps/reduce/objects.md
deleted file mode 100644
index 6313720..0000000
--- a/docs/docdown/deps/reduce/objects.md
+++ /dev/null
@@ -1,11 +0,0 @@
-# objects.js API documentation
-
-
-
-
-
-
-
-
-
- [1]: # "Jump back to the TOC."
diff --git a/docs/docdown/deps/reduce/reduce.md b/docs/docdown/deps/reduce/reduce.md
index c73a1de..7c87af3 100644
--- a/docs/docdown/deps/reduce/reduce.md
+++ b/docs/docdown/deps/reduce/reduce.md
@@ -5,7 +5,7 @@
## `exports`
-* `exports`
+* `exports`
@@ -19,12 +19,19 @@
-# exports(map=undefined)
+exports(map=undefined)
+
+
[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/reduce/reduce.js#L26 "View in source") [Ⓣ][1]
(Function): Map -> Object
-#### Since
+
+#### @see
+
+* ArrayFrom
+
+#### @Since
4.0.0
#### Arguments
diff --git a/docs/docdown/deps/reduce/toObj.md b/docs/docdown/deps/reduce/toObj.md
new file mode 100644
index 0000000..45ad4a2
--- /dev/null
+++ b/docs/docdown/deps/reduce/toObj.md
@@ -0,0 +1,11 @@
+# toObj.js API documentation
+
+
+
+
+
+
+
+
+
+ [1]: # "Jump back to the TOC."
diff --git a/docs/docdown/deps/string/camelCase.md b/docs/docdown/deps/string/camelCase.md
new file mode 100644
index 0000000..7ed1027
--- /dev/null
+++ b/docs/docdown/deps/string/camelCase.md
@@ -0,0 +1,72 @@
+# camelCase.js API documentation
+
+
+
+
+
+## `exports`
+* `exports`
+
+
+
+
+
+
+
+
+
+## `exports`
+
+
+
+* 🌊 Types: deps.d
+* 🌊 Types: deps.encase.d
+* 🌊 Types: deps.reduce.d
+
+🔬 Tests: camelCase
+
+exports(str=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/string/camelCase.js#L26 "View in source") [Ⓣ][1]
+
+(Function): camelCase
+
+
+#### @see
+
+* https://stackoverflow.com/questions/1533131/what-useful-bitwise-operator-code-tricks-should-a-developer-know-about
+
+#### @todos
+
+- [ ] s.charAt(0).toLowerCase() + string.slice(1)
+
+
+#### @symb
+
+🐫
+
+#### @Since
+0.2.0
+
+#### Arguments
+1. `str=undefined` *(string)*: string to turn into camelCase
+
+#### Returns
+*(string)*: camelCased string
+
+#### Example
+```js
+camelCase('snake_case')
+//=> 'snakeCase'
+
+```
+---
+
+
+
+
+
+
+
+ [1]: #exports "Jump back to the TOC."
diff --git a/docs/docdown/deps/string/class-names.md b/docs/docdown/deps/string/class-names.md
index 5823b4b..a312ea6 100644
--- a/docs/docdown/deps/string/class-names.md
+++ b/docs/docdown/deps/string/class-names.md
@@ -5,7 +5,7 @@
## `exports`
-* `exports`
+* `exports`
@@ -19,7 +19,9 @@
-# exports(_c=undefined)
+exports(_c=undefined)
+
+
[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/string/class-names.js#L6 "View in source") [Ⓣ][1]
Function
diff --git a/docs/docdown/deps/string/firstToUpperCase.md b/docs/docdown/deps/string/firstToUpperCase.md
new file mode 100644
index 0000000..3ada6a3
--- /dev/null
+++ b/docs/docdown/deps/string/firstToUpperCase.md
@@ -0,0 +1,11 @@
+# firstToUpperCase.js API documentation
+
+
+
+
+
+
+
+
+
+ [1]: # "Jump back to the TOC."
diff --git a/docs/docdown/deps/to-arr.md b/docs/docdown/deps/to-arr.md
index 9e5395c..b984730 100644
--- a/docs/docdown/deps/to-arr.md
+++ b/docs/docdown/deps/to-arr.md
@@ -5,14 +5,14 @@
## `exports`
-* `exports`
+* `exports`
## `to-arr`
-* ``
+* ``
@@ -26,18 +26,23 @@
-🌊 Types: deps.d
+* 🌊 Types: deps.d
+* 🌊 Types: deps.encase.d
+* 🌊 Types: deps.reduce.d
-# exports(ar=undefined)
+exports(ar=undefined)
+
+
[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/to-arr.js#L48 "View in source") [Ⓣ][1]
(Function): anything into an array
-### @sig
+#### @sig
* => Array
-#### Since
+
+#### @Since
0.0.1
#### Arguments
@@ -87,7 +92,9 @@ toarr('').concat(toarr(false)).concat(toarr(null))
-
+
+
+
[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/to-arr.js#L58 "View in source") [Ⓣ][1]
unknown
diff --git a/docs/docdown/deps/to-regexp.md b/docs/docdown/deps/to-regexp.md
deleted file mode 100644
index 42b7125..0000000
--- a/docs/docdown/deps/to-regexp.md
+++ /dev/null
@@ -1,11 +0,0 @@
-# to-regexp.js API documentation
-
-
-
-
-
-
-
-
-
- [1]: # "Jump back to the TOC."
diff --git a/docs/docdown/deps/to-test.md b/docs/docdown/deps/to-test.md
deleted file mode 100644
index 051f415..0000000
--- a/docs/docdown/deps/to-test.md
+++ /dev/null
@@ -1,70 +0,0 @@
-# to-test.js API documentation
-
-
-
-
-
-## `exports`
-* `exports`
-
-
-
-
-
-
-
-
-
-## `exports`
-
-
-
-# exports(matchable, [arg1=undefined], [arg2=undefined])
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/to-test.js#L41 "View in source") [Ⓣ][1]
-
-
-
-#### Since
-3.0.0
-
-#### Arguments
-1. `matchable` *(Matchable)*: any matchable
-2. `[arg1=undefined]` *(any)*: arg to match with
-3. `[arg2=undefined]` *(any)*: optional second arg to pass into tester
-
-#### Returns
-*(boolean)*: is a match, passes the test
-
-#### Example
-```js
-matcher('kinga', 'kinga')
- //=> true
- matcher('k*nga', 'kinga')
- //=> true
- matcher('kinga', 'nope')
- //=> false
-
- matcher(new RegExp(/kinga/), 'kinga')
- //=> true
- matcher(new RegExp(/kinga/), 'nope')
- //=> false
-
- matcher(x => x === 'kinga', 'kinga')
- //=> true
- matcher(x => x === 'kinga', 'nope')
- //=> false
-
- matcher({test: x => x === 'kinga'}, 'kinga')
- //=> true
- matcher({test: x => x === 'kinga'}, 'nope')
- //=> false
-```
----
-
-
-
-
-
-
-
- [1]: #exports "Jump back to the TOC."
diff --git a/docs/docdown/deps/to/array.md b/docs/docdown/deps/to/array.md
new file mode 100644
index 0000000..09c2c71
--- /dev/null
+++ b/docs/docdown/deps/to/array.md
@@ -0,0 +1,11 @@
+# array.js API documentation
+
+
+
+
+
+
+
+
+
+ [1]: # "Jump back to the TOC."
diff --git a/docs/docdown/deps/to/boolean.md b/docs/docdown/deps/to/boolean.md
new file mode 100644
index 0000000..25f967e
--- /dev/null
+++ b/docs/docdown/deps/to/boolean.md
@@ -0,0 +1,11 @@
+# boolean.js API documentation
+
+
+
+
+
+
+
+
+
+ [1]: # "Jump back to the TOC."
diff --git a/docs/docdown/deps/to/coerce.md b/docs/docdown/deps/to/coerce.md
new file mode 100644
index 0000000..487cdaf
--- /dev/null
+++ b/docs/docdown/deps/to/coerce.md
@@ -0,0 +1,11 @@
+# coerce.js API documentation
+
+
+
+
+
+
+
+
+
+ [1]: # "Jump back to the TOC."
diff --git a/docs/docdown/deps/to/index.md b/docs/docdown/deps/to/index.md
new file mode 100644
index 0000000..5ac127d
--- /dev/null
+++ b/docs/docdown/deps/to/index.md
@@ -0,0 +1,11 @@
+# index.js API documentation
+
+
+
+
+
+
+
+
+
+ [1]: # "Jump back to the TOC."
diff --git a/docs/docdown/deps/to/integer.md b/docs/docdown/deps/to/integer.md
new file mode 100644
index 0000000..b34f07f
--- /dev/null
+++ b/docs/docdown/deps/to/integer.md
@@ -0,0 +1,11 @@
+# integer.js API documentation
+
+
+
+
+
+
+
+
+
+ [1]: # "Jump back to the TOC."
diff --git a/docs/docdown/deps/primitives/null.md b/docs/docdown/deps/to/map.md
similarity index 82%
rename from docs/docdown/deps/primitives/null.md
rename to docs/docdown/deps/to/map.md
index d39738f..2bf4eff 100644
--- a/docs/docdown/deps/primitives/null.md
+++ b/docs/docdown/deps/to/map.md
@@ -1,4 +1,4 @@
-# null.js API documentation
+# map.js API documentation
diff --git a/docs/docdown/deps/to/number.md b/docs/docdown/deps/to/number.md
new file mode 100644
index 0000000..abdca98
--- /dev/null
+++ b/docs/docdown/deps/to/number.md
@@ -0,0 +1,11 @@
+# number.js API documentation
+
+
+
+
+
+
+
+
+
+ [1]: # "Jump back to the TOC."
diff --git a/docs/docdown/deps/to/object.md b/docs/docdown/deps/to/object.md
new file mode 100644
index 0000000..daec193
--- /dev/null
+++ b/docs/docdown/deps/to/object.md
@@ -0,0 +1,11 @@
+# object.js API documentation
+
+
+
+
+
+
+
+
+
+ [1]: # "Jump back to the TOC."
diff --git a/docs/docdown/deps/to/set.md b/docs/docdown/deps/to/set.md
new file mode 100644
index 0000000..e2a6d32
--- /dev/null
+++ b/docs/docdown/deps/to/set.md
@@ -0,0 +1,11 @@
+# set.js API documentation
+
+
+
+
+
+
+
+
+
+ [1]: # "Jump back to the TOC."
diff --git a/docs/docdown/deps/to/setToArray.md b/docs/docdown/deps/to/setToArray.md
new file mode 100644
index 0000000..e2d82b7
--- /dev/null
+++ b/docs/docdown/deps/to/setToArray.md
@@ -0,0 +1,11 @@
+# setToArray.js API documentation
+
+
+
+
+
+
+
+
+
+ [1]: # "Jump back to the TOC."
diff --git a/docs/docdown/deps/to/string.md b/docs/docdown/deps/to/string.md
new file mode 100644
index 0000000..b37889c
--- /dev/null
+++ b/docs/docdown/deps/to/string.md
@@ -0,0 +1,11 @@
+# string.js API documentation
+
+
+
+
+
+
+
+
+
+ [1]: # "Jump back to the TOC."
diff --git a/docs/docdown/deps/to/to.md b/docs/docdown/deps/to/to.md
new file mode 100644
index 0000000..d5f2edb
--- /dev/null
+++ b/docs/docdown/deps/to/to.md
@@ -0,0 +1,37 @@
+# to.js API documentation
+
+
+
+
+
+## `to.exports`
+* `to.exports`
+
+
+
+
+
+
+
+
+
+## `to.exports`
+
+
+
+to.exports
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/to/to.js#L13 "View in source") [Ⓣ][1]
+
+Object
+
+---
+
+
+
+
+
+
+
+ [1]: #to.exports "Jump back to the TOC."
diff --git a/docs/docdown/deps/traverse.md b/docs/docdown/deps/traverse.md
index 3e444cf..34118f3 100644
--- a/docs/docdown/deps/traverse.md
+++ b/docs/docdown/deps/traverse.md
@@ -4,173 +4,36 @@
-## `Traverse.prototype`
-* `Traverse.prototype.`
-* `Traverse.prototype.`
-* `Traverse.prototype.clone`
-* `Traverse.prototype.forEach`
-* `Traverse.prototype.get`
-* `Traverse.prototype.has`
-* `Traverse.prototype.nodes`
-* `Traverse.prototype.paths`
-* `Traverse.prototype.reduce`
-* `Traverse.prototype.set`
+## `Traverse`
+* `Traverse.checkIteratable`
+* `Traverse.clone`
+* `Traverse.forEach`
+* `Traverse.iterate`
+* `Traverse.remove`
+* `Traverse.skip`
+* `Traverse.stop`
+* `Traverse.update`
-## `after`
-* `after`
+## `clone`
+* `clone`
-## `before`
-* `before`
-
-
-
-
-
-## `block`
-* `block`
-
-
-
-
-
-## `circular`
-* `circular`
-
-
-
-
-
-## `delete`
-* `delete`
-
-
-
-
-
-## `forEach`
-* `forEach`
-
-
-
-
-
-## `isRoot`
-* `isRoot`
-
-
-
-
-
-## `key`
-* `key`
-
-
-
-
-
-## `level`
-* `level`
-
-
-
-
-
-## `node`
-* `node`
-
-
-
-
-
-## `node_`
-* `node_`
-
-
-
-
-
-## `parent`
-* `parent`
-
-
-
-
-
-## `path`
-* `path`
-
-
-
-
-
-## `post`
-* `post`
-
-
-
-
-
-## `pre`
-* `pre`
-
-
-
-
-
-## `remove`
-* `remove`
-
-
-
-
-
-## `return`
-* `return`
-
-
-
-
-
-## `state`
-* `state`
-
-
-
-
-
-## `stop`
-* `stop`
+## `copy`
+* `copy`
## `traverse`
-* ``
-* ``
-* `traverse`
-
-
-
-
-
-## `update`
-* `update`
-
-
-
-
-
-## `updateState`
-* `updateState`
+* ``
@@ -180,56 +43,46 @@
-## `Traverse.prototype`
+## `Traverse`
-* 🌊 Types: TraverseChain.d
-* 🌊 Types: traverse.d
-
-* 🔬 Tests: circular
-* 🔬 Tests: date
-* 🔬 Tests: equal
-* 🔬 Tests: error
-* 🔬 Tests: has
-* 🔬 Tests: index
-* 🔬 Tests: instance
-* 🔬 Tests: interface
-* 🔬 Tests: json
-* 🔬 Tests: keys
-* 🔬 Tests: leaves
-* 🔬 Tests: negative
-* 🔬 Tests: obj
-* 🔬 Tests: set-map
-* 🔬 Tests: siblings
-* 🔬 Tests: stop
-* 🔬 Tests: stringify
-* 🔬 Tests: subexpr
-* 🔬 Tests: superDeep
-
-# Traverse.prototype.Traverse(obj=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/traverse.js#L91 "View in source") [Ⓣ][1]
+Traverse.checkIteratable(node=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/traverse.js#L337 "View in source") [Ⓣ][1]
-Function
+(Function): checks whether a node is iteratable
-### @todos
+#### @todos
-- [ ] : symbol, map, set
-
-
-### @classProps
-
-* {value} the data passed in as an argument to traverse on
+- [ ] move into the wrapper? if perf allows?
#### Arguments
-1. `obj=undefined` *(Traversable)*: any traversable value
+1. `node=undefined` *(*)*: value to check
+
+#### Returns
+*(void)*:
#### Example
```js
-traverse({})
-//=> Traverser
-
+.checkIteratable({eh: true})
+ //=> this.isLeaf = false
+ //=> this.isCircular = false
+ //=> this.isIteratable = true
+
+ .checkIteratable({} || [])
+ //=> this.isLeaf = true
+ //=> this.isCircular = false
+ //=> this.isIteratable = false
+
+ var circular = {}
+ circular.circular = circular
+ .checkIteratable(circular)
+ //=> this.isLeaf = false
+ //=> this.isCircular = true
+ //=> this.isIteratable = true
```
---
@@ -237,54 +90,43 @@ traverse({})
-# Traverse.prototype.map(cb=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/traverse.js#L199 "View in source") [Ⓣ][1]
+Traverse.clone(arg=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/traverse.js#L833 "View in source") [Ⓣ][1]
-(Function): Execute fn for each node in the object and return a new object with the results of the walk. To update nodes in the result use this.update(value).
+(Function): clone any value
-#### Arguments
-1. `cb=undefined` *(Function)*: fn for each node in the object
-#### Returns
-*(any)*:
+#### @see
-#### Example
-```js
-var { traverse } = require('chain-able')
+* dopemerge
-var obj = { a: 1, b: 2, c: [3, 4] }
-obj.c.push(obj)
+#### @extends
-var scrubbed = traverse(obj).map(function(x) {
- if (this.circular) this.remove()
-})
-console.dir(scrubbed)
-//=> { a: 1, b: 2, c: [ 3, 4 ] }
-
-```
----
+* undefined
+* undefined
-
-
-# Traverse.prototype.clone()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/traverse.js#L319 "View in source") [Ⓣ][1]
+#### @Since
+4.0.0
-(Function): Create a deep clone of the object.
+#### Arguments
+1. `arg=undefined` *(*)*: argument to clone
#### Returns
-*(any)*:
+*(*)*: cloned value
#### Example
```js
-const { traverse, eq } = require('chain-able')
+var obj = { eh: true }
+clone(obj) === obj //=> false
-const obj = { eh: true, canada: [1] }
-const cloned = traverse(obj).clone()
-cloned.eh = false
-eq(cloned, obj)
-//=> false
+var obj = { eh: true }
+var obj2 = clone(obj)
+obj.eh = false
+console.log(obj2.eh) //=> true
```
---
@@ -293,28 +135,29 @@ eq(cloned, obj)
-# Traverse.prototype.forEach(callback=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/traverse.js#L226 "View in source") [Ⓣ][1]
+Traverse.forEach(cb=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/traverse.js#L250 "View in source") [Ⓣ][1]
+
+(Function): this is the main usage of Traverse
+
-(Function): Execute fn for each node in the object but unlike .map(), when this.update() is called it updates the object in-place. executes a provided function once for each traversed element.
+#### @Since
+3.0.0
#### Arguments
-1. `callback=undefined` *(Function)*: provided callback function
+1. `cb=undefined` *(Function)*: callback for each iteration
#### Returns
-*(any)*: this.value
+*(*)*: mapped result or original value, depends how it is used
#### Example
```js
-var { traverse } = require('chain-able')
-
-var obj = [5, 6, -3, [7, 8, -2, 1], { f: 10, g: -13 }]
-traverse(obj).forEach(function(x) {
- if (x < 0) this.update(x + 128)
-})
-
-console.dir(obj)
-//=> [ 5, 6, 125, [ 7, 8, 126, 1 ], { f: 10, g: 115 } ]
+traverse([1, 2, 3]).forEach((key, value) => console.log({ [key]: value }))
+//=> {'0': 1}
+//=> {'1': 2}
+//=> {'2': 3}
```
---
@@ -323,123 +166,67 @@ console.dir(obj)
-# Traverse.prototype.get(ps=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/traverse.js#L105 "View in source") [Ⓣ][1]
+Traverse.iterate(on=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/traverse.js#L518 "View in source") [Ⓣ][1]
-(Function): Get the element at the array path.
+Function
-### @todos
+#### @todos
-- [ ] hasOwnProperty
+- [ ] handler for Set & Map so they can be skipped or traversed, for example when cloning...
+- [ ] add hook to add custom checking if isIteratable
+- [ ] deal with .isRoot if needed
+- [ ] examples with clone and stop
-#### Arguments
-1. `ps=undefined` *(string[])*: paths
-
-#### Returns
-*(any)*: value at dot-prop
----
-
-
-
-
-
-# Traverse.prototype.has(pathsArray=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/traverse.js#L144 "View in source") [Ⓣ][1]
-
-(Function): Return whether the element at the array path exists.
+#### @sig
+on(key: null | Primitive, val: any, instance: Traverse): any
#### Arguments
-1. `pathsArray=undefined` *(string[])*: paths
+1. `on=undefined` *(Function)*: callback fn for each iteration
#### Returns
-*(boolean)*: has element at path
+*(*)*: this.node
#### Example
```js
-traverse({ eh: true }).has(['eh'])
-//=> true
+iterate([])
+//=> []
+//=> on(null, [])
```
#### Example
```js
-traverse({ eh: true }).has(['canada'])
-//=> false
+iterate([1])
+//=> [1]
+//=> on(null, [1])
+//=> on('1', 1)
```
#### Example
```js
-traverse([0]).has([2])
-//=> false
+//primitive - same for any number, string, symbol, null, undefined
+iterate(Symbol('eh'))
+//=> Symbol('eh')
+//=> on(Symbol('eh'))
```
----
-
-
-
-
-
-# Traverse.prototype.nodes()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/traverse.js#L294 "View in source") [Ⓣ][1]
-
-(Function): Return an Array of every node in the object.
-
-#### Returns
-*(*)*:
-
----
-
-
-
-
-
-🔬 Tests: keys
-
-# Traverse.prototype.paths()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/traverse.js#L281 "View in source") [Ⓣ][1]
-
-(Function): Return an Array of every possible non-cyclic path in the object. Paths are Arrays of string keys.
-
-#### Returns
-*(*)*:
-
----
-
-
-
-
-
-# Traverse.prototype.reduce(cb=undefined, init=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/traverse.js#L264 "View in source") [Ⓣ][1]
-
-(Function): applies a function against an accumulator and each element in the array *(from left to right)* to reduce it to a single value. calls cb for each loop that is .notRoot defaults initial value to `this.value`
-
-#### Arguments
-1. `cb=undefined` *(Function)*: callback forEach
-2. `init=undefined` *(Array|Object|any)*: initial value
-
-#### Returns
-*(*)*:
-
#### Example
```js
-var { traverse } = require('chain-able')
+var deeper = { eh: 'canada', arr: [{ moose: true }, 0] }
+iterate(deeper)
+//=> deeper // returns
+//=> on(null, deeper, this) // root
-var obj = {
- a: [1, 2, 3],
- b: 4,
- c: [5, 6],
- d: { e: [7, 8], f: 9 },
-}
+//=> on('eh', 'canada', this) // 1st branch
-var leaves = traverse(obj).reduce(function(acc, x) {
- if (this.isLeaf) acc.push(x)
- return acc
-}, [])
-
-console.dir(leaves)
-//=> [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
+//=> on('arr', [{moose: true}, 0], this)
+//=> on('arr.0', [{moose: true}], this)
+//=> on('arr.0.moose', true, this)
+//=> on('arr.1', [0], this)
```
---
@@ -448,395 +235,126 @@ console.dir(leaves)
-# Traverse.prototype.set(arrayPath=undefined, value=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/traverse.js#L166 "View in source") [Ⓣ][1]
-
-(Function): Set the element at the array path to value.
-
-#### Arguments
-1. `arrayPath=undefined` *(string[])*: paths
-2. `value=undefined` *(any)*: any value to assign to the element @ the path
+Traverse.remove([arg=undefined])
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/traverse.js#L397 "View in source") [Ⓣ][1]
-#### Returns
-*(any)*: value passed in
+(Function): Remove the current element from the output.
+If the node is in an Array it will be spliced off.
+Otherwise it will be deleted from its parent.
----
-
-
-
-
-
-
-## `after`
-
-
-
-# after(fn=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/traverse.js#L485 "View in source") [Ⓣ][1]
-
-(Function): Call this function after any of the children are traversed.
+#### @Since
+2.0.0
#### Arguments
-1. `fn=undefined` *(Function)*:
+1. `[arg=undefined]` *(|Object)*: optional obj to use, defaults to this.node
#### Returns
-*(any)*:
-
----
-
-
-
-
-
-
-
-## `before`
-
-
-
-# before(fn=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/traverse.js#L477 "View in source") [Ⓣ][1]
+*(void)*:
-(Function): Call this function before any of the children are traversed.
-You can assign into this.keys here to traverse in a custom order.
+#### Example
+```js
+traverse([0]).forEach((key, val, it) => it.remove())
+//=> []
-#### Arguments
-1. `fn=undefined` *(Function)*:
+traverse({ eh: true }).forEach((key, val, it) => it.remove())
+//=> {}
-#### Returns
-*(any)*:
+traverse({ eh: true, str: 'stringy' }).forEach((key, val, it) => {
+ if (!isString(val)) it.remove()
+})
+//=> {str: 'stringy'}
+```
---
-
-
-
-
-## `block`
-
-# block()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/traverse.js#L517 "View in source") [Ⓣ][1]
+Traverse.skip()
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/traverse.js#L298 "View in source") [Ⓣ][1]
Function
-#### Returns
-*(void)*:
-
----
-
-
-
+#### @todos
-
-
-## `circular`
-
-
-
-# circular
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/traverse.js#L427 "View in source") [Ⓣ][1]
-
-unknown
-
----
-
-
-
-
-
-
-
-## `delete`
-
-
-
-# delete(stopHere=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/traverse.js#L448 "View in source") [Ⓣ][1]
-
-(Function): Delete the current element from its parent in the output. Calls delete even on Arrays.
+- [ ] skip 1 branch
+
-#### Arguments
-1. `stopHere=undefined` *(boolean)*:
+#### @Since
+3.0.0
#### Returns
*(void)*:
----
-
-
-
-
-
-
-
-## `forEach`
-
-
-
-# forEach()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/traverse.js#L673 "View in source") [Ⓣ][1]
-
-(Function): adds methods to Traverser
-
----
-
-
-
-
-
-
-
-## `isRoot`
-
-
-
-# isRoot
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/traverse.js#L417 "View in source") [Ⓣ][1]
-
-(Boolean): Whether the present node is the root node
-
----
-
-
-
-
-
-
-
-## `key`
-
-
-
-# key
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/traverse.js#L412 "View in source") [Ⓣ][1]
-
-unknown
-
----
-
-
-
-
-
-
-
-## `level`
-
-
-
-# level
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/traverse.js#L422 "View in source") [Ⓣ][1]
-
-(number): Depth of the node within the traversal
-
----
-
-
-
-
-
-
-
-## `node`
-
-
-
-# node
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/traverse.js#L390 "View in source") [Ⓣ][1]
-
-(Array): The present node on the recursive walk
-
----
-
-
-
-
-
-
-
-## `node_`
-
-
-
-# node_
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/traverse.js#L396 "View in source") [Ⓣ][1]
-
-Array
-
----
-
-
-
-
-
-
-
-## `parent`
-
-
-
-# parent
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/traverse.js#L406 "View in source") [Ⓣ][1]
-
-unknown
-
----
-
-
-
-
-
-
-
-## `path`
-
-
-
-# path
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/traverse.js#L401 "View in source") [Ⓣ][1]
-
-(Array): An array of string keys from the root to the present node
+#### Example
+```js
+traverse([1, 2, 3, [4]]).forEach((key, val, t) => {
+ if (isArray(val)) t.skip()
+})
+```
---
-
-
-## `post`
-
-
+Traverse.stop()
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/traverse.js#L278 "View in source") [Ⓣ][1]
-# post(fn=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/traverse.js#L501 "View in source") [Ⓣ][1]
-
-(Function): Call this function after each of the children are traversed.
-
-#### Arguments
-1. `fn=undefined` *(Function)*:
+(Function): stop the iteration
#### Returns
-*(any)*:
-
----
-
-
-
-
-
-
-
-## `pre`
-
-
-
-# pre(fn=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/traverse.js#L493 "View in source") [Ⓣ][1]
-
-(Function): Call this function before each of the children are traversed.
-
-#### Arguments
-1. `fn=undefined` *(Function)*:
+*(void)*:
-#### Returns
-*(any)*:
+#### Example
+```js
+traverse({ eh: true, arr: [] }).forEach((key, val, t) => {
+ if (isArray(val)) this.stop()
+})
+```
---
-
-
-## `remove`
+Traverse.update(value=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/traverse.js#L440 "View in source") [Ⓣ][1]
-
+(Function): update the value for the current key
-# remove(stopHere=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/traverse.js#L457 "View in source") [Ⓣ][1]
-(Function): Remove the current element from the output. If the node is in an Array it will be spliced off. Otherwise it will be deleted from its parent.
+#### @Since
+2.0.0
#### Arguments
-1. `stopHere=undefined` *(boolean)*:
+1. `value=undefined` *(*)*: this.node[this.key] = value
#### Returns
*(void)*:
----
-
-
-
-
-
-
-
-## `return`
-
-
-
-# return(node_=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/traverse.js#L374 "View in source") [Ⓣ][1]
-
-Function
-
-#### Arguments
-1. `node_=undefined` *(any)*:
-
-#### Returns
-*(State)*: see types
-
----
-
-
-
-
-
-
-
-## `state`
-
-
-
-# state
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/traverse.js#L385 "View in source") [Ⓣ][1]
-
-(Object): Each method that takes a callback has a context *(its this object)* with these attributes:
-
-
-### @classProps
-
-* {isRoot} @alias isNotRoot Whether or not the present node is a leaf node (has no children)
-
----
-
-
-
-
-
-
-
-## `stop`
-
-
-
-# stop()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/traverse.js#L509 "View in source") [Ⓣ][1]
-
-Function
-
-#### Returns
-*(void)*:
+#### Example
+```js
+traverse({ eh: true }).forEach((key, val, traverser) => {
+ if (this.isRoot) return
+ traverser.update(false)
+})
+//=> {eh: false}
+```
---
@@ -845,68 +363,36 @@ Function
-## `traverse`
-
-
-
-# walk(root=undefined, cb=undefined, immutable=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/traverse.js#L360 "View in source") [Ⓣ][1]
-
-Function
-
-#### Arguments
-1. `root=undefined` *(any)*: root node
-2. `cb=undefined` *(Function)*: callback for each
-3. `immutable=undefined` *(boolean)*: should mutate or not
-
-#### Returns
-*(any)*:
-
----
-
-
+## `clone`
-# copy(src=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/traverse.js#L610 "View in source") [Ⓣ][1]
+clone(arg=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/traverse.js#L801 "View in source") [Ⓣ][1]
Function
-### @notes
+#### @todos
-* wicked ternary
-
-
-### @todos
-
-- [ ] does not respect ObjectDescriptors
+- [ ] merge with dopemerge?
+- [ ] needs tests converted back for this (observe tests do cover somewhat)
#### Arguments
-1. `src=undefined` *(any)*:
+1. `arg=undefined` *(*)*: defaults to this.node
#### Returns
-*(any)*:
-
----
-
-
-
-
-
-# traverse(obj=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/traverse.js#L7 "View in source") [Ⓣ][1]
-
-Function
-
-#### Arguments
-1. `obj=undefined` *(Traversable)*: object to traverse
+*(*)*: cloned
#### Example
```js
-traverse({})
-//=> new Traverse(obj)
+var obj = {}
+var cloned = traverse().clone(obj)
+obj.eh = true
+eq(obj, cloned)
+//=> false
```
---
@@ -917,22 +403,27 @@ traverse({})
-## `update`
+## `copy`
-# update(x=undefined, stopHere=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/traverse.js#L436 "View in source") [Ⓣ][1]
+copy(src=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/traverse.js#L808 "View in source") [Ⓣ][1]
+
+Function
+
-(Function): Set a new value for the present node.
-All the elements in value will be recursively traversed unless stopHere is true.
+#### @todos
+- [ ] ugh, how to clone better with *recursive* objects?
+
#### Arguments
-1. `x=undefined` *(Function)*:
-2. `stopHere=undefined` *(boolean)*:
+1. `src=undefined` *(any)*: wip
#### Returns
-*(void)*:
+*(any)*: wip
---
@@ -942,17 +433,16 @@ All the elements in value will be recursively traversed unless stopHere is true.
-## `updateState`
+## `traverse`
-# updateState()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/traverse.js#L533 "View in source") [Ⓣ][1]
-
-(Function): updates if needed:
+
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/traverse.js#L22 "View in source") [Ⓣ][1]
-#### Returns
-*(void)*:
+unknown
---
@@ -962,4 +452,4 @@ All the elements in value will be recursively traversed unless stopHere is true.
- [1]: #traverse.prototype "Jump back to the TOC."
+ [1]: #traverse "Jump back to the TOC."
diff --git a/docs/docdown/deps/traversers/_eq.md b/docs/docdown/deps/traversers/_eq.md
new file mode 100644
index 0000000..0022459
--- /dev/null
+++ b/docs/docdown/deps/traversers/_eq.md
@@ -0,0 +1,75 @@
+# _eq.js API documentation
+
+
+
+
+
+## `Traverse`
+* `Traverse.eq`
+
+
+
+
+
+
+
+
+
+## `Traverse`
+
+
+
+Traverse.eq(traverse=undefined, a=undefined, b=undefined, [loose=undefined])
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/traversers/_eq.js#L25 "View in source") [Ⓣ][1]
+
+Function
+
+
+#### @see
+
+* js-equality-table
+* immutable-js-deep-equal
+* node-deep-equal
+* ramda-equals
+* lodash-is-equal
+* angular-is-equal
+* underscore-equal
+* traverse-deep-equal
+* react-deep-differ
+
+#### @extends
+
+
+
+
+#### @Since
+3.0.0
+
+#### Arguments
+1. `traverse=undefined` *(Traverse): traversejs *(scoped, @FIXME @HACK)**
+2. `a=undefined` *(*)*: compare to b
+3. `b=undefined` *(*)*: compare to a
+4. `[loose=undefined]` *(boolean)*: compare loosely
+
+#### Returns
+*(boolean)*: isEqual: a === b
+
+#### Example
+```js
+eq(1, 1) //=> true
+eq(1, '1') //=> false
+eq(1, '1', true) //=> true
+eq([1], [1]) //=> true
+
+```
+---
+
+
+
+
+
+
+
+ [1]: #traverse "Jump back to the TOC."
diff --git a/docs/docdown/deps/traversers/copy.md b/docs/docdown/deps/traversers/copy.md
new file mode 100644
index 0000000..0d5b501
--- /dev/null
+++ b/docs/docdown/deps/traversers/copy.md
@@ -0,0 +1,59 @@
+# copy.js API documentation
+
+
+
+
+
+## `Traverse`
+* `Traverse.copy`
+
+
+
+
+
+
+
+
+
+## `Traverse`
+
+
+
+Traverse.copy(src=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/traversers/copy.js#L29 "View in source") [Ⓣ][1]
+
+(Function): copy any primitive value, part of clone
+
+
+#### @see
+
+* clone
+
+#### @Since
+3.0.0
+
+#### Arguments
+1. `src=undefined` *(*)*: value to copy
+
+#### Returns
+*(*)*: copied
+
+#### Example
+```js
+copy(/eh/gim) //=> new RegExp('eh', 'gmi')
+copy(new Error('eh')) // => new Error with copied stack + msg
+copy([1]) // => [1]
+copy({}) // => {}
+
+```
+---
+
+
+
+
+
+
+
+ [1]: #traverse "Jump back to the TOC."
diff --git a/docs/docdown/deps/traversers/eq.md b/docs/docdown/deps/traversers/eq.md
index ba308e0..a25ed62 100644
--- a/docs/docdown/deps/traversers/eq.md
+++ b/docs/docdown/deps/traversers/eq.md
@@ -2,106 +2,10 @@
-
-
-## `traverse.prototype`
-* `traverse.prototype.exports`
-
-
-
-
-
-## `traverse.prototype`
-
-
-
-* 🌊 Types: TraverseChain.d
-* 🌊 Types: traverse.d
-
-# traverse.prototype.exports(a=undefined, b=undefined, [loose=false])
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/traversers/eq.js#L94 "View in source") [Ⓣ][1]
-
-(Function): deep traversal of nodes to compare any data types does not check reference, only value equality
-
-
-### @see
-
-* fluents/chain able/blob/master/src/traverse chain.js
-
-### @symb
-
-⚖️
-#### Since
-3.0.0
-
-#### Arguments
-1. `a=undefined` *(any)*: compare a with b
-2. `b=undefined` *(any)*: compare b with a
-3. `[loose=false]` *(boolean)*: whether to do looser equals check
-
-#### Returns
-*(boolean)*: isEqual
-
-#### Example
-```js
-eq(1, 1)
-//=> true
-
-eq(true, false)
-//=> false
-
-eq({}, {})
-//=> true
-
-```
-#### Example
-```js
-eq(
- { d: new Date(0, 0, 0, 0), x: [1, 2, 3] },
- { d: new Date(0, 0, 0, 0), x: [1, 2, 3] }
-)
-//=> true
-
-eq([new RegExp('x')], [/x/])
-//=> true
-
-eq([new String('x')], ['x'])
-//=> true
-
-eq([new Boolean(false)], [false])
-//=> true
-
-eq([undefined], [null]) || eq(undefined, null)
-//=> false
-
-```
-#### Example
-```js
-var xs = [1, 2, 3, 4]
-delete xs[2]
-
-var ys = Object.create(Array.prototype)
-ys[0] = 1
-ys[1] = 2
-ys[3] = 4
-
-eq(xs, ys)
-//=> true
-
-eq(xs, [1, 2, undefined, 4])
-//=> false
-
-```
----
-
-
-
-
-
- [1]: #traverse.prototype "Jump back to the TOC."
+ [1]: # "Jump back to the TOC."
diff --git a/docs/docdown/deps/traversers/eqValue.md b/docs/docdown/deps/traversers/eqValue.md
new file mode 100644
index 0000000..9ddfe76
--- /dev/null
+++ b/docs/docdown/deps/traversers/eqValue.md
@@ -0,0 +1,62 @@
+# eqValue.js API documentation
+
+
+
+
+
+## `Traverse`
+* `Traverse.exports`
+
+
+
+
+
+
+
+
+
+## `Traverse`
+
+
+
+Traverse.exports(x=undefined, y=undefined, [loose=false])
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/traversers/eqValue.js#L48 "View in source") [Ⓣ][1]
+
+(Function): checks value equality, used by eq which compares all types
+
+
+#### @todos
+
+- [ ] !!!!!! USE ENUM FLAGS ON LOOSE TO ALLOW MORE CONFIG FOR ==, COMPARATOR, VALUEOF, walk proto (check ownProps...)...
+
+
+#### @Since
+4.1.0
+
+#### Arguments
+1. `x=undefined` *(*)*: compare to y
+2. `y=undefined` *(*)*: compare to x
+3. `[loose=false]` *(boolean|number)*: use == checks when typof !=
+
+#### Returns
+*(boolean)*:
+
+#### Example
+```js
+eqValue(1, 1) //=> true
+eqValue('1', 1) //=> false
+eqValue('1', 1, true) //=> true
+eqValue({}, {}) //=> true
+
+```
+---
+
+
+
+
+
+
+
+ [1]: #traverse "Jump back to the TOC."
diff --git a/docs/docdown/deps/traversers/eqdeep.md b/docs/docdown/deps/traversers/eqdeep.md
new file mode 100644
index 0000000..c190fc9
--- /dev/null
+++ b/docs/docdown/deps/traversers/eqdeep.md
@@ -0,0 +1,11 @@
+# eqdeep.js API documentation
+
+
+
+
+
+
+
+
+
+ [1]: # "Jump back to the TOC."
diff --git a/docs/docdown/deps/traversers/stringify.md b/docs/docdown/deps/traversers/stringify.md
new file mode 100644
index 0000000..79afae4
--- /dev/null
+++ b/docs/docdown/deps/traversers/stringify.md
@@ -0,0 +1,11 @@
+# stringify.js API documentation
+
+
+
+
+
+
+
+
+
+ [1]: # "Jump back to the TOC."
diff --git a/docs/docdown/deps/traversers/traverse-comments.md b/docs/docdown/deps/traversers/traverse-comments.md
new file mode 100644
index 0000000..df93d90
--- /dev/null
+++ b/docs/docdown/deps/traversers/traverse-comments.md
@@ -0,0 +1,11 @@
+# traverse-comments.js API documentation
+
+
+
+
+
+
+
+
+
+ [1]: # "Jump back to the TOC."
diff --git a/docs/docdown/deps/util/assign.md b/docs/docdown/deps/util/assign.md
index 495aba2..80d9cdd 100644
--- a/docs/docdown/deps/util/assign.md
+++ b/docs/docdown/deps/util/assign.md
@@ -2,10 +2,44 @@
+
+
+## `util`
+* `util.exports`
+
+
+
+
+
+## `util`
+
+
+
+util.exports
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/util/assign.js#L5 "View in source") [Ⓣ][1]
+
+Function
+
+
+#### @see
+
+* react-object-assign
+* ramda-assign
+* lodash-assign
+* esdiscuss-object-assign
+* mozilla-object-assign
+---
+
+
+
+
+
- [1]: # "Jump back to the TOC."
+ [1]: #util "Jump back to the TOC."
diff --git a/docs/docdown/deps/util/flatten.md b/docs/docdown/deps/util/flatten.md
index a5ab7a0..3fc4bb9 100644
--- a/docs/docdown/deps/util/flatten.md
+++ b/docs/docdown/deps/util/flatten.md
@@ -2,10 +2,60 @@
+
+
+## `util`
+* `util.exports`
+
+
+
+
+
+## `util`
+
+
+
+util.exports(x=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/util/flatten.js#L20 "View in source") [Ⓣ][1]
+
+(Function): flatten multi-dimensional arrays in `1` line
+
+
+#### @see
+
+* https://stackoverflow.com/questions/10865025/merge-flatten-an-array-of-arrays-in-javascript
+
+#### @Since
+4.0.0
+
+#### Arguments
+1. `x=undefined` *(Array|any)[]): array(s)* to flatten
+
+#### Returns
+*(*)*: flattened arrays
+
+#### Example
+```js
+flatten([[1], [2]])
+//=> [1, 2]
+flatten([[1], 2])
+//=> [1, 2]
+flatten(1)
+//=> [1]
+
+```
+---
+
+
+
+
+
- [1]: # "Jump back to the TOC."
+ [1]: #util "Jump back to the TOC."
diff --git a/docs/docdown/deps/util/from.md b/docs/docdown/deps/util/from.md
index 7a92f07..a7ec6a1 100644
--- a/docs/docdown/deps/util/from.md
+++ b/docs/docdown/deps/util/from.md
@@ -5,7 +5,7 @@
## `exports`
-* `exports`
+* `exports`
@@ -19,11 +19,17 @@
-# exports
+exports
+
+
[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/util/from.js#L6 "View in source") [Ⓣ][1]
unknown
+
+#### @see
+
+* https://github.com/lodash/lodash/blob/master/.internal/setToArray.js
---
diff --git a/docs/docdown/deps/util/index.md b/docs/docdown/deps/util/index.md
new file mode 100644
index 0000000..5ac127d
--- /dev/null
+++ b/docs/docdown/deps/util/index.md
@@ -0,0 +1,11 @@
+# index.js API documentation
+
+
+
+
+
+
+
+
+
+ [1]: # "Jump back to the TOC."
diff --git a/docs/docdown/deps/util/keysObjOrArray.md b/docs/docdown/deps/util/keysObjOrArray.md
new file mode 100644
index 0000000..d46e2c9
--- /dev/null
+++ b/docs/docdown/deps/util/keysObjOrArray.md
@@ -0,0 +1,79 @@
+# keysObjOrArray.js API documentation
+
+
+
+
+
+## `keysObjOrArray`
+* `keysObjOrArray`
+
+
+
+
+
+
+
+
+
+## `keysObjOrArray`
+
+
+
+keysObjOrArray(obj=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/util/keysObjOrArray.js#L27 "View in source") [Ⓣ][1]
+
+(Function): Creates an array of the own enumerable property names of `object`.
+**Note:** Non-object values are coerced to objects. See the
+[ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
+for more details.
+
+
+#### @see
+
+* deps/util/lengthFromZero
+* deps/util/props
+*
+* lodash-keys
+* lodash-get-all-keys
+
+#### @todos
+
+- [ ] https://github.com/lodash/lodash/blob/master/.internal/arrayLikeKeys.js
+
+
+#### @Since
+0.1.0
+
+#### Arguments
+1. `obj=undefined` *(Object)*: The object to query.
+
+#### Returns
+*(Array)*: Returns the array of property names.
+
+#### Example
+```js
+function Foo() {
+ this.a = 1
+ this.b = 2
+}
+
+Foo.prototype.c = 3
+
+keys(new Foo())
+// => ['a', 'b'] (iteration order is not guaranteed)
+
+keys('hi')
+// => ['0', '1']
+
+```
+---
+
+
+
+
+
+
+
+ [1]: #keysobjorarray "Jump back to the TOC."
diff --git a/docs/docdown/deps/util/keywords.md b/docs/docdown/deps/util/keywords.md
new file mode 100644
index 0000000..eb8e102
--- /dev/null
+++ b/docs/docdown/deps/util/keywords.md
@@ -0,0 +1,11 @@
+# keywords.js API documentation
+
+
+
+
+
+
+
+
+
+ [1]: # "Jump back to the TOC."
diff --git a/docs/docdown/deps/util/lengthFromZero.md b/docs/docdown/deps/util/lengthFromZero.md
new file mode 100644
index 0000000..46a2802
--- /dev/null
+++ b/docs/docdown/deps/util/lengthFromZero.md
@@ -0,0 +1,69 @@
+# lengthFromZero.js API documentation
+
+
+
+
+
+## `util`
+* `util.lengthFromZero`
+
+
+
+
+
+
+
+
+
+## `util`
+
+
+
+util.lengthFromZero(obj=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/util/lengthFromZero.js#L28 "View in source") [Ⓣ][1]
+
+(Function): when length > `1`, use length-1
+otherwise, when length == `1`, use `0`
+default, use length
+
+
+#### @see
+
+* util/length
+* util/lengthMinusOne
+
+#### @todos
+
+- [ ] lense to use an object, or transform it to one with .length?
+ const len = prop('length')
+ // when isObj, use len, otherwise, value
+ const coerceLength = lense([isObj, len])
+
+
+#### @Since
+5.0.0-beta.2
+
+#### Arguments
+1. `obj=undefined` *(Array|Object|number)*: with length
+
+#### Returns
+*(number)*: obj length from `0`
+
+#### Example
+```js
+lengthFromZero([1]) //=> 1
+lengthFromZero([]) //=> 0
+lengthFromZero([1, 2, 3]) //=> 2
+
+```
+---
+
+
+
+
+
+
+
+ [1]: #util "Jump back to the TOC."
diff --git a/docs/docdown/deps/util/localGlobal.md b/docs/docdown/deps/util/localGlobal.md
new file mode 100644
index 0000000..03b9580
--- /dev/null
+++ b/docs/docdown/deps/util/localGlobal.md
@@ -0,0 +1,11 @@
+# localGlobal.js API documentation
+
+
+
+
+
+
+
+
+
+ [1]: # "Jump back to the TOC."
diff --git a/docs/docdown/deps/util/noop.md b/docs/docdown/deps/util/noop.md
new file mode 100644
index 0000000..3cc0995
--- /dev/null
+++ b/docs/docdown/deps/util/noop.md
@@ -0,0 +1,58 @@
+# noop.js API documentation
+
+
+
+
+
+## `noop`
+* `noop`
+
+
+
+
+
+
+
+
+
+## `noop`
+
+
+
+noop()
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/util/noop.js#L17 "View in source") [Ⓣ][1]
+
+Function
+
+
+#### @see
+
+* noop3
+
+#### @Since
+5.0.0
+
+#### Returns
+*(void)*:
+
+#### Example
+```js
+noop
+
+```
+#### Example
+```js
+noop()
+
+```
+---
+
+
+
+
+
+
+
+ [1]: #noop "Jump back to the TOC."
diff --git a/docs/docdown/deps/util/props.md b/docs/docdown/deps/util/props.md
index b92ba6e..ae1dba7 100644
--- a/docs/docdown/deps/util/props.md
+++ b/docs/docdown/deps/util/props.md
@@ -5,7 +5,7 @@
## `allProperties`
-* `allProperties`
+* `allProperties`
@@ -19,16 +19,37 @@
-# allProperties(obj=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/util/props.js#L30 "View in source") [Ⓣ][1]
+allProperties(obj=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/util/props.js#L38 "View in source") [Ⓣ][1]
(Function): properties, property symbols, object keys ^ all again for prototype
+
+#### @see
+
+* deps/gc
+* deps/utils/nonEnumerableTypes
+* http://2ality.com/2011/07/js-properties.html
+
+#### @todos
+
+- [ ] https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptors
+`const getOwnPropertyDescriptors = Object.getOwnPropertyDescriptors`
+
+
+#### @Since
+3.0.0
+
#### Arguments
1. `obj=undefined` *(Object)*: object to get properties & symbols from
#### Returns
*(*)*: properties
+
+
+only used in gc *(as of 5.0.0-beta.4)*
#### Example
```js
diff --git a/docs/docdown/deps/util/simpleKindOf.md b/docs/docdown/deps/util/simpleKindOf.md
index 60f3240..6c988fe 100644
--- a/docs/docdown/deps/util/simpleKindOf.md
+++ b/docs/docdown/deps/util/simpleKindOf.md
@@ -5,7 +5,7 @@
## `exports`
-* `exports`
+* `exports`
@@ -19,17 +19,38 @@
-# exports(x=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/util/simpleKindOf.js#L12 "View in source") [Ⓣ][1]
+exports(x=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/util/simpleKindOf.js#L24 "View in source") [Ⓣ][1]
(Function): when Array -> 'array' when null -> 'null' else `typeof x`
+
+#### @todos
+
+- [ ] `type.split(' ').pop().replace(/\s\[\]/g, '').toLowerCase()`
+
+
+#### @Since
+4.0.0
+
#### Arguments
-1. `x=undefined` *(any)*:
+1. `x=undefined` *(any)*: value for type
#### Returns
*(string)*: type
+
+
+split at space, replace brackets and space, lowercase
+
+#### Example
+```js
+simpleKindOf([]) //=> 'array'
+simpleKindOf(null) //=> 'null'
+simpleKindOf({}) //=> 'object'
+```
---
diff --git a/docs/docdown/deps/util/util.md b/docs/docdown/deps/util/util.md
new file mode 100644
index 0000000..5920e90
--- /dev/null
+++ b/docs/docdown/deps/util/util.md
@@ -0,0 +1,37 @@
+# util.js API documentation
+
+
+
+
+
+## `util.exports`
+* `util.exports`
+
+
+
+
+
+
+
+
+
+## `util.exports`
+
+
+
+util.exports
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/util/util.js#L25 "View in source") [Ⓣ][1]
+
+Object
+
+---
+
+
+
+
+
+
+
+ [1]: #util.exports "Jump back to the TOC."
diff --git a/docs/docdown/deps/validators/error.md b/docs/docdown/deps/validators/error.md
index 436e68d..eaecde7 100644
--- a/docs/docdown/deps/validators/error.md
+++ b/docs/docdown/deps/validators/error.md
@@ -4,8 +4,8 @@
-## `encase.prototype`
-* `encase.prototype.exports`
+## `encase`
+* `encase.exports`
@@ -15,28 +15,31 @@
-## `encase.prototype`
+## `encase`
-# encase.prototype.exports(method=undefined, type=undefined)
+encase.exports(method=undefined, type=undefined)
+
+
[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/validators/error.js#L54 "View in source") [Ⓣ][1]
(Function): enhance an Error, enable rethrowing & better inspection
-### @see
+#### @see
-* fluents/chain able/blob/master/src/method chain.js
-* fluents/chain able/blob/master/src/deps/validators/schema builder.js
-* fluents/chain able/blob/master/src/deps/validators/validator builder.js
-* fluents/chain able/blob/master/src/plugins/encase.js
+* MethodChain
+* validators/schemaBuilder
+* validators/validatorBuilder
+* plugins/encase
-### @todos
+#### @todos
- [ ] js stringify if development
-#### Since
+
+#### @Since
4.0.0-alpha.1
#### Arguments
@@ -77,4 +80,4 @@ console.log(error)
- [1]: #encase.prototype "Jump back to the TOC."
+ [1]: #encase "Jump back to the TOC."
diff --git a/docs/docdown/deps/validators/schemaBuilder.md b/docs/docdown/deps/validators/schemaBuilder.md
index 7ac5ed7..d26b313 100644
--- a/docs/docdown/deps/validators/schemaBuilder.md
+++ b/docs/docdown/deps/validators/schemaBuilder.md
@@ -4,15 +4,15 @@
-## `schema.prototype`
-* `schema.prototype.typeValidator`
+## `schema`
+* `schema.typeValidator`
## `schemaFactory`
-* `schemaFactory`
+* `schemaFactory`
@@ -22,24 +22,27 @@
-## `schema.prototype`
+## `schema`
-# schema.prototype.typeValidator(input=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/validators/schemaBuilder.js#L102 "View in source") [Ⓣ][1]
+schema.typeValidator(input=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/validators/schemaBuilder.js#L91 "View in source") [Ⓣ][1]
(Function): build a recursive schema for all around runtime type safety
-### @see
+#### @see
-* fluents/chain able/blob/master/src/deps/is/array.js
+* is
-### @symb
+#### @symb
🛂
-#### Since
+
+#### @Since
4.0.0-beta.1
#### Arguments
@@ -89,12 +92,15 @@ var isValid = typeValidator(1)
-# schemaFactory(property=undefined, nestedSchema=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/validators/schemaBuilder.js#L60 "View in source") [Ⓣ][1]
+schemaFactory(property=undefined, nestedSchema=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/validators/schemaBuilder.js#L49 "View in source") [Ⓣ][1]
(Function): pass the property & schema in, get a nestable typeValidator out
-#### Since
+
+#### @Since
4.0.0-alpha.1
#### Arguments
@@ -139,4 +145,4 @@ input = {
- [1]: #schema.prototype "Jump back to the TOC."
+ [1]: #schema "Jump back to the TOC."
diff --git a/docs/docdown/deps/validators/validatorBuilder.md b/docs/docdown/deps/validators/validatorBuilder.md
index 008d2f8..2f834ff 100644
--- a/docs/docdown/deps/validators/validatorBuilder.md
+++ b/docs/docdown/deps/validators/validatorBuilder.md
@@ -5,35 +5,35 @@
## `ChainedMap`
-* `ChainedMap`
+* `ChainedMap`
## `addTypes`
-* `addTypes`
+* `addTypes`
## `arithmeticTypeFactory`
-* `arithmeticTypeFactory`
+* `arithmeticTypeFactory`
## `builder`
-* `builder`
+* `builder`
-## `schema.prototype`
-* `schema.prototype.typeListFactory`
+## `schema`
+* `schema.typeListFactory`
@@ -47,7 +47,9 @@
-# ChainedMap(validators=undefined)
+ChainedMap(validators=undefined)
+
+
[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/validators/validatorBuilder.js#L8 "View in source") [Ⓣ][1]
(Function): library of validators to use by name
@@ -69,11 +71,17 @@
🌊 Types: schema.d
-# addTypes(types=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/validators/validatorBuilder.js#L75 "View in source") [Ⓣ][1]
+addTypes(types=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/validators/validatorBuilder.js#L74 "View in source") [Ⓣ][1]
(Function): add custom types for validation
+
+#### @see
+
+* deps/validators/validatorFactory
#### Arguments
1. `types=undefined` *(Object)*: custom Types
@@ -116,17 +124,24 @@ new Chain().methods('eh').type('*').build().eh
🌊 Types: schema.d
-# arithmeticTypeFactory(fullKey=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/validators/validatorBuilder.js#L182 "View in source") [Ⓣ][1]
+arithmeticTypeFactory(fullKey=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/validators/validatorBuilder.js#L172 "View in source") [Ⓣ][1]
(Function): transform arithmetic strings into types
-### @todos
+#### @see
+
+* is
+
+#### @todos
- [ ] coercing values to certain types: arithmeticTypeFactory('')
-#### Since
+
+#### @Since
4.0.0-alpha.1
#### Arguments
@@ -178,18 +193,25 @@ arithmeticTypeFactory('===')
-# builder(fullKey=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/validators/validatorBuilder.js#L247 "View in source") [Ⓣ][1]
+builder(fullKey=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/validators/validatorBuilder.js#L237 "View in source") [Ⓣ][1]
(Function): @pattern @builder -> builds using multiple factories depending on conditons or abstractFactory whatever opinionated: if it's a function, it's a validator...
-### @notes
+#### @see
+
+* https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/Default_parameters
+
+#### @notes
* if/else is for uglifying ternaries, even though else if is not needed
* if key is number, iterating the array
-#### Since
+
+#### @Since
4.0.0
#### Arguments
@@ -231,12 +253,14 @@ builder('string|string[]')
-## `schema.prototype`
+## `schema`
-# schema.prototype.typeListFactory(fullKey=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/validators/validatorBuilder.js#L110 "View in source") [Ⓣ][1]
+schema.typeListFactory(fullKey=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/deps/validators/validatorBuilder.js#L100 "View in source") [Ⓣ][1]
Function
diff --git a/docs/docdown/dists/dev/index.md b/docs/docdown/dists/dev/index.md
deleted file mode 100644
index 47b12e4..0000000
--- a/docs/docdown/dists/dev/index.md
+++ /dev/null
@@ -1,7812 +0,0 @@
-# index.js API documentation
-
-
-
-
-
-## `/* istanbul ignore next`
-* `/* istanbul ignore next`
-
-
-
-
-
-## `CM`
-* `CM`
-
-
-
-
-
-## `Chainable.prototype`
-* `Chainable.prototype.Chainable`
-
-
-
-
-
-## `ChainedMapBase.prototype`
-* `ChainedMapBase.prototype.CMC`
-* `ChainedMapBase.prototype.compose`
-* `ChainedMapBase.prototype.entries`
-* `ChainedMapBase.prototype.extend`
-* `ChainedMapBase.prototype.from`
-* `ChainedMapBase.prototype.get`
-* `ChainedMapBase.prototype.set`
-* `ChainedMapBase.prototype.tap`
-
-
-
-
-
-## `ChainedSet`
-* `ChainedSet`
-
-
-
-
-
-## `DotProp.prototype`
-* `DotProp.prototype.get`
-* `DotProp.prototype.set`
-
-
-
-
-
-## `FactoryChain.prototype`
-* `FactoryChain.prototype.FactoryChain`
-* `FactoryChain.prototype.chainUpDowns`
-* `FactoryChain.prototype.factory`
-* `FactoryChain.prototype.getData`
-* `FactoryChain.prototype.prop`
-* `FactoryChain.prototype.props`
-
-
-
-
-
-## `MergeChain.prototype`
-* `MergeChain.prototype.MergeChain`
-* `MergeChain.prototype.init`
-* `MergeChain.prototype.onExisting`
-
-
-
-
-
-## `MethodChain.prototype`
-* `MethodChain.prototype.MethodChain`
-* `MethodChain.prototype._build`
-* `MethodChain.prototype._defaults`
-* `MethodChain.prototype.autoGetSet`
-* `MethodChain.prototype.autoIncrement`
-* `MethodChain.prototype.build`
-* `MethodChain.prototype.decorate`
-* `MethodChain.prototype.decorate`
-* `MethodChain.prototype.name`
-* `MethodChain.prototype.schema`
-
-
-
-
-
-## `Observe.prototype`
-* `Observe.prototype.`
-* `Observe.prototype.DotProp`
-* `Observe.prototype.Observe`
-
-
-
-
-
-## `ShorthandChain.prototype`
-* `ShorthandChain.prototype.return`
-* `ShorthandChain.prototype.setIfEmpty`
-* `ShorthandChain.prototype.wrap`
-
-
-
-
-
-## `Transform`
-* `Transform`
-
-
-
-
-
-## `TransformChain.prototype`
-* `TransformChain.prototype.`
-* `TransformChain.prototype.remap`
-* `TransformChain.prototype.set`
-* `TransformChain.prototype.transform`
-
-
-
-
-
-## `Traverse.prototype`
-* `Traverse.prototype.`
-* `Traverse.prototype.`
-* `Traverse.prototype.TraverseChain`
-* `Traverse.prototype.clone`
-* `Traverse.prototype.forEach`
-* `Traverse.prototype.get`
-* `Traverse.prototype.has`
-* `Traverse.prototype.nodes`
-* `Traverse.prototype.paths`
-* `Traverse.prototype.reduce`
-* `Traverse.prototype.set`
-
-
-
-
-
-## `TraverseChain.prototype`
-* `TraverseChain.prototype.traverse`
-
-
-
-
-
-## `add`
-* `add`
-* `add`
-
-
-
-
-
-## `addTypes`
-* `addTypes`
-
-
-
-
-
-## `after`
-* `after`
-
-
-
-
-
-## `alias`
-* `alias`
-
-
-
-
-
-## `allProperties`
-* `allProperties`
-
-
-
-
-
-## `anyKeyVal`
-* `anyKeyVal`
-
-
-
-
-
-## `argumentor`
-* `argumentor`
-
-
-
-
-
-## `arithmeticTypeFactory`
-* `arithmeticTypeFactory`
-
-
-
-
-
-## `autoIncrement`
-* `autoIncrement`
-
-
-
-
-
-## `before`
-* `before`
-
-
-
-
-
-## `block`
-* `block`
-
-
-
-
-
-## `builder`
-* `builder`
-
-
-
-
-
-## `camelCase`
-* `camelCase`
-
-
-
-
-
-## `circular`
-* `circular`
-
-
-
-
-
-## `clear`
-* `clear`
-
-
-
-
-
-## `compose.prototype`
-* `compose.prototype.compose`
-
-
-
-
-
-## `conditional.prototype`
-* `conditional.prototype.all`
-* `conditional.prototype.and`
-* `conditional.prototype.not`
-* `conditional.prototype.or`
-
-
-
-
-
-## `debug`
-* `debug`
-
-
-
-
-
-## `define`
-* `define`
-* `define`
-
-
-
-
-
-## `delete`
-* `delete`
-* `delete`
-* `delete`
-
-
-
-
-
-## `dopemerge.prototype`
-* `dopemerge.prototype.cloneIfNeeded`
-* `dopemerge.prototype.defaultArrayMerge`
-* `dopemerge.prototype.dopemerge`
-* `dopemerge.prototype.emptyTarget`
-* `dopemerge.prototype.isMergeableObj`
-
-
-
-
-
-## `dot`
-* `dot`
-
-
-
-
-
-## `encase`
-* `encase`
-
-
-
-
-
-## `encase.prototype`
-* `encase.prototype.error$3`
-
-
-
-
-
-## `end`
-* `end`
-
-
-
-
-
-## `entries`
-* `entries`
-
-
-
-
-
-## `fn.call`
-* `fn.call`
-
-
-
-
-
-## `forEach`
-* `forEach`
-* `forEach`
-
-
-
-
-
-## `from`
-* `from`
-
-
-
-
-
-## `get`
-* `get`
-
-
-
-
-
-## `getMeta`
-* `getMeta`
-
-
-
-
-
-## `handleExisting`
-* `handleExisting`
-
-
-
-
-
-## `has`
-* `has`
-* `has`
-* `has`
-
-
-
-
-
-## `if`
-* `if`
-* `if`
-* `if`
-* `if`
-* `if`
-
-
-
-
-
-## `index`
-* ``
-* ``
-* ``
-* ``
-* ``
-* ``
-* ``
-* ``
-
-
-
-
-
-## `is.prototype`
-* `is.prototype.isBoolean`
-* `is.prototype.isDate`
-* `is.prototype.isError`
-* `is.prototype.isFalse`
-* `is.prototype.isFunction`
-* `is.prototype.isIterator`
-* `is.prototype.isMap`
-* `is.prototype.isMapish`
-* `is.prototype.isMatcher`
-* `is.prototype.isNotEmptyArray`
-* `is.prototype.isNull`
-* `is.prototype.isNullOrUndefined`
-* `is.prototype.isNumber`
-* `is.prototype.isObj`
-* `is.prototype.isObjLoose`
-* `is.prototype.isObjStrict`
-* `is.prototype.isObjWithKeys`
-* `is.prototype.isReal`
-* `is.prototype.isTrue`
-* `is.prototype.isUndefined`
-* `is.prototype.string`
-* `is.prototype.stringOrNumber`
-* `is.prototype.stringPrimitive`
-* `is.prototype.symbol`
-* `is.prototype.toS`
-
-
-
-
-
-## `is.prototype.index$12`
-* `is.prototype.index$12`
-
-
-
-
-
-## `isArray`
-* `isArray`
-
-
-
-
-
-## `isRoot`
-* `isRoot`
-
-
-
-
-
-## `key`
-* `key`
-
-
-
-
-
-## `level`
-* `level`
-
-
-
-
-
-## `m`
-* `m`
-
-
-
-
-
-## `markForGarbageCollection`
-* `markForGarbageCollection`
-
-
-
-
-
-## `matcher.prototype`
-* `matcher.prototype.escapeStringRegExp`
-* `matcher.prototype.make`
-* `matcher.prototype.match`
-* `matcher.prototype.matcher`
-* `matcher.prototype.toRegExp`
-
-
-
-
-
-## `merge`
-* `merge`
-* `merge`
-* `merge`
-
-
-
-
-
-## `meta`
-* `meta`
-
-
-
-
-
-## `method`
-* `method`
-
-
-
-
-
-## `methodEncasingFactory`
-* `methodEncasingFactory`
-
-
-
-
-
-## `node`
-* `node`
-
-
-
-
-
-## `node_`
-* `node_`
-
-
-
-
-
-## `objs`
-* `objs`
-
-
-
-
-
-## `objs.set`
-* `objs.set`
-
-
-
-
-
-## `parent`
-* `parent`
-
-
-
-
-
-## `path`
-* `path`
-
-
-
-
-
-## `paths`
-* `paths`
-
-
-
-
-
-## `post`
-* `post`
-
-
-
-
-
-## `pre`
-* `pre`
-
-
-
-
-
-## `prepend`
-* `prepend`
-
-
-
-
-
-## `prototype[iterator]`
-* `prototype[iterator]`
-
-
-
-
-
-## `prototype[primitive]`
-* `prototype[primitive]`
-
-
-
-
-
-## `reduce`
-* `reduce`
-
-
-
-
-
-## `reduce.prototype`
-* `reduce.prototype.clean`
-
-
-
-
-
-## `regexp`
-* `regexp`
-
-
-
-
-
-## `remove`
-* `remove`
-
-
-
-
-
-## `return`
-* `return`
-
-
-
-
-
-## `schema`
-* `schema`
-
-
-
-
-
-## `schema.prototype`
-* `schema.prototype.typeListFactory`
-* `schema.prototype.typeValidator`
-
-
-
-
-
-## `schemaFactory`
-* `schemaFactory`
-
-
-
-
-
-## `scopedEncase`
-* `scopedEncase`
-
-
-
-
-
-## `set`
-* `set`
-
-
-
-
-
-## `set$$2`
-* `set$$2`
-
-
-
-
-
-## `setChosen`
-* `setChosen`
-* `setChosen`
-
-
-
-
-
-## `simpleKindOf`
-* `simpleKindOf`
-
-
-
-
-
-## `state`
-* `state`
-
-
-
-
-
-## `stop`
-* `stop`
-
-
-
-
-
-## `test`
-* `test`
-
-
-
-
-
-## `this.extend`
-* `this.extend`
-
-
-
-
-
-## `toArr`
-* `toArr`
-
-
-
-
-
-## `toTest`
-* `toTest`
-
-
-
-
-
-## `traverse`
-* `traverse`
-* `traverse`
-
-
-
-
-
-## `traverse.prototype`
-* `traverse.prototype.eq`
-
-
-
-
-
-## `traversed`
-* `traversed`
-
-
-
-
-
-## `tryCatch`
-* `tryCatch`
-
-
-
-
-
-## `typedOnCall`
-* `typedOnCall`
-
-
-
-
-
-## `types`
-* `types`
-
-
-
-
-
-## `update`
-* `update`
-
-
-
-
-
-## `updateState`
-* `updateState`
-
-
-
-
-
-## `validators`
-* `validators`
-
-
-
-
-
-## `values`
-* `values`
-
-
-
-
-
-## `when`
-* `when`
-
-
-
-
-
-## `while`
-* `while`
-
-
-
-
-
-
-
-
-
-## `/* istanbul ignore next`
-
-
-
-# /* istanbul ignore next
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L4875 "View in source") [Ⓣ][1]
-
-unknown
-
----
-
-
-
-
-
-
-
-## `CM`
-
-
-
-* 🌊 Types: ChainedMap.d
-* 🌊 Types: ChainedMapBase.d
-
-🔬 Tests: ChainedMap
-
-# CM()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L5479 "View in source") [Ⓣ][1]
-
-(Function): ChainedMap composer
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-
-### @extends
-ChainedMapBase
-
-
-#### Since
-0.0.1
-
-#### Returns
-*(Class)*: ChainedMap
-
-#### Example
-```js
-const heh = class {}
-const composed = ChainedMap.compose(heh)
-const hehchain = new Composed()
-hehchain instanceof heh
-//=> true
-
-```
----
-
-
-
-
-
-
-
-## `Chainable.prototype`
-
-
-
-🌊 Types: Chainable.d
-
-🔬 Tests: Chainable
-
-# Chainable.prototype.Chainable
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L336 "View in source") [Ⓣ][1]
-
-(Chainable): Trait class that can inherit any class passed into compose, extended by ChainedMap & ChainedSet
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-
-### @classProps
-
-* {parent}
-* {className} {@link https://github.com/iluwatar/java-design-patterns/tree/master/chain chain-pattern}
-
----
-
-
-
-
-
-
-
-## `ChainedMapBase.prototype`
-
-
-
-🌊 Types: ChainedMapBase.d
-
-🔬 Tests: ChainedMap
-
-# ChainedMapBase.prototype.CMC
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L1726 "View in source") [Ⓣ][1]
-
-(Chainable): this is to avoid circular requires
-because MergeChain & MethodChain extend this
-yet .method & .merge use those chains
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-
-### @classProps
-
-* {meta} meta fn
-* {store} main store
-
-{@link https://ponyfoo.com/articles/es6-maps-in-depth pony-map}
-{@link https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Map mozilla-map}
-
-
-### @extends
-Chainable
-
-
-#### Since
-4.0.0-alpha.1
-
----
-
-
-
-
-
-# ChainedMapBase.prototype.cmc()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L1972 "View in source") [Ⓣ][1]
-
-(Composer): ChainedMapBase composer
-
-#### Returns
-*(Class)*: ChainedMapBase
-
-#### Example
-```js
-const heh = class {}
-const composed = ChainedMapBase.compose(heh)
-const hehchain = new Composed()
-hehchain instanceof heh
-//=> true
-
-```
----
-
-
-
-
-
-# ChainedMapBase.prototype.entries()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L1879 "View in source") [Ⓣ][1]
-
-(Function): spreads the entries from ChainedMapBase.store *(Map)* return store.entries, plus all chain properties if they exist
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-#### Since
-0.4.0
-
-#### Returns
-*(Object)*: reduced object containing all properties from the store, and when `chains` is true, all instance properties, and recursive chains
-
-
-//
-
-
-{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/entries mozilla-map-entries}
-
-#### Example
-```js
-map.set('a', 'alpha').set('b', 'beta').entries()
-//=> {a: 'alpha', b: 'beta'}
-
-```
----
-
-
-
-
-
-# ChainedMapBase.prototype.extend()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L1847 "View in source") [Ⓣ][1]
-
-(Function): shorthand methods, from strings to functions that call .set
-
-#### Since
-0.4.0
-
-#### Returns
-*(ChainedMapBase)*: @chainable
-
-#### Example
-```js
-const chain1 = new Chain()
-chain1.extend(['eh'])
-
-const chain2 = new Chain()
-chain2.eh = val => this.set('eh', val)
-
-eq(chain2.eh, chain1.eh)
-//=> true
-
-```
----
-
-
-
-
-
-# ChainedMapBase.prototype.from()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L1803 "View in source") [Ⓣ][1]
-
-(Function): checks each property of the object calls the chains accordingly
-
-
-### @todos
-
-- [ ] could also add parsing stringified
-
-#### Since
-0.5.0
-
-#### Returns
-*(Chainable)*: @chainable
-
-#### Example
-```js
-const from = new Chain().from({ eh: true })
-const eh = new Chain().set('eh', true)
-eq(from, eh)
-// => true
-
-```
----
-
-
-
-
-
-# ChainedMapBase.prototype.get()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L1915 "View in source") [Ⓣ][1]
-
-(Function): get value for key path in the Map store ❗ `debug` is a special key and is *not* included into .store it goes onto .meta
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-#### Since
-0.4.0
-
-#### Returns
-*(any)*: value in .store at key
-
-
-{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/get mozilla-map-get}
-
-#### Example
-```js
-const chain = new Chain()
-chain.set('eh', true)
-chain.get('eh')
-//=> true
-
-chain.get('nope')
-//=> undefined
-
-```
----
-
-
-
-
-
-# ChainedMapBase.prototype.set()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L1944 "View in source") [Ⓣ][1]
-
-(Function): sets the value using the key on store adds or updates an element with a specified key and value
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-#### Since
-0.4.0
-
-#### Returns
-*(ChainedMapBase)*: @chainable
-
-
-{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/set mozilla-map-set}
-
-#### Example
-```js
-const chain = new Chain()
-chain.set('eh', true)
-chain.get('eh')
-//=> true
-
-```
----
-
-
-
-
-
-# ChainedMapBase.prototype.tap()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L1779 "View in source") [Ⓣ][1]
-
-(Function): tap a value with a function
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-#### Since
-4.0.0-alpha.1 <- moved from transform & shorthands
-
-#### Returns
-*(Chain)*: @chainable
-
-
-{@link https://github.com/sindresorhus/awesome-tap awesome-tap}
-{@link https://github.com/midknight41/map-factory map-factory}
-{@link https://github.com/webpack/tapable tapable}
-
-#### Example
-```js
-chain
- .set('moose', { eh: true })
- .tap('moose', moose => {
- moose.eh = false
- return moose
- })
- .get('moose')
-
-// => {eh: false}
-
-```
-#### Example
-```js
-const entries = new Chain()
- .set('str', 'emptyish')
- .tap('str', str => str + '+')
- .set('arr', [1])
- .tap('arr', arr => arr.concat([2]))
- .entries()
-
-//=> {str: 'emptyish+', arr: [1, 2]}
-
-```
----
-
-
-
-
-
-
-
-## `ChainedSet`
-
-
-
-🌊 Types: ChainedSet.d
-
-🔬 Tests: ChainedSet
-
-# ChainedSet
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L5593 "View in source") [Ⓣ][1]
-
-Set
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-
-### @notes
-
-* had Symbol.isConcatSpreadable but it was not useful
-
-
-### @todos
-
-- [ ] could add .first .last ?
-
-
-### @classProps
-
-* {store}
-
-
-### @extends
-Chainable
-
-
----
-
-
-
-
-
-
-
-## `DotProp.prototype`
-
-
-
-# DotProp.prototype.get()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L7478 "View in source") [Ⓣ][1]
-
-(Function): dot-prop enabled get
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-
-### @todos
-
-- [ ] dot-prop on non-store instance.property when using nested chains...
-
-#### Since
-3.0.1
-
-#### Returns
-*(any)*: value for path, or fallback value if provided
-
-#### Example
-```js
-chain.set('moose.simple', 1)
-//=> Chain
-
-chain.get('moose.simple')
-//=>1
-
-chain.get('moose')
-//=> {simple: 1}
-
-```
-#### Example
-```js
-//also works with an array (moose.simple)
-chain.get(['moose', 'simple'])
-//=> 1
-
-```
----
-
-
-
-
-
-# DotProp.prototype.set
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L7420 "View in source") [Ⓣ][1]
-
-unknown
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-#### Since
-3.0.1
-
-#### Example
-```js
-const chain = new Target()
-
-chain.set('moose.simple', 1)
-//=> Target store:Map: { moose: { simple: 1 } }
-
-```
----
-
-
-
-
-
-
-
-## `FactoryChain.prototype`
-
-
-
-🌊 Types: FactoryChain.d
-
-🔬 Tests: FactoryChain
-
-# FactoryChain.prototype.FactoryChain
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L5697 "View in source") [Ⓣ][1]
-
-Map
-
-
-### @classProps
-
-* {data}
-* {_calls}
-
-
-### @extends
-ChainedMapBase
-
-
----
-
-
-
-
-
-# FactoryChain.prototype.chainUpDowns()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L5758 "View in source") [Ⓣ][1]
-
-(Function): chain back up to parent for any of these
-
-
-### @todos
-
-- [ ] should have a debug log for this
-
-#### Since
-2.0.0
-
-#### Returns
-*(FactoryChain)*: @chainable
-
-#### Example
-```js
-const { Chain, FactoryChain, ChainedSet } = require('chain-able')
-
-class Things extends Chain {
- constructor(parent) {
- super(parent)
- this.people = new ChainedSet(this)
- }
- person() {
- const person = new FactoryChain(this)
- person
- .props(['name', 'age', 'email'])
- .onChainUpDown(this.person)
- .chainUpDowns(['person'])
- .onDone(personChain => {
- this.people.add(personChain)
- return this
- })
-
- return person
- }
-}
-
-const things = new Things()
-const returned = things
- .person()
- .name('sue')
- .person()
- .age(100)
- .name('john')
- .email('@')
-
-```
----
-
-
-
-
-
-# FactoryChain.prototype.factory()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L5908 "View in source") [Ⓣ][1]
-
-(Function): creates/add the `.end` method, which checks how many methods have been called, and decides whether to return parent or not
-
-#### Since
-2.0.0
-
-#### Returns
-*(FactoryChain)*: @chainable
-
----
-
-
-
-
-
-# FactoryChain.prototype.getData()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L5889 "View in source") [Ⓣ][1]
-
-(Function): access data being built when stepping through a factory
-
-#### Since
-2.0.0
-
-#### Returns
-*(any)*: this.data
-
-#### Example
-```js
-.data['prop'] = 'eh'
- .getData('prop')
- //=> 'eh'
- .getData()
- //=> {prop: 'eh'}
-```
-#### Example
-```js
-const person = new FactoryChain(this)
-const age = person.props(['name', 'age']).age(10).getData('age')
-expect(age).toBe(10)
-
-```
----
-
-
-
-
-
-# FactoryChain.prototype.prop()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L5829 "View in source") [Ⓣ][1]
-
-(Function): add property that are counted towards the call count for easy auto-ending chaining
-
-#### Since
-2.0.0
-
-#### Returns
-*(FactoryChain)*: @chainable
-
-#### Example
-```js
-person
- //.prop also accepts an optional callback,
- //for nestable nestable chains
- .prop('name')
- .prop('age')
- .prop('email')
-
-```
----
-
-
-
-
-
-# FactoryChain.prototype.props()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L5801 "View in source") [Ⓣ][1]
-
-(Function): adds an *array* of properties, using FactoryChain.prop
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-#### Since
-2.0.0
-
-#### Returns
-*(FactoryChain)*: @chainable
-
-#### Example
-```js
-person.props(['name', 'age', 'email'])
-
-typeof person.name
-//=> 'function'
-
-person.name().age()
-//=> FactoryChain
-
-person.name().age().email()
-//=> ParentChain
-
-// person.name().age().person()
-//=> FactoryChain
-//^ because .person is `chainUpDowns`
-//^ so it finishes the old chain, and begins a new one
-
-```
----
-
-
-
-
-
-
-
-## `MergeChain.prototype`
-
-
-
-🔬 Tests: MergeChain
-
-# MergeChain.prototype.MergeChain
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L5162 "View in source") [Ⓣ][1]
-
-Map
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-
-### @todos
-
-- [ ] consider just making this a function,
- because 80/20 onValue merger & onExisting
- are rarely used & are easily overridable with .merge
-
-
-### @extends
-ChainedMapBase
-
-
-#### Since
-1.0.0
-
----
-
-
-
-
-
-# MergeChain.prototype.init()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L5199 "View in source") [Ⓣ][1]
-
-(Function): options for merging with dopemerge
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-#### Since
-1.0.2
-
-#### Returns
-*(MergeChain)*: @chainable
-
-#### Example
-```js
-{
- stringToArray: true,
- boolToArray: false,
- boolAsRight: true,
- ignoreTypes: ['null', 'undefined', 'NaN'],
- debug: false,
- }
-```
-#### Example
-```js
-.merger(require('lodash.mergewith')())
-```
----
-
-
-
-
-
-# MergeChain.prototype.MergeChain_1
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L5447 "View in source") [Ⓣ][1]
-
-unknown
-
-#### Since
-0.9.0
-
-#### Example
-```js
-const { Chain, MergeChain } = require('chain-able')
-
-const chain = new Chain().set('str', 'stringy')
-
-MergeChain.init(chain).onExisting((a, b) => a + b).merge({ str: '+' })
-
-chain.get('str')
-//=> 'stringy+'
-
-```
----
-
-
-
-
-
-
-
-## `MethodChain.prototype`
-
-
-
-🌊 Types: MethodChain.d
-
-🔬 Tests: MethodChain
-
-# MethodChain.prototype.MethodChain
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L4410 "View in source") [Ⓣ][1]
-
-(Map): ❗ using `+` will call `.build()` in a shorthand fashion
-
-
-### @todos
-
-- [ ] maybe abstract the most re-usable core as a protected class
- so the shorthands could be used, and more functionality made external
-- [ ] need to separate schema from here as external functionality & add .add
-- [ ] .prop - for things on the instance, not in the store?
- !!! .sponge - absorn properties into the store
-
-
-### @extends
-ChainedMap
-
-
-#### Since
-4.0.0
-
----
-
-
-
-
-
-# MethodChain.prototype._build()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L4748 "View in source") [Ⓣ][1]
-
-Function
-
-
-### @notes
-
-* scoping here adding default functions have to rescope arguments
-
-
-### @todos
-
-- [ ] allow config of method var in plugins since it is scoped...
-- [ ] add to .meta(shorthands)
-- [ ] reduce complexity if perf allows
-
-#### Since
-4.0.0-alpha.1
-
-#### Returns
-*(void)*:
-
----
-
-
-
-
-
-# MethodChain.prototype._defaults()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L4708 "View in source") [Ⓣ][1]
-
-Function
-
-
-### @todos
-
-- [ ] optimize the size of this
- with some bitwise operators
- hashing the things that have been defaulted
- also could be plugin
-
-#### Since
-4.0.0
-
-#### Returns
-*(void)*:
-
-#### Example
-```js
-._defaults('', {}, {})
-```
-#### Example
-```js
-let methodFactories
-
- ### `onSet`
-
- > defaults to `this.set(key, value)`
-
- ```ts
- public onSet(fn: Fn): MethodChain
- ```
-
- ### `onCall`
-
- > defaults to .onSet ^
-
- ```ts
- public onCall(fn: Fn): MethodChain
- ```
-
- ### `onGet`
-
- > defaults to `this.get(key)`
-
- ```ts
- public onGet(fn: Fn): MethodChain
- ```
-```
----
-
-
-
-
-
-# MethodChain.prototype.autoGetSet()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L4183 "View in source") [Ⓣ][1]
-
-Function
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-#### Returns
-*(MethodChain)*: @chainable
-
-#### Example
-```js
-const chain = new Chain()
-chain.methods('eh').plugin(autoGetSet).build()
-
-chain.eh(1)
-//=> Chain
-chain.eh()
-//=> 1
-
-```
----
-
-
-
-
-
-# MethodChain.prototype.autoIncrement()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L5054 "View in source") [Ⓣ][1]
-
-(Function): adds a plugin to increment the value on every call
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-#### Since
-0.4.0
-
-#### Returns
-*(MethodChain)*: @chainable
-
-#### Example
-```js
-chain.methods(['index']).autoIncrement().build().index().index(+1).index()
-chain.get('index')
-//=> 3
-
-```
----
-
-
-
-
-
-# MethodChain.prototype.build()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L4634 "View in source") [Ⓣ][1]
-
-(Function): set the actual method, also need .context - use .parent
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-
-### @todos
-
-- [ ] if passing in a name that already exists, operations are decorations... (partially done)
-
-#### Since
-4.0.0
-
-#### Returns
-*(MethodChain)*: @chainable
-
-#### Example
-```js
-var obj = {}
-const one = new MethodChain(obj).methods('eh').getSet().build(1)
-//=> 1
-
-typeof obj.getEh
-//=> 'function'
-
-```
----
-
-
-
-
-
-# MethodChain.prototype.decorate()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L4128 "View in source") [Ⓣ][1]
-
-(Function): decorates a parent when the argument is provided
-BUT THE FUNCTIONS WILL STILL BE SCOPED TO CURRENT PARENT
-for easy factory chaining
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-
-### @todos
-
-- [ ] this is more like a preset since it *adds* plugins?
- more of methodFactory now
-
-#### Since
-4.0.0-alpha.1
-
-#### Returns
-*(MethodChain)*: @chainable
-
-#### Example
-```js
-const chain = new Chain()
-const obj = {}
-chain.method('ehOh').decorate(obj).build()
-typeof obj.ehOh
-//=> 'function'
-
-```
----
-
-
-
-
-
-# MethodChain.prototype.decorate()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L5023 "View in source") [Ⓣ][1]
-
-(Function): add methods to the parent for easier chaining
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-#### Returns
-*(ChainedMap)*: @chainable
-
-#### Example
-```js
-var obj = {}
-new MethodChain({}).name('eh').decorate(obj).build()
-typeof obj.eh
-//=> 'function'
-
-```
-#### Example
-```js
-class Decorator extends Chain {
- constructor(parent) {
- super(parent)
- this.methods(['easy']).decorate(parent).build()
- this.methods('advanced')
- .onCall(this.advanced.bind(this))
- .decorate(parent)
- .build()
- }
- advanced(arg) {
- this.set('advanced', arg)
- return this.parent
- }
- easy(arg) {
- this.parent.set('easy-peasy', arg)
- }
-}
-
-class Master extends Chain {
- constructor(parent) {
- super(parent)
- this.eh = new Decorator(this)
- }
-}
-
-const master = new Master()
-
-master.get('easy-peasy')
-//=> true
-
-master.eh.get('advanced')
-//=> 'a+'
-
-```
-#### Example
-```js
-;+chain.method('ehOh').decorate(null)
-//=> @throws Error('must provide parent argument')
-
-```
----
-
-
-
-
-
-# MethodChain.prototype.name()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L4526 "View in source") [Ⓣ][1]
-
-(Function): setup methods to build
-
-#### Returns
-*(MethodChain)*: @chainable
-
-#### Example
-```js
-var obj = {}
-new MethodChain(obj).name('eh').build()
-typeof obj.eh
-//=> 'function'
-
-```
----
-
-
-
-
-
-# MethodChain.prototype.schema()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L4609 "View in source") [Ⓣ][1]
-
-(Function): an object that contains nestable `.type`s
-they are recursively *(using an optimized traversal cache)* mapped to validators
-❗ this method auto-calls .build, all other method config calls should be done before it
-
-
-### @todos
-
-- [ ] link to `deps/is` docs
-- [ ] move out into a plugin to show how easy it is to use a plugin
- and make it able to be split out for size when needed
-- [ ] inherit properties (in plugin, for each key)
- from this for say, dotProp, getSet
-- [ ] very @important
- that we setup schema validation at the highest root for validation
- and then have some demo for how to validate on set using say mobx
- observables for all the way down...
-
-#### Since
-4.0.0
-
-#### Returns
-*(MethodChain)*: @chainable
-
-#### Example
-```js
-chain
- .methods()
- .define()
- .getSet()
- .onInvalid((error, arg, instance) => console.log(error))
- .schema({
- id: '?number',
- users: '?object|array',
- topic: '?string[]',
- roles: '?array',
- creator: {
- name: 'string',
- email: 'email',
- id: 'uuid',
- },
- created_at: 'date',
- updated_at: 'date|date[]',
- summary: 'string',
- })
-
-//--- valid
-chain.created_at = new Date()
-chain.setCreatedAt(new Date())
-
-isDate(chain.created_at) === true
-
-//--- nestable validation 👍
-chain.merge({ creator: { name: 'string' } })
-
-//--- invalid
-chain.updated_at = false
-
-```
----
-
-
-
-
-
-
-
-## `Observe.prototype`
-
-
-
-# Observe.prototype.observe()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L6564 "View in source") [Ⓣ][1]
-
-(Function): observe properties when they change
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-
-### @todos
-
-- [ ] gotta update `data` if `deleting` too...
-- [ ] un-observe
-- [ ] should hash these callback properties
-- [ ] just throttle the `.set` to allow easier version of .commit
-
-#### Returns
-*(Target)*: @chainable
-
-#### Example
-```js
-const Target = require('chain-able')
-
-const chain = new Target()
-const log = arg => console.log(arg)
-
-chain.extend(['eh']).observe('eh', data => log(data)).eh(true)
-//=> {eh: true}
-
-```
-#### Example
-```js
-chain
- .extend(['canada', 'timbuck'])
- .observe(['canad*'], data => console.log(data.canada))
- .canada(true)
- .canada(true)
- .timbuck(false)
-
-//=> true
-//=> false
-
-// only called when changed,
-// otherwise it would be 2 `true` & 1 `false`
-
-```
----
-
-
-
-
-
-🔬 Tests: DotProp
-
-# Observe.prototype.DotProp()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L7367 "View in source") [Ⓣ][1]
-
-Function
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-
-### @extends
-ChainedMap
-
-
-#### Returns
-*(DotProp)*: class
-
-#### Example
-```js
-const { compose } = require('chain-able')
-const { DotProp } = compose
-new DotProp()
-//=> DotProp
-
-```
-#### Example
-```js
-const chain = new Chain()
-
-chain.set('moose.simple', 1)
-//=> Chain
-
-chain.get('moose.simple')
-//=>1
-
-chain.get('moose')
-//=> {simple: 1}
-
-chain.set('moose.canada.eh', true).set('moose.canada.igloo', true)
-//=> Chain
-
-//set, has, get, delete :-)
-chain.delete('moose.canada.eh')
-//=> Chain
-
-//also works with an array (moose.canada.igloo)
-chain.get(['moose', 'canada', 'igloo'])
-//=> true
-
-```
----
-
-
-
-
-
-🔬 Tests: observe
-
-# Observe.prototype.Observe()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L6508 "View in source") [Ⓣ][1]
-
-(Function): > subscribe to changes ❗ called only on **change** observers are only called when data they subscribe to changes
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-
-### @extends
-
-* ChainedMap
-* DotProp
-
-
-#### Since
-3.0.1
-
-#### Returns
-*(Observe)*: class
-
-#### Example
-```js
-const { compose } = require('chain-able')
-const { DotProp } = compose
-new DotProp()
-//=> DotProp
-
-```
----
-
-
-
-
-
-
-
-## `ShorthandChain.prototype`
-
-
-
-# ShorthandChain.prototype.return()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L6790 "View in source") [Ⓣ][1]
-
-(Function): returns any value passed in return a value at the end of a chain regardless
-
-#### Since
-3.0.0
-
-#### Returns
-*(any)*: value
-
-#### Example
-```js
-const chain = new Chain()
-
-const saveAndDebug = env =>
- chain.from({ env: env.NODE_ENV }).return(JSON.stringify(env))
-
-console.log(saveAndDebug(process.env))
-//=> value of process.env
-
-```
----
-
-
-
-
-
-# ShorthandChain.prototype.setIfEmpty()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L6764 "View in source") [Ⓣ][1]
-
-(Function): sets a value **only** when .has is false aka set if the value has not been set
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-#### Since
-1.0.2
-
-#### Returns
-*(ShorthandChain)*: @chainable
-
-#### Example
-```js
-const chain = new Chain()
-
-chain.set('eh', true)
-
-// eh is already set ^, ignored
-chain.setIfEmpty('eh', false)
-
-chain.get('eh')
-//=> true
-
-```
-#### Example
-```js
-new Chain().setIfEmpty('canada', true).entries()
-//=> {canada: true}
-
-```
-#### Example
-```js
-// longhand way to do the same thing
-if (chain.has('eh') === false) {
- chain.set('eh', false)
-}
-
-// or using .when
-chain.when(!chain.has('eh'), instance => instance.set('eh', false))
-
-```
----
-
-
-
-
-
-# ShorthandChain.prototype.wrap()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L6823 "View in source") [Ⓣ][1]
-
-(Function): wrap a value, if it's a Function call it, return this aka execute something and return this
-
-#### Since
-2.0.0
-
-#### Returns
-*(ShorthandChain)*: @chainable
-
-#### Example
-```js
-const { eh } = chain.wrap(chain => (chain.eh = true))
-//=> true
-
-```
-#### Example
-```js
-new Chain()
- .wrap(
- encased =>
- (encased.fn = arg => {
- throw new Error('encased yo')
- })
- )
- .method('fn')
- .encase()
- .catch(error => {
- //=> Error('encasedYo')
- })
- .build()
- .fn(true)
-
-```
----
-
-
-
-
-
-
-
-## `Transform`
-
-
-
-
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L7089 "View in source") [Ⓣ][1]
-
-Function
-
-#### Returns
-*(TransformChain)*: class
-
-#### Example
-```js
-compose(class {})
-//=> TransformChain
-
-```
----
-
-
-
-
-
-
-
-## `TransformChain.prototype`
-
-
-
-🔬 Tests: TransformChain
-
-
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L7111 "View in source") [Ⓣ][1]
-
-Map
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-
-### @symb
-
-🤖
-
-### @extends
-ChainedMap
-
-
----
-
-
-
-
-
-
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L7258 "View in source") [Ⓣ][1]
-
-(Function): remap properties from `1` to another, for example, apis with inconsistent naming
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-
-### @symb
-
-🗺
-#### Since
-1.0.0
-
-#### Returns
-*(Chain)*: @chainable
-
-#### Example
-```js
-chain.remap('dis', 'dat').from({ dis: true })
-
-chain.entries()
-//=> {dat: true}
-
-```
-#### Example
-```js
-chain
- .remap({dis: 'dat'})
- .from({dis: 1, other: true}}
-
- chain.entries()
- //=> {dist: 1, other: true}
-```
----
-
-
-
-
-
-
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L7197 "View in source") [Ⓣ][1]
-
-Function
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-#### Since
-1.0.0
-
-#### Returns
-*(Chainable)*: @chainable
-
----
-
-
-
-
-
-
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L7179 "View in source") [Ⓣ][1]
-
-Function
-
-
-### @todos
-
-- [ ] dot-prop here
-
-#### Since
-1.0.2
-
-#### Returns
-*(TransformChain)*: @chainable
-
-#### Example
-```js
-// coerce values with .id into the value they hold
-chain.transform('dis', val => (typeof val === 'string' ? val : val.id))
-
-chain.set('dis', 'eh')
-chain.get('dis')
-//=> 'eh'
-
-chain.set('dis', { id: 'eh' })
-chain.get('dis')
-//=> 'eh'
-
-```
-#### Example
-```js
-import { format } from 'date-fns/esm'
-import { Chain } from 'chain-able'
-
-const chain = new Chain()
-chain.transform('created_at', date => format(date, 'MM/DD/YYYY'))
-chain.set('created_at', new Date())
-
-// is formatted human-readable pretty!
-const { created_at } = chain.entries()
-//=> '02/11/2014'
-
-```
----
-
-
-
-
-
-
-
-## `Traverse.prototype`
-
-
-
-* 🌊 Types: TraverseChain.d
-* 🌊 Types: traverse.d
-
-* 🔬 Tests: circular
-* 🔬 Tests: date
-* 🔬 Tests: equal
-* 🔬 Tests: error
-* 🔬 Tests: has
-* 🔬 Tests: index
-* 🔬 Tests: instance
-* 🔬 Tests: interface
-* 🔬 Tests: json
-* 🔬 Tests: keys
-* 🔬 Tests: leaves
-* 🔬 Tests: negative
-* 🔬 Tests: obj
-* 🔬 Tests: set-map
-* 🔬 Tests: siblings
-* 🔬 Tests: stop
-* 🔬 Tests: stringify
-* 🔬 Tests: subexpr
-* 🔬 Tests: superDeep
-
-# Traverse.prototype.Traverse()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2211 "View in source") [Ⓣ][1]
-
-Function
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-
-### @todos
-
-- [ ] : symbol, map, set
-
-
-### @classProps
-
-* {value} the data passed in as an argument to traverse on
-
-#### Example
-```js
-traverse({})
-//=> Traverser
-
-```
----
-
-
-
-
-
-# Traverse.prototype.map()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2319 "View in source") [Ⓣ][1]
-
-(Function): Execute fn for each node in the object and return a new object with the results of the walk. To update nodes in the result use this.update(value).
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-#### Returns
-*(any)*:
-
-#### Example
-```js
-var { traverse } = require('chain-able')
-
-var obj = { a: 1, b: 2, c: [3, 4] }
-obj.c.push(obj)
-
-var scrubbed = traverse(obj).map(function(x) {
- if (this.circular) this.remove()
-})
-console.dir(scrubbed)
-//=> { a: 1, b: 2, c: [ 3, 4 ] }
-
-```
----
-
-
-
-
-
-🌊 Types: TraverseChain.d
-
-🔬 Tests: TraverseChain
-
-# Traverse.prototype.TraverseChain
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L6931 "View in source") [Ⓣ][1]
-
-Map
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-
-### @symb
-
-👣
-
-### @classProps
-
-* {obj}
-* {keys}
-* {vals}
-* {onMatch}
-* {onNonMatch}
-* {clone}
-
-
-### @extends
-ChainedMapBase
-
-
-#### Since
-1.0.0
-
----
-
-
-
-
-
-# Traverse.prototype.clone()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2439 "View in source") [Ⓣ][1]
-
-(Function): Create a deep clone of the object.
-
-#### Returns
-*(any)*:
-
-#### Example
-```js
-const { traverse, eq } = require('chain-able')
-
-const obj = { eh: true, canada: [1] }
-const cloned = traverse(obj).clone()
-cloned.eh = false
-eq(cloned, obj)
-//=> false
-
-```
----
-
-
-
-
-
-# Traverse.prototype.forEach()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2346 "View in source") [Ⓣ][1]
-
-(Function): Execute fn for each node in the object but unlike .map(), when this.update() is called it updates the object in-place. executes a provided function once for each traversed element.
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-#### Returns
-*(any)*: this.value
-
-#### Example
-```js
-var { traverse } = require('chain-able')
-
-var obj = [5, 6, -3, [7, 8, -2, 1], { f: 10, g: -13 }]
-traverse(obj).forEach(function(x) {
- if (x < 0) this.update(x + 128)
-})
-
-console.dir(obj)
-//=> [ 5, 6, 125, [ 7, 8, 126, 1 ], { f: 10, g: 115 } ]
-
-```
----
-
-
-
-
-
-# Traverse.prototype.get()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2225 "View in source") [Ⓣ][1]
-
-(Function): Get the element at the array path.
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-
-### @todos
-
-- [ ] hasOwnProperty
-
-#### Returns
-*(any)*: value at dot-prop
-
----
-
-
-
-
-
-# Traverse.prototype.has()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2264 "View in source") [Ⓣ][1]
-
-(Function): Return whether the element at the array path exists.
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-#### Returns
-*(boolean)*: has element at path
-
-#### Example
-```js
-traverse({ eh: true }).has(['eh'])
-//=> true
-
-```
-#### Example
-```js
-traverse({ eh: true }).has(['canada'])
-//=> false
-
-```
-#### Example
-```js
-traverse([0]).has([2])
-//=> false
-
-```
----
-
-
-
-
-
-# Traverse.prototype.nodes()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2414 "View in source") [Ⓣ][1]
-
-(Function): Return an Array of every node in the object.
-
-#### Returns
-*(*)*:
-
----
-
-
-
-
-
-🔬 Tests: keys
-
-# Traverse.prototype.paths()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2401 "View in source") [Ⓣ][1]
-
-(Function): Return an Array of every possible non-cyclic path in the object. Paths are Arrays of string keys.
-
-#### Returns
-*(*)*:
-
----
-
-
-
-
-
-# Traverse.prototype.reduce()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2384 "View in source") [Ⓣ][1]
-
-(Function): applies a function against an accumulator and each element in the array *(from left to right)* to reduce it to a single value. calls cb for each loop that is .notRoot defaults initial value to `this.value`
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-#### Returns
-*(*)*:
-
-#### Example
-```js
-var { traverse } = require('chain-able')
-
-var obj = {
- a: [1, 2, 3],
- b: 4,
- c: [5, 6],
- d: { e: [7, 8], f: 9 },
-}
-
-var leaves = traverse(obj).reduce(function(acc, x) {
- if (this.isLeaf) acc.push(x)
- return acc
-}, [])
-
-console.dir(leaves)
-//=> [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
-
-```
----
-
-
-
-
-
-# Traverse.prototype.set()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2286 "View in source") [Ⓣ][1]
-
-(Function): Set the element at the array path to value.
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-#### Returns
-*(any)*: value passed in
-
----
-
-
-
-
-
-
-
-## `TraverseChain.prototype`
-
-
-
-# TraverseChain.prototype.traverse()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L6987 "View in source") [Ⓣ][1]
-
-(Function): runs traverser, checks the tests, calls the onMatch
-
-#### Since
-1.0.0
-
-#### Returns
-*(any)*: this.obj/data cleaned
-
-#### Example
-```js
-const traversed = new Chain()
- .merge({ flat: 0, one: { two: true } })
- .traverse(false)
- .vals([/true/])
- .onMatch((current, traverser) => {
- traverser.path.join('.')
- //=> 'one.two'
-
- current
- //=> true
-
- typeof traverser.update === typeof traverser.remove
- typeof traverser.update === 'function'
- //=> true
-
- traverser.remove()
- //=> void
- })
- .onNonMatch(val => {
- // ignore
- })
- .call(true)
-
-traversed
-//=> {flat: 0}
-
-```
----
-
-
-
-
-
-
-
-## `add`
-
-
-
-# add()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L5091 "View in source") [Ⓣ][1]
-
-(Function): add methodFactories easily
-
-#### Since
-4.0.0-beta.2
-
-#### Returns
-*(void)*:
-
-#### Example
-```js
-function autoGetSet(name, parent) {
- const auto = arg =>
- isUndefined(arg) ? parent.get(name) : parent.set(name, arg)
-
- //so we know if we defaulted them
- auto.autoGetSet = true
- return this.onSet(auto).onGet(auto).onCall(auto)
-}
-MethodChain.addPlugin({ autoGetSet })
-
-const chain = new Chain()
-chain.methods('eh').autoGetSet().build()
-
-chain.eh(1)
-//=> chain
-chain.eh()
-//=> 1 *
-
-```
----
-
-
-
-
-
-# add()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L5620 "View in source") [Ⓣ][1]
-
-(Function): appends a new element with a specified value to the end of the .store
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-#### Since
-0.4.0
-
-#### Returns
-*(ChainedSet)*: @chainable
-
-#### Example
-```js
-const people = new ChainedSet()
-people.add('sam').add('sue')
-
-for (let name of people) console.log(name)
-//=> sam, sue
-
-```
----
-
-
-
-
-
-
-
-## `addTypes`
-
-
-
-🌊 Types: schema.d
-
-# addTypes
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L3323 "View in source") [Ⓣ][1]
-
-unknown
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-#### Example
-```js
-addTypes({ yaya: x => typeof x === 'string' })
-
-const chain = new Chain().methods('eh').type('yaya').build()
-
-chain.eh('good')
-//=> chain
-
-chain.eh(!!'throws')
-//=> TypeError(false != {yaya: x => typeof x === 'string'})
-
-```
-#### Example
-```js
-const custom = {}
-custom.enums = enums => x => enums.includes(x)
-custom['*'] = x => true
-addTypes(custom)
-//-> void
-
-new Chain().methods('eh').type('*').build().eh
-//=> validateType(custom['*'])
-
-```
----
-
-
-
-
-
-
-
-## `after`
-
-
-
-# after()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2605 "View in source") [Ⓣ][1]
-
-(Function): Call this function after any of the children are traversed.
-
-#### Returns
-*(any)*:
-
----
-
-
-
-
-
-
-
-## `alias`
-
-
-
-# alias()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L4476 "View in source") [Ⓣ][1]
-
-(Function): alias methods
-
-
-### @notes
-
-* these would be .transform
-
-#### Since
-2.0.0
-
-#### Returns
-*(MethodChain)*: @chainable
-
-#### Example
-```js
-const chain = new Chain()
-chain.methods(['canada']).alias(['eh']).build()
-chain.eh('actually...canada o.o')
-chain.get('canada')
-//=> 'actually...canada o.o')
-
-```
----
-
-
-
-
-
-
-
-## `allProperties`
-
-
-
-# allProperties()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L4221 "View in source") [Ⓣ][1]
-
-(Function): properties, property symbols, object keys ^ all again for prototype
-
-#### Returns
-*(*)*: properties
-
-#### Example
-```js
-var obj = { key: true }
-allProperties(obj)
-//=> ['key']
-
-```
-#### Example
-```js
-class One {
- method() {}
-}
-class Two extends One {
- eh() {}
-}
-allProperties(new Two())
-//=> ['eh', 'method']
-
-```
----
-
-
-
-
-
-
-
-## `anyKeyVal`
-
-
-
-🌊 Types: matcher.d
-
-# anyKeyVal()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L6898 "View in source") [Ⓣ][1]
-
-(Function): the original simple to-test matcher for traversable,
-will be merged into, or simplified as simplified into matcher
-
-
-### @todos
-
-- [ ] should use matcher,
-- [ ] should inprove the callback data...
-
-#### Since
-2.0.0
-
-#### Returns
-*(boolean)*: matched or not
-
-#### Example
-```js
-anyKeyVal([], [])(0, 0)
-//=> false
-
-anyKeyVal([() => true], [])(0, 0)
-//=> true
-
-```
----
-
-
-
-
-
-
-
-## `argumentor`
-
-
-
-# argumentor()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2108 "View in source") [Ⓣ][1]
-
-(Function): turns arguments into an array, used as a util, for opt
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-#### Since
-3.0.0
-
-#### Returns
-*(*)*:
-
-#### Example
-```js
-function eh() {
- const args = argumentor.apply(null, arguments).slice(1)
-
- console.log(args)
- //=> [1, 10, 100]
-}
-eh(0, 1, 10, 100)
-
-```
----
-
-
-
-
-
-
-
-## `arithmeticTypeFactory`
-
-
-
-🌊 Types: schema.d
-
-# arithmeticTypeFactory()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L3429 "View in source") [Ⓣ][1]
-
-(Function): transform arithmetic strings into types
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-
-### @todos
-
-- [ ] coercing values to certain types: arithmeticTypeFactory('')
-
-#### Since
-4.0.0-alpha.1
-
-#### Returns
-*(Matchable)*: function to match with, with .inspect for easy debugging
-
-#### Example
-```js
-arithmeticTypeFactory('?string')
-//=> x => !isReal(x) || isString(x)
-
-```
-#### Example
-```js
-arithmeticTypeFactory('?string|string[]')
-//=> x => isString(x) || isArrayOf(isString)(x)
-
-```
-#### Example
-```js
-arithmeticTypeFactory('!string')
-//=> x => not(isString)(x)
-
-```
-#### Example
-```js
-types.addTypes({ star: x => true })
-arithmeticTypeFactory('object|function|star')
-//=> x => isObj(x) || isFunction(x) || isStar(x)
-
-```
-#### Example
-```js
-arithmeticTypeFactory('===')
-//=> x => (['===']).includes(x)
-
-```
----
-
-
-
-
-
-
-
-## `autoIncrement`
-
-
-
-# autoIncrement()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L4158 "View in source") [Ⓣ][1]
-
-Function
-
-#### Returns
-*(MethodChain)*: @chainable
-
----
-
-
-
-
-
-
-
-## `before`
-
-
-
-# before()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2597 "View in source") [Ⓣ][1]
-
-(Function): Call this function before any of the children are traversed.
-You can assign into this.keys here to traverse in a custom order.
-
-#### Returns
-*(any)*:
-
----
-
-
-
-
-
-
-
-## `block`
-
-
-
-# block()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2637 "View in source") [Ⓣ][1]
-
-Function
-
-#### Returns
-*(void)*:
-
----
-
-
-
-
-
-
-
-## `builder`
-
-
-
-# builder()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L3494 "View in source") [Ⓣ][1]
-
-(Function): @pattern @builder -> builds using multiple factories depending on conditons or abstractFactory whatever opinionated: if it's a function, it's a validator...
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-
-### @notes
-
-* if/else is for uglifying ternaries, even though else if is not needed
-* if key is number, iterating the array
-
-#### Since
-4.0.0
-
-#### Returns
-*(Function)*: validator
-
-#### Example
-```js
-// functionType
-const isString = x => typeof x === 'string'
-builder(isString)
-// => isString
-
-```
-#### Example
-```js
-// stringType (built in, or custom-keyed validator, or eqeqeq)
-builder('string')
-// => isString
-
-const enummy = builder('enum')
-// => x => ['enum'].includes(x)
-
-```
-#### Example
-```js
-// arithmeticType
-builder('string|string[]')
-// => isString || isArrayOf(isString)
-
-```
----
-
-
-
-
-
-
-
-## `camelCase`
-
-
-
-# camelCase()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L3147 "View in source") [Ⓣ][1]
-
-(Function): camelCase
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-
-### @todos
-
-- [ ] s.charAt(0).toLowerCase() + string.slice(1)
-
-#### Since
-0.2.0
-
-#### Returns
-*(string)*: camelCased string
-
-#### Example
-```js
-camelCase('snake_case')
-//=> 'snakeCase'
-
-```
----
-
-
-
-
-
-
-
-## `circular`
-
-
-
-# circular
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2547 "View in source") [Ⓣ][1]
-
-unknown
-
----
-
-
-
-
-
-
-
-## `clear`
-
-
-
-# clear()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L505 "View in source") [Ⓣ][1]
-
-(Function): clears the map, goes through this properties, calls .clear if they are instanceof Chainable or Map
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-#### Returns
-*(Chainable)*: @chainable
-
-#### Example
-```js
-const chain = new Chain()
-chain.set('eh', 1)
-chain.entries()
-//=> {eh: 1}
-chain.clear()
-chain.entries()
-//=> {}
-
-```
----
-
-
-
-
-
-
-
-## `compose.prototype`
-
-
-
-🌊 Types: compose.d
-
-🔬 Tests: compose
-
-# compose.prototype.compose()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L7603 "View in source") [Ⓣ][1]
-
-(Function): compose chains all the way up from Chainable
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-
-### @symb
-
-🎼
-#### Since
-3.0.0
-
-#### Returns
-*(*)*: composed
-
-#### Example
-```js
-class Eh extends compose() {}
-new Eh() instanceof Chainable
-//=> true
-
-```
-#### Example
-```js
-class Target {}
-class Eh extends compose(Target) {}
-new Eh() instanceof Target
-//=> true
-
-```
-#### Example
-```js
-class Target {}
-const mixin = SuperClass => class extends SuperClass {}
-class Eh extends compose(Target) {}
-new Eh() instanceof Chainable
-//=> true
-
-```
-#### Example
-```js
-class Winning {}
-class Yes extends compose(Winning) {
- get winning() {
- return true
- }
-}
-const yes = new Yes()
-yes instanceof Winning && yes.winning
-//=> true
-
-```
----
-
-
-
-
-
-
-
-## `conditional.prototype`
-
-
-
-# conditional.prototype.all()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L3241 "View in source") [Ⓣ][1]
-
-(Function): map all values in an array to see if all match
-
-#### Since
-4.0.1
-
-#### Returns
-*(boolean)*: all match predicate
-
-#### Example
-```js
-const allBoolean = all(x => typeof x === 'boolean'q)
-
- allBoolean([true])
- //=> true
-
- allBoolean([1])
- //=> false
-```
----
-
-
-
-
-
-# conditional.prototype.and()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L3197 "View in source") [Ⓣ][1]
-
-(Function): first fn & second fn
-
-#### Since
-4.0.1
-
-#### Returns
-*(boolean)*: both functions return truthy
-
-#### Example
-```js
-const both = and(x => typeof x === 'boolean', x => x === true)
-
-both([true])
-//=> true
-
-both([false])
-//=> false
-
-both([1])
-//=> false
-
-```
----
-
-
-
-
-
-# conditional.prototype.not()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L3173 "View in source") [Ⓣ][1]
-
-(Function): return a negated function
-
-#### Since
-4.0.1
-
-#### Returns
-*(Function)*: !Function
-
-#### Example
-```js
-const falsed = not(x => true)
-const trued = not(x => false)
-
-trued()
-//=> true
-
-falsed()
-//=> false
-
-```
----
-
-
-
-
-
-# conditional.prototype.or()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L3221 "View in source") [Ⓣ][1]
-
-(Function): first fn || second fn
-
-#### Since
-4.0.1
-
-#### Returns
-*(boolean)*: one of the functions return truthy
-
-#### Example
-```js
-const either = or(x => x === false, x => x === true)
-
-either([true])
-//=> true
-
-either([new Boolean(true)])
-//=> false
-
-either([1])
-//=> false
-
-```
----
-
-
-
-
-
-
-
-## `debug`
-
-
-
-# debug()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L6718 "View in source") [Ⓣ][1]
-
-(Function): sets on store not this.set for easier extension
-
-
-### @notes
-
-* is inherited by any chain with a parent with .meta.debug
-
-#### Returns
-*(Chainable)*: @chainable
-
-#### Example
-```js
-const Chain = require('chain-able')
-const chain = new Chain()
-chain.debug()
-
-chain.get('debug')
-//=> true
-
-// not in entries
-chain.entries()
-//=> {}
-
-```
----
-
-
-
-
-
-
-
-## `define`
-
-
-
-# define()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L281 "View in source") [Ⓣ][1]
-
-(Function): default to configurable and enumerable, unless configured otherwise
-
-#### Since
-4.0.0
-
-#### Returns
-*(void)*:
-
-#### Example
-```js
-var desc = Object.getOwnPropertyDescriptor(obj, 'eh', {
- get: () => console.log('eh'),
-})
-
-```
----
-
-
-
-
-
-# define()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L679 "View in source") [Ⓣ][1]
-
-Function
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-#### Since
-0.5.0
-
-#### Returns
-*(number)*:
-
-#### Example
-```js
-for (var i = 0; i < chain.length; i++)
-```
----
-
-
-
-
-
-
-
-## `delete`
-
-
-
-# delete()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L545 "View in source") [Ⓣ][1]
-
-(Function): calls .delete on this.store.map
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-#### Since
-0.3.0
-
-#### Returns
-*(Chainable)*:
-
-#### Example
-```js
-const chain = new Chain()
-chain.set('eh', 1)
-chain.get('eh')
-// => 1
-chain.delete('eh', 1)
-chain.get('eh')
-// => undefined
-
-```
----
-
-
-
-
-
-# delete()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2568 "View in source") [Ⓣ][1]
-
-(Function): Delete the current element from its parent in the output. Calls delete even on Arrays.
-
-#### Returns
-*(void)*:
-
----
-
-
-
-
-
-# delete
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L7534 "View in source") [Ⓣ][1]
-
-unknown
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-#### Since
-3.0.1
-
-#### Example
-```js
-chain.set('moose.canada.eh', true)
-chain.set('moose.canada.igloo', true)
-//=> Chain
-
-chain.delete('moose.canada.eh')
-//=> Chain
-
-chain.has('moose.canada.eh')
-//=> true
-
-//still has moose.canada.igloo
-chain.has('moose.canada')
-//=> true
-
-```
----
-
-
-
-
-
-
-
-## `dopemerge.prototype`
-
-
-
-# dopemerge.prototype.cloneIfNeeded()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L1085 "View in source") [Ⓣ][1]
-
-(Function): Defaults to `false`.
-If `clone` is `true` then both `x` and `y` are recursively cloned as part of the merge.
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-#### Since
-2.0.0
-
-#### Returns
-*(*)*: cloned or original value
-
-#### Example
-```js
-var obj = { eh: true }
-
-cloneIfNeeded(obj, { clone: true }) === obj
-//=> false
-
-cloneIfNeeded(obj, { clone: false }) === obj
-//=> true
-
-```
----
-
-
-
-
-
-# dopemerge.prototype.defaultArrayMerge()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L1124 "View in source") [Ⓣ][1]
-
-(Function): The merge will also merge arrays and array values by default.
-However, there are nigh-infinite valid ways to merge arrays,
-and you may want to supply your own.
-You can do this by passing an `arrayMerge` function as an option.
-
-#### Since
-2.0.0
-
-#### Returns
-*(*)*: merged array
-
-#### Example
-```js
-function concatMerge(destinationArray, sourceArray, options) {
- destinationArray
- //=> [1, 2, 3]
-
- sourceArray
- //=> [3, 2, 1]
-
- options
- //=> { arrayMerge: concatMerge }
-
- return destinationArray.concat(sourceArray)
-}
-merge([1, 2, 3], [3, 2, 1], { arrayMerge: concatMerge })
-//=> [1, 2, 3, 3, 2, 1]
-
-```
----
-
-
-
-
-
-🌊 Types: _dopemergelater.d
-
-# dopemerge.prototype.dopemerge()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L1250 "View in source") [Ⓣ][1]
-
-(Function): Merge the enumerable attributes of two objects deeply. Merge two objects `x` and `y` deeply, returning a new merged object with the elements from both `x` and `y`. If an element at the same key is present for both `x` and `y`, the value from
-`y` will appear in the result. Merging creates a new object, so that neither `x` or `y` are be modified. However, child objects on `x` or `y` are copied over - if you want to copy all values, you must pass `true` to the clone option.
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-#### Returns
-*(*)*: merged
-
-
-{@link https://github.com/KyleAMathews/deepmerge deepmerge}
-
-#### Example
-```js
-var x = {
- foo: { bar: 3 },
- array: [
- {
- does: 'work',
- too: [1, 2, 3],
- },
- ],
-}
-
-var y = {
- foo: { baz: 4 },
- quux: 5,
- array: [
- {
- does: 'work',
- too: [4, 5, 6],
- },
- {
- really: 'yes',
- },
- ],
-}
-
-var expected = {
- foo: {
- bar: 3,
- baz: 4,
- },
- array: [
- {
- does: 'work',
- too: [1, 2, 3, 4, 5, 6],
- },
- {
- really: 'yes',
- },
- ],
- quux: 5,
-}
-
-merge(x, y)
-//=> expected
-
-```
----
-
-
-
-
-
-# dopemerge.prototype.emptyTarget()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L1056 "View in source") [Ⓣ][1]
-
-(Function): make a new empty Array or Object for cloning
-
-#### Since
-2.0.0
-
-#### Returns
-*(*)*: depending on the data type of val
-
-#### Example
-```js
-emptyTarget({ eh: true })
-//=> {}
-
-emptyTarget([1])
-//=> []
-
-```
----
-
-
-
-
-
-# dopemerge.prototype.isMergeableObj()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L1036 "View in source") [Ⓣ][1]
-
-(Function): 1: not null object `2`: object toString is not a date or regex
-
-#### Since
-2.0.0
-
-#### Returns
-*(boolean)*:
-
-#### Example
-```js
-isMergeableObj({})
-//=> true
-
-isMergeableObj(Object.create(null))
-// => true
-
-isMergeableObj(new Date())
-//=> false
-
-isMergeableObj(/eh/)
-//=> false
-
-```
----
-
-
-
-
-
-
-
-## `dot`
-
-
-
-# dot()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L7395 "View in source") [Ⓣ][1]
-
-Function
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-#### Since
-3.0.1
-
-#### Returns
-*(DotProp)*: @chainable
-
-#### Example
-```js
-const chain = new Target()
-chain.dot(false)
-chain.set('moose.simple', 1)
-
-toArr(chain.store.keys())
-//=> ['moose.simple']
-
-```
----
-
-
-
-
-
-
-
-## `encase`
-
-
-
-# encase()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L3907 "View in source") [Ⓣ][1]
-
-Function
-
-#### Since
-4.0.0
-
-#### Returns
-*(Function)*: -> FunctionObject{onInvalid, onValid, rethrow, call}
-
-#### Example
-```js
-const throws = x => {
- if (x === false) {
- throw new Error('invalid - cannot be false')
- }
- return true
-}
-const api = encase(throws)
-
-api.onValid(console.log)
-api.onInvalid(console.error)
-
-//--- invalid
-api.call(false)
-//=> 'invalid - cannot be false'
-
-//--- valid
-api.call(true)
-//=> 'true'
-
-```
----
-
-
-
-
-
-
-
-## `encase.prototype`
-
-
-
-# encase.prototype.error$3()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L3805 "View in source") [Ⓣ][1]
-
-(Function): enhance an Error, enable rethrowing & better inspection
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-
-### @todos
-
-- [ ] js stringify if development
-
-#### Since
-4.0.0-alpha.1
-
-#### Returns
-*(Function): function that returns a decorated TypeError with .inspect & metadata (arg, thrown, meta)*
-
-#### Example
-```js
-const badValidator = x => {
- if (x === 'bad') {
- throw new Error('bad!')
- }
-}
-const enhancer = enhanceError('eh', badValidator)
-
-// called by plugins/encase when throws or invalid
-let error
-let arg = 'bad'
-try {
- error = badValidator(arg)
-} catch (e) {
- error = enhancer(arg, e, { metadata: true })
-}
-
-console.log(error)
-//=> {[eh]: { type: badValidator, arg: 'bad', json, str, rethrow }}
-//=> console.log on DEVELOPMENT
-
-```
----
-
-
-
-
-
-
-
-## `end`
-
-
-
-# end()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L433 "View in source") [Ⓣ][1]
-
-(Function): for ending nested chains
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-#### Since
-0.4.0
-
-#### Returns
-*(*)*:
-
-#### Example
-```js
-const parent = 'eh'
-const child = newChain(parent)
-child.end()
-//=> 'eh'
-
-```
----
-
-
-
-
-
-
-
-## `entries`
-
-
-
-# entries()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L1413 "View in source") [Ⓣ][1]
-
-(Function): recursively reduce maps and objects that include reducable data
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-
-### @sig
-
-reduced => object => isMap(object) -> reduced; merge(object, reduced)
-#### Since
-4.0.0
-
-#### Returns
-*(Function): Function(values: Object)*
-
-#### Example
-```js
-const map = new Map()
- map.set('eh', true)
- const nested = new Map()
- nested.set('reduced', true)
-
- const chain = {
- entries() {
- return {
- nested: reduce(nested),
- key: true,
- }
- },
- }
- const reduced = reduce(map)
- reduceEntries(reduced)({chain})
- // => {
- eh: true,
- chain: {
- nested: {
- reduced: true,
- key: true,
- },
- },
- }
-```
-#### Example
-```js
-const reducedIgnored = {
- canada: {
- store: chain,
- },
- }
- const ignored = reduceEntries(reduced)(reducedIgnored)
- //=> {
- eh: true,
- chain: {
- nested: {
- reduced: true,
- },
- key: true,
- },
- }
-```
----
-
-
-
-
-
-
-
-## `fn.call`
-
-
-
-# fn.call()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L6607 "View in source") [Ⓣ][1]
-
-(Function): call the observer - it matched & data changed
-
----
-
-
-
-
-
-
-
-## `forEach`
-
-
-
-# forEach
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2164 "View in source") [Ⓣ][1]
-
-unknown
-
-
-### @notes
-
-* if there is .forEach on the obj already, use it
-otherwise, call function for each
-
-
-### @todos
-
-- [ ] unexpectedly breaks things iterating
-if you are relying on internal functionality
-(such as .path, .get, .value...) with map & set
-
-#### Since
-3.0.0
-
-#### Example
-```js
-forEach([1], console.log)
-//=> 1
-
-```
----
-
-
-
-
-
-# forEach()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2793 "View in source") [Ⓣ][1]
-
-(Function): adds methods to Traverser
-
----
-
-
-
-
-
-
-
-## `from`
-
-
-
-# from
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L1312 "View in source") [Ⓣ][1]
-
-unknown
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
----
-
-
-
-
-
-
-
-## `get`
-
-
-
-# get()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L1611 "View in source") [Ⓣ][1]
-
-Function
-
-#### Since
-4.0.0
-
-#### Returns
-*(any)*:
-
----
-
-
-
-
-
-
-
-## `getMeta`
-
-
-
-
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L1564 "View in source") [Ⓣ][1]
-
-Function
-
-#### Since
-4.0.0
-
-#### Returns
-*(Chain)*:
-
----
-
-
-
-
-
-
-
-## `handleExisting`
-
-
-
-# handleExisting()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L5285 "View in source") [Ⓣ][1]
-
-Function
-
-
-### @todos
-
-- [ ] could use .eq here
-- [ ] if (isMapish(obj)) obj = obj.entries()
-
-#### Returns
-*(void)*:
-
-#### Example
-```js
-var obj = { key: 1 }
-
-MergeChain.init(obj).merge({ key: ['value'] })
-
-// goes to this internal scoped function
-handleExisting('key', ['value'])
-// if there is .onValue or .onExisting, use them, default deepmerge
-
-obj
-//=> {key: [1, 'value']}
-
-```
----
-
-
-
-
-
-
-
-## `has`
-
-
-
-# has()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L565 "View in source") [Ⓣ][1]
-
-Function
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-#### Since
-0.3.0
-
-#### Returns
-*(boolean)*:
-
-#### Example
-```js
-const chain = new Chain()
-chain.set('eh', 1).has('eh')
-//=> true
-chain.has('canada')
-//=> false
-
-```
----
-
-
-
-
-
-# has()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L1601 "View in source") [Ⓣ][1]
-
-Function
-
-#### Since
-4.0.0
-
-#### Returns
-*(boolean)*:
-
----
-
-
-
-
-
-# has
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L7501 "View in source") [Ⓣ][1]
-
-unknown
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-#### Since
-3.0.1
-
-#### Example
-```js
-chain.set('one.two', 3)
-chain.has('one.two')
-//=> true
-
-```
----
-
-
-
-
-
-
-
-## `if`
-
-
-
-# if()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L658 "View in source") [Ⓣ][1]
-
-(Function): hint === 'number'
-`s`tring is `115`
-`n`umber is `110`
-110 & `4` = `1`
-115 & `4` = `0`
-
-
-if *(hint === 'string' && this.toJSON) return this.toJSON()*
-else if *(hint === 'number' && this.toNumber) return this.toNumber()*
-
----
-
-
-
-
-
-# if()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L4536 "View in source") [Ⓣ][1]
-
-(Function): this is a plugin for building methods schema defaults value to `.type` this defaults values to `.onCall`
-
----
-
-
-
-
-
-# if()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L5319 "View in source") [Ⓣ][1]
-
-(Function): check if it's shorthanded
--> check if it has a value already
-
----
-
-
-
-
-
-# if()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L5327 "View in source") [Ⓣ][1]
-
-(Function): if we have onExisting, call it
-else default to dopemerge
-
----
-
-
-
-
-
-# if()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L6592 "View in source") [Ⓣ][1]
-
-(Function): if we have called it at least once... and it has not changed, leave it
-else clone it call the observer
-
----
-
-
-
-
-
-
-
-## `index`
-
-
-
-# compose
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L711 "View in source") [Ⓣ][1]
-
-unknown
-
-#### Since
-3.0.0
-
-#### Example
-```js
-class Target {}
-const TargetChain = Chainable.compose(Target)
-const chain = new TargetChain()
-chain instanceof Target
-//=> true
-
-```
----
-
-
-
-
-
-
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L1524 "View in source") [Ⓣ][1]
-
-unknown
-
----
-
-
-
-
-
-
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L1575 "View in source") [Ⓣ][1]
-
-unknown
-
----
-
-
-
-
-
-# walk()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2480 "View in source") [Ⓣ][1]
-
-Function
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-#### Returns
-*(any)*:
-
----
-
-
-
-
-
-# copy()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2730 "View in source") [Ⓣ][1]
-
-Function
-
-
-### @notes
-
-* wicked ternary
-
-
-### @todos
-
-- [ ] does not respect ObjectDescriptors
-
-#### Returns
-*(any)*:
-
----
-
-
-
-
-
-
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L4315 "View in source") [Ⓣ][1]
-
-unknown
-
-
-### @todos
-
-- [ ] clarify .set vs .call
-{@link https://github.com/iluwatar/java-design-patterns/tree/master/property property-pattern}
-{@link https://github.com/iluwatar/java-design-patterns/tree/master/prototype prototype-pattern}
-{@link https://github.com/iluwatar/java-design-patterns/tree/master/step-builder step-builder-pattern}
-{@link https://github.com/iluwatar/java-design-patterns/tree/master/builder builder-pattern}
-{@link https://github.com/addyosmani/essential-js-design-patterns/blob/master/diagrams/mixins.png mixin-png}
-{@link https://sourcemaking.com/design_patterns/creational_patterns creational-patterns}
-{@link https://sourcemaking.com/design_patterns/factory_method factory-method}
-{@link https://medium.com/javascript-scene/javascript-factory-functions-vs-constructor-functions-vs-classes-2f22ceddf33e constructors}
-{@link https://www.sitepoint.com/factory-functions-javascript/ js-factory-functions}
-
----
-
-
-
-
-
-
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L6620 "View in source") [Ⓣ][1]
-
-unknown
-
-#### Since
-2.0.0
-
----
-
-
-
-
-
-
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L7286 "View in source") [Ⓣ][1]
-
-unknown
-
-#### Since
-2.0.0
-
----
-
-
-
-
-
-
-
-## `is.prototype`
-
-
-
-# is.prototype.boolean_1()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L972 "View in source") [Ⓣ][1]
-
-(Function): Checks if `value` is classified as a boolean primitive or object.
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-
-### @notes
-
-* could also have typeof x === 'boolean' || (/true|false/).test(x)
-
-
-### @extends
-
-* undefined
-* undefined
-
-
-#### Since
-3.0.0
-
-#### Returns
-*(boolean)*: isBoolean
-
-#### Example
-```js
-isBoolean(false)
-//=> true
-isBoolean(new Boolean(1))
-//=> true
-isBoolean(1)
-//=> false
-isBoolean('')
-//=> false
-
-```
----
-
-
-
-
-
-# is.prototype.date()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L940 "View in source") [Ⓣ][1]
-
-Function
-
-#### Since
-3.0.0
-
-#### Returns
-*(boolean)*: isDate
-
-#### Example
-```js
-isDate(new Date())
-//=> true
-isDate(Date.now())
-//=> false
-isDate(1)
-//=> false
-isDate('')
-//=> false
-
-```
-#### Example
-```js
-const e = {}
-eh[Symbol.toStringTag] = '[Object Date]'
-isDate(eh)
-//=> true
-
-```
-#### Example
-```js
-class Eh extends Date()
- isDate(new Eh())
- //=> true
-```
----
-
-
-
-
-
-# is.prototype.error$1()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2043 "View in source") [Ⓣ][1]
-
-Function
-
-#### Returns
-*(boolean)*: isError
-
-#### Example
-```js
-isError(new Error())
-//=> true
-isError(new Error().stack)
-//=> false
-isError(1)
-//=> false
-isError('')
-//=> false
-
-```
-#### Example
-```js
-const e = {}
-eh[Symbol.toStringTag] = '[Object Error]'
-isError(eh)
-//=> true
-
-```
-#### Example
-```js
-class Eh extends Error()
- isError(new Eh())
- //=> true
-```
----
-
-
-
-
-
-# is.prototype._false()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L257 "View in source") [Ⓣ][1]
-
-Function
-
-#### Since
-4.0.0-alpha.1
-
-#### Returns
-*(boolean)*: isFalse
-
-#### Example
-```js
-isFalse(false)
-//=> true
-isFalse(true)
-//=> false
-isFalse(0)
-//=> false
-isFalse('')
-//=> false
-
-```
----
-
-
-
-
-
-# is.prototype._function()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L178 "View in source") [Ⓣ][1]
-
-(Function): Checks if `value` is classified as a `Function` object.
-
-
-### @notes
-
-* || x instanceof Function
-
-#### Since
-3.0.0
-
-#### Returns
-*(boolean)*: x isFunction
-
-#### Example
-```js
-isFunction(function() {})
-//=> true
-isFunction(() => {})
-//=> true
-isFunction(new Function())
-//=> true
-
-isFunction(1)
-//=> false
-isFunction('')
-//=> false
-isFunction(/abc/)
-// => false
-
-```
----
-
-
-
-
-
-# is.prototype.()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L1471 "View in source") [Ⓣ][1]
-
-Function
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-#### Since
-3.0.0
-
-#### Returns
-*(boolean)*: isIterator
-
-#### Example
-```js
-isIterator(new Set().values())
-//=> true
-isIterator(new Map.entries())
-//=> true
-isIterator(new Map())
-//=> false
-isIterator('')
-//=> false
-isIterator(1)
-//=> false
-
-```
-#### Example
-```js
-const e = {}
-eh[Symbol.toStringTag] = '[Map Iterator]'
-isIterator(eh)
-//=> true
-eh[Symbol.toStringTag] = '[Set Iterator]'
-isIterator(eh)
-//=> true
-
-```
-#### Example
-```js
-class Eh extends Set()
- isIterator(new Eh().values())
- //=> true
-```
----
-
-
-
-
-
-# is.prototype.map()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L119 "View in source") [Ⓣ][1]
-
-(Function): Checks if `value` is classified as a `Map` object.
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-#### Since
-3.0.0
-
-#### Returns
-*(boolean)*: isMap
-
-#### Example
-```js
-isMap(new Map())
-//=> true
-isMap(new Map.entries())
-//=> false
-isMap(new Set())
-//=> false
-isMap({})
-//=> false
-isMap('')
-//=> false
-isMap(1)
-//=> false
-isMap(new WeakMap())
-// => false
-
-```
-#### Example
-```js
-const e = {}
-eh[Symbol.toStringTag] = '[object Map]'
-isMap(eh)
-
-```
-#### Example
-```js
-class Eh extends Map()
- isMap(new Eh())
- //=> true
-```
----
-
-
-
-
-
-# is.prototype.mapish()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L5124 "View in source") [Ⓣ][1]
-
-Function
-
-
-### @extends
-
-
-
-#### Since
-3.0.0
-
-#### Returns
-*(boolean)*: isMapish
-
-#### Example
-```js
-isMapish(new Map())
-//=> true
-
-isMapish(new Chain())
-//=> true
-
-isMapish({})
-//=> false
-
-isMapish(1)
-//=> false
-
-```
----
-
-
-
-
-
-# is.prototype.matcher()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L3083 "View in source") [Ⓣ][1]
-
-Function
-
-#### Since
-3.0.0
-
-#### Returns
-*(boolean)*: isFunction || isRegExp
-
-#### Example
-```js
-isMatcher(/(.*)/)
-//=> true
-
-isMatcher(x => true)
-//=> true
-
-isMatcher(1)
-//=> false
-isMatcher('.*')
-//=> false
-
-```
----
-
-
-
-
-
-# is.prototype.notEmptyArray()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L7657 "View in source") [Ⓣ][1]
-
-(Function): value is an Array, with at least `1` value
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-
-### @extends
-
-
-
-#### Since
-4.0.0-alpha.1
-
-#### Returns
-*(boolean)*: isNotEmptyArray
-
-#### Example
-```js
-isNotEmptyArray(new Array(3))
-//=> true
-isNotEmptyArray([1, 2, 3])
-//=> true
-
-isNotEmptyArray(new Array())
-//=> false
-isNotEmptyArray([])
-//=> false
-isNotEmptyArray(new Map())
-//=> false
-
-```
----
-
-
-
-
-
-# is.prototype._null()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L775 "View in source") [Ⓣ][1]
-
-Function
-
-#### Since
-3.0.0
-
-#### Returns
-*(boolean)*: isNull
-
-#### Example
-```js
-isNull(null)
-//=> true
-
-isNull(undefined)
-//=> false
-isNull(void 0)
-//=> false
-isNull({})
-//=> false
-isNull('')
-//=> false
-isNull(1)
-//=> false
-
-```
----
-
-
-
-
-
-# is.prototype.nullOrUndefined()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L814 "View in source") [Ⓣ][1]
-
-(Function): Checks if `value` is `null` or `undefined`.
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-#### Since
-4.0.0-alpha.1
-
-#### Returns
-*(boolean)*: isNullOrUndefined
-
-#### Example
-```js
-isNullOrUndefined(null)
-//=> true
-isNullOrUndefined(undefined)
-//=> true
-isNullOrUndefined(void 0)
-//=> true
-
-isNullOrUndefined(NaN)
-//=> false
-isNullOrUndefined({})
-//=> false
-isNullOrUndefined('')
-//=> false
-isNullOrUndefined(1)
-//=> false
-isNullOrUndefined(false)
-//=> false
-
-```
----
-
-
-
-
-
-# is.prototype.number()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2086 "View in source") [Ⓣ][1]
-
-Function
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-
-### @notes
-
-* was not needed except for abstract ==
- const isObj = require('./obj')
- const isSymbol = require('./symbol')
- (isObj(x) || isSymbol(x)
- ? false
- : (/^0x[0-9a-f]+$/i).test(x) ||
- (/^[-+]?(?:\d+(?:\.\d*)?|\.\d+)(e[-+]?\d+)?$/).test(x))
-
-#### Since
-3.0.0
-
-#### Returns
-*(boolean)*: isNumber
-
-#### Example
-```js
-isNumber(1)
-//=> true
-isNumber(Number(1))
-//=> true
-isNumber(NaN)
-//=> true
-
-isNumber(null)
-//=> false
-isNumber(undefined)
-//=> false
-isNumber(void 0)
-//=> false
-isNumber({})
-//=> false
-isNumber('')
-//=> false
-isNumber(false)
-//=> false
-
-```
----
-
-
-
-
-
-# is.prototype.obj()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2009 "View in source") [Ⓣ][1]
-
-Function
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-
-### @notes
-
-* Object.prototype.toString.call(val) === '[object Object]'
-
-#### Since
-3.0.0
-
-#### Returns
-*(boolean)*: Returns `true` if `value` is an object, else `false`.
-
-#### Example
-```js
-isObject({})
-// => true
-
-isObject([1, 2, 3])
-// => true
-
-isObject(Function)
-// => true
-
-isObject(null)
-// => false
-
-```
----
-
-
-
-
-
-# is.prototype.objLoose()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L748 "View in source") [Ⓣ][1]
-
-Function
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-#### Since
-3.0.0
-
-#### Returns
-*(boolean)*: isObjLoose
-
-#### Example
-```js
-isObjLoose(new Object())
-//=> true
-isObjLoose({})
-//=> true
-isObjLoose(Object.create(null))
-//=> true
-isObjLoose(null)
-//=> true
-
-isObjLoose(new Set())
-//=> false
-isObjLoose(function() {})
-//=> false
-isObjLoose('')
-//=> false
-isObjLoose(1)
-//=> false
-
-```
----
-
-
-
-
-
-# is.prototype.objStrict()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L856 "View in source") [Ⓣ][1]
-
-Function
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-
-### @todos
-
-- [ ] !Array.isArray
-
-
-### @extends
-
-
-
-#### Since
-3.0.0
-
-#### Returns
-*(boolean)*: isObjStrict
-
-#### Example
-```js
-isObjStrict(new Object())
-//=> true
-isObjStrict({})
-//=> true
-isObjStrict(Object.create(null))
-//=> true
-isObjStrict(null)
-//=> false
-
-isObjStrict(new Set())
-//=> false
-isObjStrict(function() {})
-//=> false
-isObjStrict('')
-//=> false
-isObjStrict(1)
-//=> false
-
-```
----
-
-
-
-
-
-# is.prototype.objWithKeys()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L3038 "View in source") [Ⓣ][1]
-
-Function
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-
-### @extends
-
-
-
-#### Since
-3.0.0
-
-#### Returns
-*(boolean)*: isObjWithKeys
-
-#### Example
-```js
-isObjWithKeys({ eh: true })
-//=> true
-isObjWithKeys({})
-//=> false
-isObjWithKeys(new Object())
-//=> false
-isObjWithKeys(Object.create(null))
-//=> false
-isObjWithKeys(null)
-//=> false
-isObjWithKeys(new Set())
-//=> false
-isObjWithKeys(function() {})
-//=> false
-isObjWithKeys('')
-//=> false
-isObjWithKeys(1)
-//=> false
-
-```
----
-
-
-
-
-
-# is.prototype.real()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2999 "View in source") [Ⓣ][1]
-
-Function
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-
-### @notes
-
-* eslint-disable-next-line no-self-compare
- && x !== x
-
-
-### @extends
-
-
-
-#### Since
-3.0.0
-
-#### Returns
-*(boolean)*: isReal
-
-#### Example
-```js
-isReal(null)
-//=> false
-isReal(void 0)
-//=> false
-const nan = Number(undefined)
-isReal(nan)
-//=> false
-
-isReal({ eh: true })
-//=> true
-isReal({})
-//=> true
-isReal(Object)
-//=> true
-isReal([])
-//=> true
-isReal(new Set())
-//=> true
-isReal(function() {})
-//=> true
-isReal('')
-//=> true
-isReal(1)
-//=> true
-
-```
----
-
-
-
-
-
-# is.prototype._true()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L886 "View in source") [Ⓣ][1]
-
-Function
-
-#### Since
-4.0.0-alpha.1
-
-#### Returns
-*(boolean)*: isTrue
-
-#### Example
-```js
-isTrue(true)
-//=> true
-isTrue(false)
-//=> false
-isTrue(1)
-//=> false
-isTrue('')
-//=> false
-
-```
----
-
-
-
-
-
-# is.prototype._undefined()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L52 "View in source") [Ⓣ][1]
-
-(Function): Checks if `value` is `undefined`.
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-
-### @notes
-
-* || typeof x === 'undefined'
-
-#### Since
-4.0.0-alpha.1
-
-#### Returns
-*(boolean)*: isUndefined
-
-#### Example
-```js
-isUndefined(undefined)
-//=> true
-isUndefined(void 0)
-//=> true
-
-isUndefined(null)
-//=> false
-isUndefined(NaN)
-//=> false
-isUndefined({})
-//=> false
-isUndefined('')
-//=> false
-isUndefined(1)
-//=> false
-isUndefined(false)
-//=> false
-
-```
----
-
-
-
-
-
-# is.prototype.string()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L235 "View in source") [Ⓣ][1]
-
-(Function): Checks if `value` is classified as a `String` primitive or object.
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-
-### @extends
-
-
-
-#### Since
-3.0.0
-
-#### Returns
-*(boolean)*: Returns `true` if `value` is a string, else `false`.
-
-#### Example
-```js
-isString('abc')
-// => true
-
-isString(new String('abc'))
-// => true
-
-isString(1)
-// => false
-
-```
----
-
-
-
-
-
-# is.prototype.stringOrNumber()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2949 "View in source") [Ⓣ][1]
-
-(Function): Checks if `value` is classified as a `String` primitive or object.
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-#### Since
-3.0.0
-
-#### Returns
-*(boolean)*: Returns `true` if `value` is a string, else `false`.
-
-#### Example
-```js
-isString('abc')
-// => true
-
-isString(1)
-// => false
-
-```
----
-
-
-
-
-
-# is.prototype.stringPrimitive()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L206 "View in source") [Ⓣ][1]
-
-(Function): Checks if `value` is classified as a `String` **primitive**.
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-#### Since
-3.0.0
-
-#### Returns
-*(boolean)*: Returns `true` if `value` is a string, else `false`.
-
-#### Example
-```js
-isString('abc')
-// => true
-
-isString(new String('abc'))
-// => false
-
-isString(1)
-// => false
-
-```
----
-
-
-
-
-
-# is.prototype.symbol()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L3059 "View in source") [Ⓣ][1]
-
-(Function): Checks if `value` is classified as a `Symbol` primitive or object.
-
-#### Since
-4.0.0
-
-#### Returns
-*(boolean)*: Returns `true` if `value` is a symbol, else `false`.
-
-#### Example
-```js
-isSymbol(Symbol.iterator)
-// => true
-
-isSymbol('abc')
-// => false
-
-```
----
-
-
-
-
-
-# is.prototype.toS()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L77 "View in source") [Ⓣ][1]
-
-(Function): The base implementation of `getTag` without fallbacks for buggy environments.
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-
-### @todos
-
-- [ ] obj[Symbol.toStringTag]
-
-#### Returns
-*(string)*: Returns the `toStringTag`.
-
----
-
-
-
-
-
-
-
-## `is.prototype.index$12`
-
-
-
-🌊 Types: is.d
-
-* 🔬 Tests: index
-* 🔬 Tests: is
-* 🔬 Tests: primitives
-* 🔬 Tests: simple
-
-# is.prototype.index$12
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L3100 "View in source") [Ⓣ][1]
-
-Object
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
----
-
-
-
-
-
-
-
-## `isArray`
-
-
-
-# array
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L864 "View in source") [Ⓣ][1]
-
-Function
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-#### Since
-3.0.0
-
----
-
-
-
-
-
-
-
-## `isRoot`
-
-
-
-# isRoot
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2537 "View in source") [Ⓣ][1]
-
-(Boolean): Whether the present node is the root node
-
----
-
-
-
-
-
-
-
-## `key`
-
-
-
-# key
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2532 "View in source") [Ⓣ][1]
-
-unknown
-
----
-
-
-
-
-
-
-
-## `level`
-
-
-
-# level
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2542 "View in source") [Ⓣ][1]
-
-(number): Depth of the node within the traversal
-
----
-
-
-
-
-
-
-
-## `m`
-
-
-
-
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L6576 "View in source") [Ⓣ][1]
-
-unknown
-
----
-
-
-
-
-
-
-
-## `markForGarbageCollection`
-
-
-
-# markForGarbageCollection()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L4268 "View in source") [Ⓣ][1]
-
-(Function): remove all methods, mark for garbage collection
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-
-### @todos
-
-- [ ] blacklist = [] param
-- [ ] put all GC events into a cached map and debounce the operation
-
-#### Since
-4.0.0
-
-#### Returns
-*(void)*:
-
-#### Example
-```js
-var scoped = {}
-var ref = () => scoped
-var obj = { scoped, ref, eh: true }
-
-markForGarbageCollection(obj)
-//=> void
-
-obj
-//=> undefined|{}
-
-```
----
-
-
-
-
-
-
-
-## `matcher.prototype`
-
-
-
-# matcher.prototype.escapeStringRegex()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L6183 "View in source") [Ⓣ][1]
-
-Function
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-
-### @notes
-
-* also as const escapeStringRegexp = require('escape-string-regexp');
-
-#### Since
-3.0.0
-
-#### Returns
-*(string)*: escaped string
-
-
-{@link https://github.com/sindresorhus/escape-string-regexp escape-string-regexp}
-
-#### Example
-```js
-const escaped = escapeStringRegexp('how much $ for a unicorn?')
-//=> 'how much \$ for a unicorn\?'
-new RegExp(escaped)
-
-```
----
-
-
-
-
-
-# matcher.prototype.make()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L6268 "View in source") [Ⓣ][1]
-
-(Function): turn any string[], function[], or RegExp[] into a matcher
-
-#### Since
-3.0.0
-
-#### Returns
-*(*)*: matchable
-
-#### Example
-```js
-matcher.make('*')
-//=> RegExp('.*', 'i')
-
-```
-#### Example
-```js
-var any = new RgExp('.*', 'i')
-matcher.make(any)
-//=> any
-
-```
-#### Example
-```js
-var strings = x => typeof x === 'string'
-matcher.make(strings)
-// {test: strings}
-
-```
-#### Example
-```js
-var tester = { test: x => x === true }
-matcher.make(tester)
-// tester
-
-```
-#### Example
-```js
-var noName = '!name'
-matcher.make(noName, true)
-// new RegExp('(?:name)', 'i')
-
-```
-#### Example
-```js
-var noName = '!name'
-matcher.make(noName, true, true)
-// new RegExp('^(?:name)$', 'i')
-
-```
----
-
-
-
-
-
-# matcher.prototype.matcher()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L6344 "View in source") [Ⓣ][1]
-
-(Function): same as .make but also accepts inputs, and returns an array
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-#### Since
-3.0.0
-
-#### Returns
-*(*)*:
-
-#### Example
-```js
-matcher(['foo', 'bar', 'moo'], ['*oo', '!foo'])
-//=> ['moo']
-
-matcher(['foo', 'bar', 'moo'], ['!*oo'])
-
-```
-#### Example
-```js
-matcher('kinga', 'kinga')
-//=> ['kinga']
-matcher('k*nga', 'kinga')
-//=> ['kinga']
-matcher('kinga', 'nope')
-//=> []
-
-matcher(new RegExp(/kinga/), 'kinga')
-//=> ['kinga']
-matcher(new RegExp(/kinga/), 'nope')
-//=> ['nope']
-
-matcher(x => x === 'kinga', 'kinga')
-//=> ['kinga']
-matcher(x => x === 'kinga', 'nope')
-//=> []
-
-matcher({ test: x => x === 'kinga' }, 'kinga')
-//=> ['kinga']
-matcher({ test: x => x === 'kinga' }, 'nope')
-//=> []
-
-```
----
-
-
-
-
-
-🌊 Types: matcher.d
-
-🔬 Tests: matcher
-
-# matcher.prototype.matcher
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L6219 "View in source") [Ⓣ][1]
-
-unknown
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-
-### @symb
-
-🎯
----
-
-
-
-
-
-# matcher.prototype.toRegexp()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L6203 "View in source") [Ⓣ][1]
-
-Function
-
-
-### @extends
-
-
-
-#### Returns
-*(string)*: escaped str
-
-#### Example
-```js
-toRegExp('*')
- => '.*'
-
- toRegExp('eh')
- => 'eh'
-```
----
-
-
-
-
-
-
-
-## `merge`
-
-
-
-# merge()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L5232 "View in source") [Ⓣ][1]
-
-(Function): merges object in, goes through all keys, checks cbs, dopemerges
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-
-### @todos
-
-- [ ] issue here if we extend without shorthands &
- we want to merge existing values... :s
-
-#### Since
-1.0.0
-
-#### Returns
-*(MergeChain)*: @chainable
-
-#### Example
-```js
-const chain = new Chain()
-chain.merge({ canada: { eh: true } })
-chain.merge({ canada: { arr: [0, { '1': 2 }], eh: { again: true } } })
-chain.entries()
-//=> {canada:{ eh: {again: true}, arr: [0, {'1': 2}] }}
-
-```
----
-
-
-
-
-
-# merge()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L5553 "View in source") [Ⓣ][1]
-
-(Function): merges an object with the current store
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-
-### @todos
-
-- [ ] needs to pass in additional opts somehow...
-
-#### Since
-0.4.0
-
-#### Returns
-*(ChainedMap)*: @chainable
-
-#### Example
-```js
-const chain = new Chain()
-chain.set('eh', [1])
-chain.merge({ eh: [2] })
-chain.get('eh')
-// => [1, 2]
-
-```
-#### Example
-```js
-const chain = new Chain()
- chain.set('emptyArr', [])
- chain.merge({emptyArr: []}, mergeChain =>
- mergeChain.onExisting((a, b) => []).merger((a, b) => []).merge()
- )
- chain.get('emptyArr').length)
- //=> 0
-```
----
-
-
-
-
-
-# merge()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L5665 "View in source") [Ⓣ][1]
-
-(Function): merge any Array/Set/Iteratable/Concatables into the array, at the end
-
-#### Since
-0.4.0
-
-#### Returns
-*(ChainedSet)*: @chainable
-
-#### Example
-```js
-const people = new ChainedSet()
-people.add('sam').add('sue').prepend('first').merge(['merged'])
-
-for (let name of people) console.log(name)
-//=> first, sam, sue, merged
-
-```
----
-
-
-
-
-
-
-
-## `meta`
-
-
-
-
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L1648 "View in source") [Ⓣ][1]
-
-(Function): a single easily minifiable function, dynamically setting & getting depending on arguments to avoid nested property accessing only instantiating when values are **addded**
-
-#### Since
-4.0.0
-
-#### Returns
-*(*)*: depending on args
-
----
-
-
-
-
-
-
-
-## `method`
-
-
-
-# method()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L5517 "View in source") [Ⓣ][1]
-
-(Function): the way to easily start building methods when using chainable instances
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-#### Since
-4.0.0
-
-#### Returns
-*(MethodChain)*: @chainable
-
-#### Example
-```js
-const chain = new Chain()
-chain.method('eh').build()
-chain.eh(true)
-chain.get('eh')
-// => true
-
-```
----
-
-
-
-
-
-
-
-## `methodEncasingFactory`
-
-
-
-# methodEncasingFactory()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L3956 "View in source") [Ⓣ][1]
-
-(Function): 3 steps
-0. enhance error
-1. encase function with a specification
-2. build a function to call onInvalid or onInvalid depending
-
-
-### @symb
-
-⛑🏭
-#### Since
-4.0.0
-
-#### Returns
-*(Function)*: curried finisher, for specification
-
-#### Example
-```js
-methodEncasingFactory('eh', {}, { onSet: console.log })
-//=> Function
-
-```
----
-
-
-
-
-
-
-
-## `node`
-
-
-
-# node
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2510 "View in source") [Ⓣ][1]
-
-(Array): The present node on the recursive walk
-
----
-
-
-
-
-
-
-
-## `node_`
-
-
-
-# node_
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2516 "View in source") [Ⓣ][1]
-
-Array
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
----
-
-
-
-
-
-
-
-## `objs`
-
-
-
-# objs
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L6461 "View in source") [Ⓣ][1]
-
-(Map): scoped clones
-
----
-
-
-
-
-
-
-
-## `objs.set`
-
-
-
-# objs.set()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L6602 "View in source") [Ⓣ][1]
-
-(Function): it did change - clone it for next deepEquals check
-
----
-
-
-
-
-
-
-
-## `parent`
-
-
-
-# parent
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2526 "View in source") [Ⓣ][1]
-
-unknown
-
----
-
-
-
-
-
-
-
-## `path`
-
-
-
-# path
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2521 "View in source") [Ⓣ][1]
-
-(Array): An array of string keys from the root to the present node
-
----
-
-
-
-
-
-
-
-## `paths`
-
-
-
-# paths()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2814 "View in source") [Ⓣ][1]
-
-(Function): gathers dot.prop from any value, with a prefixed/base key
-
-
-### @notes
-
-* had `onlyLongest` & `asString` but can just .join(',') to match
-
-#### Since
-4.0.0
-
-#### Returns
-*(*)*: paths
-
----
-
-
-
-
-
-
-
-## `post`
-
-
-
-# post()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2621 "View in source") [Ⓣ][1]
-
-(Function): Call this function after each of the children are traversed.
-
-#### Returns
-*(any)*:
-
----
-
-
-
-
-
-
-
-## `pre`
-
-
-
-# pre()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2613 "View in source") [Ⓣ][1]
-
-(Function): Call this function before each of the children are traversed.
-
-#### Returns
-*(any)*:
-
----
-
-
-
-
-
-
-
-## `prepend`
-
-
-
-# prepend()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L5641 "View in source") [Ⓣ][1]
-
-(Function): inserts the value at the **beginning** of the Set
-
-#### Since
-0.4.0
-
-#### Returns
-*(ChainedSet)*: @chainable
-
-#### Example
-```js
-const people = new ChainedSet()
-people.add('sue').prepend('first')
-
-for (let name of people) console.log(name)
-//=> first, sue
-
-```
----
-
-
-
-
-
-
-
-## `prototype[iterator]`
-
-
-
-🔬 Tests: iteration
-
-# prototype[iterator]()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L391 "View in source") [Ⓣ][1]
-
-(generator): Iterator for looping values in the store
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-
-### @notes
-
-* assigned to a variable so buble ignores it
-
-#### Since
-0.5.0
-
-#### Returns
-*(Object)*: {value: undefined | any, done: true | false}
-
-#### Example
-```js
-const chain = new Chain().set('eh', 1)
-for (var [key, val] of chain) console.log({ [key]: val })
-//=> {eh: 1}
-
-```
-#### Example
-```js
-*[Symbol.iterator](): void { for (const item of this.store) yield item }
-```
-#### Example
-```js
-const { ChainedSet } = require('chain-able')
-const set = new ChainedSet()
-set.add('eh')
-
-for (const arr of set) {
- const [key, val] = arr
-
- key
- //=> 0
-
- val
- //=> 'eh'
-
- arr.length
- //=> 2
-}
-
-```
----
-
-
-
-
-
-
-
-## `prototype[primitive]`
-
-
-
-# prototype[primitive]()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L646 "View in source") [Ⓣ][1]
-
-Function
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-#### Since
-1.0.2
-
-#### Returns
-*(Primitive)*:
-
-#### Example
-```js
-const chain = new Chain()
-chain.toNumber = () => 1 + chain
-//=> 1
-chain + 1
-//=>
-
-```
-#### Example
-```js
-const chain = new Chain()
-chain.toString = () => 'eh'
-chain + ''
-//=> 'eh'
-
-```
----
-
-
-
-
-
-
-
-## `reduce`
-
-
-
-# reduce()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L1337 "View in source") [Ⓣ][1]
-
-(Function): Map -> Object
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-#### Since
-4.0.0
-
-#### Returns
-*(Object)*: reduced object
-
-#### Example
-```js
-var emptyMap = new Map()
-reduce(emptyMap)
-// => {}
-
-```
-#### Example
-```js
-var map = new Map()
-map.set('eh', 1)
-reduce(map)
-// => {eh: 1}
-
-```
----
-
-
-
-
-
-
-
-## `reduce.prototype`
-
-
-
-# reduce.prototype.clean()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L7692 "View in source") [Ⓣ][1]
-
-(Function): goes through the maps, and the map values, reduces them to array then to an object using the reduced values
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-#### Returns
-*(Object)*: reduced object, without `notReal` values
-
-#### Example
-```js
-const map = new ChainedMap()
-
-map
- .set('emptyArr', [])
- .set('arr', [1])
- .set('nill', null)
- .set('emptyObj', {})
- .set('obj', { keys: true })
-
-clean(map.entries())
-//=> {arr: [1], obj: {keys: true}}
-
-```
----
-
-
-
-
-
-
-
-## `regexp`
-
-
-
-# regexp()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L906 "View in source") [Ⓣ][1]
-
-(Function): Checks if `value` is classified as a `RegExp` object.
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-#### Since
-0.1.0
-
-#### Returns
-*(boolean)*: Returns `true` if `value` is a regexp, else `false`.
-
-#### Example
-```js
-isRegExp(/abc/)
-// => true
-
-isRegExp('/abc/')
-// => false
-
-```
----
-
-
-
-
-
-
-
-## `remove`
-
-
-
-# remove()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2577 "View in source") [Ⓣ][1]
-
-(Function): Remove the current element from the output. If the node is in an Array it will be spliced off. Otherwise it will be deleted from its parent.
-
-#### Returns
-*(void)*:
-
----
-
-
-
-
-
-
-
-## `return`
-
-
-
-# return()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2494 "View in source") [Ⓣ][1]
-
-Function
-
-#### Returns
-*(State)*: see types
-
----
-
-
-
-
-
-
-
-## `schema`
-
-
-
-# schema()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L3686 "View in source") [Ⓣ][1]
-
-(Function): handles: 1. recursively building nestable schemas, 2. creating MethodChains for all types 3. carrying over the inheritable properties 4. @modifies @injects @decorates .add(customValidators)
-
-#### Returns
-*(MethodFactory)*: @chainable
-
----
-
-
-
-
-
-
-
-## `schema.prototype`
-
-
-
-# schema.prototype.typeListFactory()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L3357 "View in source") [Ⓣ][1]
-
-Function
-
-#### Returns
-*(Function)*: validator
-
-#### Example
-```js
-const isStringOrNumber = typeListFactory('string|number')
-
-isStringOrNumber(1)
-//=> true
-isStringOrNumber('one')
-//=> true
-isStringOrNumber(Object)
-//=> false
-
-```
----
-
-
-
-
-
-# schema.prototype.typeValidator()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L3615 "View in source") [Ⓣ][1]
-
-(Function): build a recursive schema for all around runtime type safety
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-
-### @symb
-
-🛂
-#### Since
-4.0.0-beta.1
-
-#### Returns
-*(boolean)*: valid
-
-#### Example
-```js
-const typeValidator = schemaFactory('eh', x => typeof x === 'string')
-
-var isValid = typeValidator('stringy')
-//=> true
-
-var isValid = typeValidator(Number)
-//=> false
-
-```
-#### Example
-```js
-const isNumber = x => typeof x === 'number'
-const typeValidator = schemaFactory('eh', { canada: 'number' })
-
-var isValid = typeValidator({ canada: 1 })
-//=> true
-
-var isValid = typeValidator({})
-//=> false
-
-var isValid = typeValidator({ canada: false })
-//=> false
-
-var isValid = typeValidator(1)
-//=> false
-
-```
----
-
-
-
-
-
-
-
-## `schemaFactory`
-
-
-
-# schemaFactory()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L3573 "View in source") [Ⓣ][1]
-
-(Function): pass the property & schema in, get a nestable typeValidator out
-
-#### Since
-4.0.0-alpha.1
-
-#### Returns
-*(Function)*: typeValidator
-
-#### Example
-```js
-// property name here is `dates`, then `created`, then `at`
-nestedSchema = {
- dates: {
- created: {
- at: 'date',
- },
- },
-}
-
-input = {
- dates: {
- created: {
- at: new Date(),
- },
- },
-}
-
-input = new Date()
-input = {
- dates: {
- mismatch: true,
- },
-}
-
-```
----
-
-
-
-
-
-
-
-## `scopedEncase`
-
-
-
-# scopedEncase()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L3979 "View in source") [Ⓣ][1]
-
-Function
-
-#### Since
-4.0.0-beta.1
-
-#### Returns
-*(Function)*: the method...
-
-#### Example
-```js
-const fnToEncase = arg => arg === true
-const onInvalid = (error, key, arg, instance) => console.log(arguments)
-const onValid = (key, arg, instance) => console.log(arguments)
-const encased = scopedEncase(fnToEncase).onValid(onValid).onInvalid(onInvalid)
-//=> typedOnCall
-
-```
----
-
-
-
-
-
-
-
-## `set`
-
-
-
-# set()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L140 "View in source") [Ⓣ][1]
-
-(Function): Checks if `value` is classified as a `Set` object.
-
-#### Since
-4.3.0
-
-#### Returns
-*(boolean)*: Returns `true` if `value` is a set, else `false`.
-
-#### Example
-```js
-isSet(new Set())
-// => true
-
-isSet(new WeakSet())
-// => false
-
-```
----
-
-
-
-
-
-
-
-## `set$$2`
-
-
-
-# set$$2()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L1620 "View in source") [Ⓣ][1]
-
-Function
-
-#### Since
-4.0.0
-
-#### Returns
-*(void)*:
-
----
-
-
-
-
-
-
-
-## `setChosen`
-
-
-
-# setChosen()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L5311 "View in source") [Ⓣ][1]
-
-(Function): when fn is a full method, not an extended shorthand
-
-#### Since
-0.5.0
-
-#### Returns
-*(*)*: .set or [keyToSet] return
-
-#### Example
-```js
-MergeChain.init(new Chain().extend(['eh']))
-
-//isFunction: true => call parent[keyToSet](valueToSet)
-setChosen('eh', 1)
-//=> parent
-parent.get('eh')
-//=> 1
-
-//=>isFunction: false => parent.set(keyToSet, valueToSet)
-setChosen('oh', 1)
-//=> parent //<- unless .set is overriden
-parent.get('oh')
-//=> 1
-
-```
----
-
-
-
-
-
-# setChosen()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L5353 "View in source") [Ⓣ][1]
-
-(Function): maybe we should not even have `.onExisting`
-since we can just override merge method...
-and then client can just use a custom merger...
-
-
-could add and remove subscriber but that's overhead and
-tricky here, because if we set a value that was just set...
-
----
-
-
-
-
-
-
-
-## `simpleKindOf`
-
-
-
-# simpleKindOf()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L984 "View in source") [Ⓣ][1]
-
-(Function): when Array -> 'array' when null -> 'null' else `typeof x`
-
-#### Returns
-*(string)*: type
-
----
-
-
-
-
-
-
-
-## `state`
-
-
-
-# state
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2505 "View in source") [Ⓣ][1]
-
-(Object): Each method that takes a callback has a context *(its this object)* with these attributes:
-
-
-### @classProps
-
-* {isRoot} @alias isNotRoot Whether or not the present node is a leaf node (has no children)
-
----
-
-
-
-
-
-
-
-## `stop`
-
-
-
-# stop()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2629 "View in source") [Ⓣ][1]
-
-Function
-
-#### Returns
-*(void)*:
-
----
-
-
-
-
-
-
-
-## `test`
-
-
-
-# test
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L6373 "View in source") [Ⓣ][1]
-
-unknown
-
-
-### @todos
-
-- [ ] replace to-test
-
----
-
-
-
-
-
-
-
-## `this.extend`
-
-
-
-# this.extend()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L4436 "View in source") [Ⓣ][1]
-
-Function
-
-#### Example
-```js
-chain
- .method('eh')
- .type(`?string`)
- .type(`string[]`)
- .type(`string|boolean`)
- .type(`boolean[]|string[]`)
- .type(`!date`)
-
-```
----
-
-
-
-
-
-
-
-## `toArr`
-
-
-
-🌊 Types: deps.d
-
-# toArr()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L1514 "View in source") [Ⓣ][1]
-
-(Function): anything into an array
-
-
-### @sig
-
-* => Array
-#### Since
-0.0.1
-
-#### Returns
-*(Array)*: anything into an array
-
-#### Example
-```js
-toarr([])
-// => []
-
-toarr('')
-// => ['']
-
-toarr('1,2')
-// => ['1', '2']
-
-toarr('1,2')
-// => ['1', '2']
-
-const map = new Map()
-map.set('eh', true)
-const arr = toarr(map.entries())
-// => ['eh', true]
-
-const set = new Set()
-set.add('eh')
-set.add(true)
-const arr = toarr(map.entries())
-// => ['eh', true]
-
-toarr('').concat(toarr(false)).concat(toarr(null))
-// => ['', false, null]
-
-```
----
-
-
-
-
-
-
-
-## `toTest`
-
-
-
-# toTest()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L6868 "View in source") [Ⓣ][1]
-
-(Function): like matcher, but .isMatch
-
-
-### @notes
-
-* as else-if for easier ternary uglification
-
-#### Since
-3.0.0
-
-#### Returns
-*(boolean)*: is a match, passes the test
-
-#### Example
-```js
-matcher('kinga', 'kinga')
-//=> true
-matcher('k*nga', 'kinga')
-//=> true
-matcher('kinga', 'nope')
-//=> false
-
-matcher(new RegExp(/kinga/), 'kinga')
-//=> true
-matcher(new RegExp(/kinga/), 'nope')
-//=> false
-
-matcher(x => x === 'kinga', 'kinga')
-//=> true
-matcher(x => x === 'kinga', 'nope')
-//=> false
-
-matcher({ test: x => x === 'kinga' }, 'kinga')
-//=> true
-matcher({ test: x => x === 'kinga' }, 'nope')
-//=> false
-
-```
----
-
-
-
-
-
-
-
-## `traverse`
-
-
-
-# traverse()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2182 "View in source") [Ⓣ][1]
-
-(Function): {@link https://sourcemaking.com/design_patterns/chain_of_responsibility chainofresponsibility}
-
-#### Example
-```js
-traverse({})
-//=> new Traverse(obj)
-
-```
----
-
-
-
-
-
-# traverse()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L7127 "View in source") [Ⓣ][1]
-
-(Function): traverse `this`, or `this.entries`
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-#### Since
-1.0.2
-
-#### Returns
-*(TraverseChain)*: @chainable
-
-#### Example
-```js
-TAKE FROM TRAVERSECHAIN
-```
----
-
-
-
-
-
-
-
-## `traverse.prototype`
-
-
-
-* 🌊 Types: TraverseChain.d
-* 🌊 Types: traverse.d
-
-# traverse.prototype.eq()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L6030 "View in source") [Ⓣ][1]
-
-(Function): deep traversal of nodes to compare any data types does not check reference, only value equality
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-
-### @symb
-
-⚖️
-#### Since
-3.0.0
-
-#### Returns
-*(boolean)*: isEqual
-
-#### Example
-```js
-eq(1, 1)
-//=> true
-
-eq(true, false)
-//=> false
-
-eq({}, {})
-//=> true
-
-```
-#### Example
-```js
-eq(
- { d: new Date(0, 0, 0, 0), x: [1, 2, 3] },
- { d: new Date(0, 0, 0, 0), x: [1, 2, 3] }
-)
-//=> true
-
-eq([new RegExp('x')], [/x/])
-//=> true
-
-eq([new String('x')], ['x'])
-//=> true
-
-eq([new Boolean(false)], [false])
-//=> true
-
-eq([undefined], [null]) || eq(undefined, null)
-//=> false
-
-```
-#### Example
-```js
-var xs = [1, 2, 3, 4]
-delete xs[2]
-
-var ys = Object.create(Array.prototype)
-ys[0] = 1
-ys[1] = 2
-ys[3] = 4
-
-eq(xs, ys)
-//=> true
-
-eq(xs, [1, 2, undefined, 4])
-//=> false
-
-```
----
-
-
-
-
-
-
-
-## `traversed`
-
-
-
-# traversed()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L7075 "View in source") [Ⓣ][1]
-
-(Function): value traversed in traverse
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-#### Since
-1.0.0
-
-#### Returns
-*(*)*: traversed
-
-#### Example
-```js
-const traverser = new Traverser()
-traverser.obj(['duck', 'duck', 'goose'])
-traverser.vals(['g**se'])
-traverser.traverse()
-
-traverser.traversed()
-//=> ['goose']
-
-```
-#### Example
-```js
-const eh = {
- me: true,
- nested: {
- really: {
- deep: {
- super: false,
- not: 'eh',
- canada: true,
- modules: [{parser: 'hi'}],
- },
- matchme: 'minime',
- notme: 'eh',
- },
- },
- }
-
- const chain = new Chain()
- Object.assign(chain, eh)
-
- const traverser = chain
- .merge(eh)
- .traverse(true)
- .keys([/super/, /parser/, /store/, /meta/])
- .vals([/minime/])
- .call(false)
-
- traverser.traversed()
- //=> {
- className: 'DotProp',
- me: true,
- nested: {
- really: {
- deep: {
- not: 'eh',
- canada: true,
- modules: [{}],
- },
- notme: 'eh',
- },
- },
- }
-```
----
-
-
-
-
-
-
-
-## `tryCatch`
-
-
-
-# tryCatch()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L3863 "View in source") [Ⓣ][1]
-
-Function
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-#### Returns
-*(*)*: validation/encased function call result
-
----
-
-
-
-
-
-
-
-## `typedOnCall`
-
-
-
-# typedOnCall()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L4013 "View in source") [Ⓣ][1]
-
-(Function): this is the actual built function
-
-#### Since
-4.0.0-beta.1
-
-#### Returns
-*(Function): typedOnCall(argToValidate: any)*
-
-#### Example
-```js
-const encased = encase(fnToEncase)
- .onValid()
- .onInvalid(function)
- .call()
-```
----
-
-
-
-
-
-
-
-## `types`
-
-
-
-# types()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L4051 "View in source") [Ⓣ][1]
-
-Function
-
-#### Returns
-*(void)*:
-
----
-
-
-
-
-
-
-
-## `update`
-
-
-
-# update()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2556 "View in source") [Ⓣ][1]
-
-(Function): Set a new value for the present node.
-All the elements in value will be recursively traversed unless stopHere is true.
-
-#### Returns
-*(void)*:
-
----
-
-
-
-
-
-
-
-## `updateState`
-
-
-
-# updateState()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2653 "View in source") [Ⓣ][1]
-
-(Function): updates if needed:
-
-#### Returns
-*(void)*:
-
----
-
-
-
-
-
-
-
-## `validators`
-
-
-
-# validators
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L3271 "View in source") [Ⓣ][1]
-
-unknown
-
----
-
-
-
-
-
-
-
-## `values`
-
-
-
-# values()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L600 "View in source") [Ⓣ][1]
-
-(Function): spreads the entries from ChainedMap.store.values allocates a new array, adds the values from the iterator
-
-
-### @see
-
-* fluents/chain able/blob/master/src/deps/reduce/clean.js
-
-### @notes
-
-* look at Chainable.constructor to ensure not to use `new Array...`
-* moved from ChainedMap and ChainedSet to Chainable @2.0.2
-* this was [...] & Array.from(this.store.values())
-
-{@link https://kangax.github.io/compat-table/es6/#test-Array_static_methods compat-array-static-methods}
-{@link https://stackoverflow.com/questions/20069828/how-to-convert-set-to-array set-to-array}
-{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/values mozilla-map-values}
-{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/values mozilla-set-values}
-
-#### Since
-0.4.0
-
-#### Returns
-*(*): toArr(this.store.values())*
-
-#### Example
-```js
-const chain = new Chain()
-chain.set('eh', 1)
-chain.values()
-//=> [1]
-
-```
----
-
-
-
-
-
-
-
-## `when`
-
-
-
-# when()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L458 "View in source") [Ⓣ][1]
-
-(Function): when the condition is true, trueBrancher is called, else, falseBrancher is called
-
-#### Returns
-*(Chainable)*: @chainable
-
-#### Example
-```js
-const prod = process.env.NODE_ENV === 'production'
-chains.when(prod, c => c.set('prod', true), c => c.set('prod', false))
-
-```
----
-
-
-
-
-
-
-
-## `while`
-
-
-
-# while()
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/dists/dev/index.js#L2883 "View in source") [Ⓣ][1]
-
-Function
-
-#### Example
-```js
-1
-'.eh' - 1 === '\\'(true) + 1 !== undefined(true, eh)
-
-```
-#### Example
-```js
-2
-'.eh' - 1 === '\\'(false, undefined) + 1 !== undefined(true, eh)
-
-```
-#### Example
-```js
-3
-'.' - 1 === '\\'(true) + 1 !== undefined(false, eh)
-
-```
----
-
-
-
-
-
-
-
- [1]: #/* istanbul ignore next "Jump back to the TOC."
diff --git a/docs/docdown/plugins/autoGetSet.md b/docs/docdown/plugins/autoGetSet.md
index d186a7f..e2d3187 100644
--- a/docs/docdown/plugins/autoGetSet.md
+++ b/docs/docdown/plugins/autoGetSet.md
@@ -4,8 +4,8 @@
-## `MethodChain.prototype`
-* `MethodChain.prototype.autoGetSet`
+## `MethodChain`
+* `MethodChain.autoGetSet`
@@ -15,19 +15,21 @@
-## `MethodChain.prototype`
+## `MethodChain`
-# MethodChain.prototype.autoGetSet(name=undefined, parent=undefined)
+MethodChain.autoGetSet(name=undefined, parent=undefined)
+
+
[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/plugins/autoGetSet.js#L24 "View in source") [Ⓣ][1]
Function
-### @see
+#### @see
-* fluents/chain able/blob/master/src/method chain.js
+* MethodChain
#### Arguments
1. `name=undefined` *(Primitive)*: method name being built
2. `parent=undefined` *(Object)*: parent containing the method
@@ -54,4 +56,4 @@ chain.eh()
- [1]: #methodchain.prototype "Jump back to the TOC."
+ [1]: #methodchain "Jump back to the TOC."
diff --git a/docs/docdown/plugins/autoIncrement.md b/docs/docdown/plugins/autoIncrement.md
index 40fbc2e..cf1ab44 100644
--- a/docs/docdown/plugins/autoIncrement.md
+++ b/docs/docdown/plugins/autoIncrement.md
@@ -5,7 +5,7 @@
## `exports`
-* `exports`
+* `exports`
@@ -19,7 +19,9 @@
-# exports(name=undefined, parent=undefined)
+exports(name=undefined, parent=undefined)
+
+
[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/plugins/autoIncrement.js#L7 "View in source") [Ⓣ][1]
Function
diff --git a/docs/docdown/plugins/decorate.md b/docs/docdown/plugins/decorate.md
index 436881b..62fbf48 100644
--- a/docs/docdown/plugins/decorate.md
+++ b/docs/docdown/plugins/decorate.md
@@ -4,8 +4,8 @@
-## `MethodChain.prototype`
-* `MethodChain.prototype.exports`
+## `MethodChain`
+* `MethodChain.exports`
@@ -15,28 +15,31 @@
-## `MethodChain.prototype`
+## `MethodChain`
-# MethodChain.prototype.exports(parentToDecorate=undefined)
-[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/plugins/decorate.js#L29 "View in source") [Ⓣ][1]
+MethodChain.exports(parentToDecorate=undefined)
+
+
+[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/plugins/decorate.js#L28 "View in source") [Ⓣ][1]
(Function): decorates a parent when the argument is provided
BUT THE FUNCTIONS WILL STILL BE SCOPED TO CURRENT PARENT
for easy factory chaining
-### @see
+#### @see
-* fluents/chain able/blob/master/src/method chain.js
+* MethodChain
-### @todos
+#### @todos
- [ ] this is more like a preset since it *adds* plugins?
more of methodFactory now
-#### Since
+
+#### @Since
4.0.0-alpha.1
#### Arguments
@@ -62,4 +65,4 @@ typeof obj.ehOh
- [1]: #methodchain.prototype "Jump back to the TOC."
+ [1]: #methodchain "Jump back to the TOC."
diff --git a/docs/docdown/plugins/encase.md b/docs/docdown/plugins/encase.md
index ec75522..d31dda2 100644
--- a/docs/docdown/plugins/encase.md
+++ b/docs/docdown/plugins/encase.md
@@ -5,21 +5,21 @@
## `methodEncasingFactory`
-* `methodEncasingFactory`
+* `methodEncasingFactory`
## `scopedEncase`
-* `scopedEncase`
+* `scopedEncase`
## `typedOnCall`
-* `typedOnCall`
+* `typedOnCall`
@@ -33,7 +33,11 @@
-# methodEncasingFactory(name=undefined, parent=undefined, built=undefined)
+🌊 Types: deps.encase.d
+
+methodEncasingFactory(name=undefined, parent=undefined, built=undefined)
+
+
[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/plugins/encase.js#L30 "View in source") [Ⓣ][1]
(Function): 3 steps
@@ -42,10 +46,11 @@
2. build a function to call onInvalid or onInvalid depending
-### @symb
+#### @symb
⛑🏭
-#### Since
+
+#### @Since
4.0.0
#### Arguments
@@ -74,12 +79,15 @@ methodEncasingFactory('eh', {}, { onSet: console.log })
-# scopedEncase(fnToEncase=undefined, [type=undefined], [specification=undefined])
+scopedEncase(fnToEncase=undefined, [type=undefined], [specification=undefined])
+
+
[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/plugins/encase.js#L53 "View in source") [Ⓣ][1]
Function
-#### Since
+
+#### @Since
4.0.0-beta.1
#### Arguments
@@ -111,12 +119,15 @@ const encased = scopedEncase(fnToEncase).onValid(onValid).onInvalid(onInvalid)
-# typedOnCall(arg=undefined)
+typedOnCall(arg=undefined)
+
+
[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/plugins/encase.js#L87 "View in source") [Ⓣ][1]
(Function): this is the actual built function
-#### Since
+
+#### @Since
4.0.0-beta.1
#### Arguments
diff --git a/docs/docdown/plugins/getterOnSet.md b/docs/docdown/plugins/getterOnSet.md
new file mode 100644
index 0000000..875d05a
--- /dev/null
+++ b/docs/docdown/plugins/getterOnSet.md
@@ -0,0 +1,11 @@
+# getterOnSet.js API documentation
+
+
+
+
+
+
+
+
+
+ [1]: # "Jump back to the TOC."
diff --git a/docs/docdown/plugins/schema.md b/docs/docdown/plugins/schema.md
index 5129520..4dd4a45 100644
--- a/docs/docdown/plugins/schema.md
+++ b/docs/docdown/plugins/schema.md
@@ -5,7 +5,7 @@
## `exports`
-* `exports`
+* `exports`
@@ -19,7 +19,9 @@
-# exports(obj=undefined)
+exports(obj=undefined)
+
+
[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/plugins/schema.js#L37 "View in source") [Ⓣ][1]
(Function): handles: 1. recursively building nestable schemas, 2. creating MethodChains for all types 3. carrying over the inheritable properties 4. @modifies @injects @decorates .add(customValidators)
diff --git a/docs/docdown/plugins/types.md b/docs/docdown/plugins/types.md
index 7ca91d7..0513fd0 100644
--- a/docs/docdown/plugins/types.md
+++ b/docs/docdown/plugins/types.md
@@ -5,7 +5,7 @@
## `exports`
-* `exports`
+* `exports`
@@ -19,7 +19,9 @@
-# exports(name=undefined, parent=undefined, built=undefined)
+exports(name=undefined, parent=undefined, built=undefined)
+
+
[Ⓢ](https://github.com/fluents/chain-able/blob/master/src/plugins/types.js#L18 "View in source") [Ⓣ][1]
Function
diff --git a/docs/examples/readme.md b/docs/examples/readme.md
index 8a9b8f1..b2e895c 100644
--- a/docs/examples/readme.md
+++ b/docs/examples/readme.md
@@ -1,34 +1,73 @@
+- [🔗 playground - super small files using features - adapted from tests](https://aretecode.github.io/chain-able-playground/)
+- [🔗 jsfiddle with Inferno](https://jsfiddle.net/wqxuags2/28/)
+
+
## who uses it?
+
+
- [fliplog][fliplog]: fluent logging with verbose insight, colors, tables, emoji, filtering, spinners, progress bars, timestamps, capturing, stack traces, tracking, presets, & more...
- [lego-api][lego-api] renders the infinitely nestable permutations of conditionals for [fuse-box][fuse-box] so only what you use is included in the bundled api
- [d-l-l][d-l-l] makes your webpack build faster, in just a few lines, without having to waste time with the tedious manual configuration steps required to use the DLLPlugin
- [webpack-split-plugin][webpack-split-plugin] easily split bundles into multiple pieces with custom specifications
- [bench-chain][bench-chain] benchmark recording - averages & graphs.
- [cli-chain][cli-chain] easy, powerful, interactive, infinitely nestable fluent cli builder.
-- [awesome-fluents][awesome-fluents] more awesome fluents/chains
+- [awesome-fluents][awesome-fluents] more awesome fluents/chains.
- [funwithflags][funwithflags] parse argument options. minimist in es6.
- [chain-able-find][chain-able-find] globby-compatible api, faster, & fluent.
+- [chain-able-md][chain-able-md] markdown builder with a fluent api, used to create chain-able docs.
+- [frisbee-chain][frisbee-chain] fetch api enhancer with Frisbee, as-a-chain.
+
+
## [examples](https://github.com/fluents/chain-able/tree/master/examples)
-- [playground - super small files using features - adapted from tests](https://aretecode.github.io/chain-able-playground/)
- - data type + schema
- - define
- - encase
- - merging
- - observing
- - LocalStorage
+- `MethodChain` _examples using method chains_
+ - [data type + schema][schema]
+ - [define][define]
+ - [encase][encase]
+ - [merging][merging]
+ - [compose][compose]
+ - [observing][observe]
-- minis - really mini projects for examples
- - decorators (making a chain that can be used to build decorators that work for all combinations*)
- - SwitchChain - making `switch {}` as a chain for fun
-- typescript (for intelisense demo)
-- decorators (for es6 transpiling experimenting)
-- bundler configs (works by default, but easier the better)
-- eventually (todo):
- - Events - will be an eventsource example
- - React & MobX
- - Routing
- - FileSystem stuff on nodejs
+- **minis** _really mini projects for examples_
+ - [`DecoratorChain`][DecoratorChain] (making a chain that can be used to build decorators that work for all combinations*)
+ - [`SwitchChain`][SwitchChain] - making `switch(condition) {}` as-a-chain, for fun
+ - [`RegExpChain`][RegExpChain] - _fluent RegExp building with english words instead of symbols_
+ - [`ObjectDefineChain`][ObjectDefineChain] - _simple example with `Object.define` as-a-chain_
+- [typescript][examples_ts] (_for intelisense demo_)
+- [decorators][examples_decorators] (for es6 transpiling experimenting)
+- **State**
+ - [Inferno/React state][examples_react_state] (_for intelisense demo_)
+ - [TodoStore][TodoStore] (_react state store as a todostore_)
+ - [LocalStorage][localStorage]
+- **nodejs**
+ - [Comments][examples_commentchain] (_another schema example_)
+- @TODO:
+ - Events: _an eventsource example_
+ - chain-able-fs: _FileSystem stuff on nodejs_
+ - Proxy: _minimal easy creation of chain-able with Proxies, slower, but shorter_
+ - React & MobX: _more state chain examples_
+ - Routing: _browser html routing, as a module later_
+
+
+[chain-able-md]: https://github.com/fluents/chain-able/blob/master/_modules/_chain-able-md/src/index.js
+[webpack-split-plugin]: https://github.com/aretecode/webpack-split-plugin
+[frisbee-chain]: https://github.com/fluents/chain-able/tree/master/examples
+[examples_commentchain]: https://github.com/fluents/chain-able/tree/master/examples/packages/node/index.js
+[localStorage]: https://github.com/fluents/chain-able/tree/master/examples/packages/playground/localStorage.js
+[compose]: https://github.com/fluents/chain-able/tree/master/examples/packages/playground/compose.js
+[observe]: https://github.com/fluents/chain-able/tree/master/examples/packages/playground/observe.js
+[define]: https://github.com/fluents/chain-able/tree/master/examples/packages/playground/define.js
+[encase]: https://github.com/fluents/chain-able/tree/master/examples/packages/playground/encase.js
+[merging]: https://github.com/fluents/chain-able/tree/master/examples/packages/playground/merge.js
+[schema]: https://github.com/fluents/chain-able/tree/master/examples/packages/playground/schema.js
+[TodoStore]: https://github.com/fluents/chain-able/tree/master/examples/packages/playground/TodoStore.js
+[examples_react_state]: examples_react_state
+[examples_decorators]: examples_decorators
+[examples_ts]: examples_ts
+[DecoratorChain]: https://github.com/fluents/chain-able/tree/master/examples/packages/minis/DecoratorChain.js
+[ObjectDefineChain]: https://github.com/fluents/chain-able/tree/master/examples/packages/minis/ObjectDefineChain.js
+[SwitchChain]: https://github.com/fluents/chain-able/tree/master/examples/packages/minis/SwitchChain.js
+[RegExpChain]: https://github.com/fluents/chain-able/tree/master/examples/packages/minis/RegExp.js
[d-l-l]: https://github.com/fliphub/d-l-l
[chain-able-find]: https://github.com/fluents/chain-able-find
diff --git a/examples/packages/minis/decorators.js b/examples/packages/minis/DecoratorChain.js
similarity index 100%
rename from examples/packages/minis/decorators.js
rename to examples/packages/minis/DecoratorChain.js
diff --git a/examples/packages/minis/ObjectDefineChain.js b/examples/packages/minis/ObjectDefineChain.js
new file mode 100644
index 0000000..b44a46d
--- /dev/null
+++ b/examples/packages/minis/ObjectDefineChain.js
@@ -0,0 +1,149 @@
+const {Chain, isUndefined, isFunction, isObj, isReal, isBoolean} = require('../../../src')
+
+const booleanMethods = ['configurable', 'enumerable']
+const allReal = x => x.filter(isReal).length === x.length
+
+// @TODO: all statics
+class ObjectDefineChain extends Chain {
+ constructor(parent) {
+ super(parent)
+
+ // normal methods
+ this
+ .methods(['obj', 'value', 'prop'])
+ .build()
+
+ const onInvalid = () => {
+ console.log('must provide a boolean to ' + booleanMethods.join(','))
+ }
+
+ // default all params to `true` and all initial values `true`
+ this
+ .methods(booleanMethods)
+ .default(true)
+ .initial(true)
+ .type('boolean')
+ .onInvalid(onInvalid)
+ .build()
+
+ // do not want to define writable by default,
+ // it is different since you cannot use it with get set
+ this
+ .method('writable')
+ .type('boolean')
+ .onInvalid(onInvalid)
+ .build()
+
+ // --------
+ // only needed because get & set are keywords for chainable/maps
+ const get = this.get.bind(this)
+ const set = this.set.bind(this)
+
+ this.get = keyOrFunction => {
+ // setting `.get`
+ if (isFunction(keyOrFunction)) {
+ return set('get', keyOrFunction)
+ }
+ // normal `key`
+ else {
+ return get(keyOrFunction)
+ }
+ }
+
+ // if we pass in `function` without `value` = `set`
+ this.set = (keyOrFunction, value) => {
+ if (isUndefined(value) && isFunction(keyOrFunction)) {
+ return set('set', keyOrFunction)
+ }
+ else {
+ // console.log('HAD VALUE DAMNIT', value)
+ return set(keyOrFunction, value)
+ }
+ }
+ }
+
+ descriptor(descriptor) {
+ return this.from(descriptor)
+ }
+
+ // @TODO validate on development env when using .get & .set & .value
+ // when we pass in an object, it can be the shorthand way to do a define
+ define(optionalObj) {
+ if (isObj(optionalObj)) this.obj(optionalObj)
+
+ const {
+ obj,
+ configurable,
+ enumerable,
+ writable,
+ set,
+ get,
+ value,
+ prop,
+ } = this.entries()
+
+ const descriptor = {configurable, enumerable}
+
+ // could also do
+ // this.observe(['get', 'set', 'value'], x => {
+ // if (x.get && x.set && x.value) {
+ // throw new Error('cannot provide get set and value')
+ // }
+ // })
+ //
+ // debug
+ if (this.get('debug')) {
+ if (allReal([get, set, value])) {
+ throw new Error('cannot provide get set and value')
+ }
+ }
+
+ // can only use .value or .get + .set
+ if (isFunction(get)) descriptor.get = get
+ if (isFunction(set)) descriptor.set = set
+ if (isReal(value)) descriptor.value = value
+ if (isBoolean(writable)) descriptor.writable = writable
+
+ Object.defineProperty(obj, prop, descriptor)
+ return this
+ }
+}
+
+
+const invalidD = new ObjectDefineChain()
+const getSetD = new ObjectDefineChain()
+const fromD = new ObjectDefineChain()
+
+function onGet() {}
+function onSet() {}
+const value = true
+const obj = {}
+
+try {
+ invalidD
+ .debug(true)
+ .value(value)
+ .get(onGet)
+ .set(onSet)
+ .define(obj)
+}
+catch (e) {
+
+}
+
+getSetD
+ .configurable()
+ .enumerable()
+ .prop('eh')
+ .get(onGet)
+ .set(onSet)
+ .define(obj)
+
+fromD
+ .prop('from')
+ .descriptor({value: true, writable: true, enumerable: false})
+ .define(obj)
+
+
+require('fliplog').data({obj}).echo()
+//=> obj: { eh: [Getter/Setter], from: true } }
diff --git a/examples/packages/minis/RegExp.js b/examples/packages/minis/RegExp.js
new file mode 100644
index 0000000..4174d61
--- /dev/null
+++ b/examples/packages/minis/RegExp.js
@@ -0,0 +1,505 @@
+// https://github.com/thebinarysearchtree/regexpbuilderjs
+// https://github.com/VerbalExpressions/JSVerbalExpressions
+const {Chain, isUndefined, isString, isEmpty} = require('chain-able')
+
+function sanitize(s) {
+ return s.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, '\\$1')
+}
+
+const lettersUpperCase = 'A-Z'
+const lettersLowerCase = 'a-z'
+const lettersUpperAndLower = lettersUpperCase + lettersLowerCase
+const digit = '(?:\\d)'
+const nonDitit = '(?:\\D)'
+const start = '(?:^)'
+const end = '(?:$)'
+const newLine = '(?:\\r\\n|\\r|\\n)'
+
+class RegExpBuilder extends Chain {
+ constructor(parent) {
+ super()
+
+ // this.methods(['flags', 'literal']).autoGetSet().build()
+ this.method('groupsUsed').autoIncrement().build()
+
+ // -------
+ // string type so adding is autoMerge plugin type thing :-)
+ this.flags = arg => {
+ if (isUndefined(arg)) return this.get('flags')
+ const flags = this.get('flags') + arg
+ return this.set('flags', flags)
+ }
+ // default/initial
+ this.set('flags', '')
+ // -------
+ // -------
+ this.addLiteral = this.literal = arg => {
+ if (isUndefined(arg)) return this.get('literal')
+ const literal = this.get('literal').push(arg)
+ return this.set('literal', literal)
+ }
+ this.set('literal', [])
+ // -------
+
+ this.transform(['of', ''], sanitize)
+
+ // this._flags = ''
+ // this._literal = []
+ // this._groupsUsed = 0
+
+ this._clear()
+ }
+
+ // ------------------ data ------------------
+
+ // -------------- config --------------
+
+ neither(r) {
+ if (isString(r)) {
+ return this.notAhead(new RegExpBuilder().exactly(1).of(r))
+ }
+ return this.notAhead(r)
+ }
+
+ nor(r) {
+ if (this.get('min') === 0 && this.get('ofAny')) {
+ this.min(-1).ofAny(false)
+ }
+
+ return this.neither(r).min(0).ofAny()
+ }
+
+ exactly(n) {
+ return this._flushState().min(n).max(n)
+ }
+
+ optional(r) {
+ this.max(1)
+ const like = this._combineGroupNumberingAndGetLiteral(r)
+ return this.like(like)
+ }
+
+ ignoreCase() {
+ return this._addFlag('i')
+ }
+
+ multiLine() {
+ return this._addFlag('m')
+ }
+
+ globalMatch() {
+ return this._addFlag('g')
+ }
+
+ startOfInput() {
+ return this.addLiteral()
+ }
+
+ startOfLine() {
+ return this.multiLine().startOfInput()
+ }
+
+ endOfInput() {
+ return this._flushState().addLiteral(end)
+ }
+
+ endOfLine() {
+ return this.multiLine().endOfInput()
+ }
+
+ either(r) {
+ if (isString(r)) {
+ return this._eitherLike(new RegExpBuilder().exactly(1).of(r))
+ }
+ else {
+ return this._eitherLike(r)
+ }
+ }
+
+ or(r) {
+ if (isString(r)) {
+ return this._orLike(new RegExpBuilder().exactly(1).of(r))
+ }
+ else {
+ return this._orLike(r)
+ }
+ }
+
+ min(min) {
+ return this._flushState().set('min', min)
+ }
+
+ max(max) {
+ return this._flushState().set('max', max)
+ }
+
+ of(s) {
+ return this.set('of', s)
+ // this._of = this._sanitize(s)
+ // return this
+ }
+
+ ofAny(ofAny = true) {
+ return this.set('ofAny', ofAny)
+ }
+
+ ofGroup(n) {
+ return this.set('ofGroup', n)
+ }
+
+ from(s) {
+ const from = this._sanitize(s.join(''))
+ return this.set('from', from)
+ }
+ notFrom(s) {
+ const notFrom = this._sanitize(s.join(''))
+ return this.set('notFrom', notFrom)
+ }
+
+ like(r) {
+ const like = this._combineGroupNumberingAndGetLiteral(r)
+ return this.set('like', like)
+ }
+
+ reluctantly() {
+ return this.set('reluctant', true)
+ }
+
+ ahead(r) {
+ return this._flushState().addLiteral(
+ '(?=' + this._combineGroupNumberingAndGetLiteral(r) + ')'
+ )
+ }
+
+ notAhead(r) {
+ this._flushState()
+ this.addLiteral('(?!' + this._combineGroupNumberingAndGetLiteral(r) + ')')
+ return this
+ }
+
+ asGroup() {
+ return this.groupsUsed(+1).set('capture', true)
+ }
+
+ then(s) {
+ return this.exactly(1).of(s)
+ }
+
+ find(s) {
+ return this.then(s)
+ }
+
+ some(s) {
+ return this.min(1).from(s)
+ }
+
+ maybeSome(s) {
+ return this.min(0).from(s)
+ }
+
+ maybe(s) {
+ return this.max(1).of(s)
+ }
+
+ something() {
+ return this.min(1).ofAny()
+ }
+
+ anything() {
+ return this.min(0).ofAny()
+ }
+
+ anythingBut(s) {
+ if (s.length === 1) {
+ return this.min(0).notFrom([s])
+ }
+
+ this.notAhead(new RegExpBuilder().exactly(1).of(s))
+ return this.min(0).ofAny()
+ }
+
+ any() {
+ return this.exactly(1).ofAny()
+ }
+
+ lineBreak() {
+ return this._flushState().addLiteral(newLine)
+ }
+
+ lineBreaks() {
+ return this.like(new RegExpBuilder().lineBreak())
+ }
+
+ whitespace() {
+ const min = this.get('min')
+ const max = this.get('max')
+
+ if (min === -1 && max === -1) {
+ return this._flushState().addLiteral('(?:\\s)')
+ }
+
+ return this.set('like', '\\s')
+ }
+
+ notWhitespace() {
+ const min = this.get('min')
+ const max = this.get('max')
+
+ if (min === -1 && max === -1) {
+ return this._flushState().addLiteral('(?:\\S)')
+ }
+
+ return this.like('\\S')
+ }
+
+ tab() {
+ return this._flushState().addLiteral('(?:\\t)')
+ }
+
+ tabs() {
+ return this.like(new RegExpBuilder().tab())
+ }
+
+ digit() {
+ return this._flushState().addLiteral(digit)
+ }
+
+ notDigit() {
+ return this._flushState().addLiteral(nonDitit)
+ }
+
+ digits() {
+ return this.like(new RegExpBuilder().digit())
+ }
+
+ notDigits() {
+ return this.like(new RegExpBuilder().notDigit())
+ }
+
+ letter() {
+ return this.exactly(1).letters()
+ }
+ letters() {
+ return this.set('from', lettersUpperAndLower)
+ }
+
+ notLetter() {
+ return this.exactly(1).notLetters()
+ }
+ notLetters() {
+ return this.set('notFrom', 'A-Za-z')
+ }
+
+ lowerCaseLetter() {
+ return this.exactly(1).lowerCaseLetters()
+ }
+ lowerCaseLetters() {
+ return this.set('from', 'a-z')
+ }
+
+ upperCaseLetter() {
+ return this.exactly(1).upperCaseLetters()
+ }
+ upperCaseLetters() {
+ return this.set('from', 'A-Z')
+ }
+
+ append(r) {
+ this.exactly(1)
+ this._like = this._combineGroupNumberingAndGetLiteral(r)
+ return this
+ }
+
+ // --------------------------------------
+ // ----------- private ------------------
+ // --------------------------------------
+
+ _clear() {
+ // @TODO would be better as .delete
+ return this.min(-1)
+ .max(-1)
+ .of('')
+ .ofAny(false)
+ .ofGroup(-1)
+ .from('')
+ .notFrom('')
+ .like('')
+ .either('')
+ .reluctant(false)
+ .capture(false)
+ }
+
+ _flushState() {
+ const _of = this.get('of')
+ const ofAny = this.get('ofAny')
+ const ofGroup = this.get('ofGroup')
+ const notFrom = this.get('notFrom')
+ const from = this.get('from')
+ const like = this.get('like')
+ const capture = this.get('capture')
+ const reluctant = this.get('reluctant')
+
+ const hasValidState =
+ ofAny ||
+ ofGroup > 0 ||
+ !isEmpty(_of) ||
+ !isEmpty(from) ||
+ !isEmpty(notFrom) ||
+ !isEmpty(like)
+
+ if (hasValidState) {
+ const captureLiteral = capture ? '' : '?:'
+ const reluctantLiteral = reluctant ? '?' : ''
+ const quantityLiteral = this._getQuantityLiteral()
+ const characterLiteral = this._getCharacterLiteral()
+
+ const literal =
+ '(' +
+ captureLiteral +
+ '(?:' +
+ characterLiteral +
+ ')' +
+ quantityLiteral +
+ reluctantLiteral +
+ ')'
+
+ this.addLiteral(literal)
+ this._clear()
+ }
+ }
+
+ _getQuantityLiteral() {
+ const min = this.get('min')
+ const max = this.get('max')
+
+ if (min !== -1) {
+ if (max !== -1) {
+ return '{' + min + ',' + max + '}'
+ }
+ return '{' + min + ',}'
+ }
+ else {
+ return '{0,' + max + '}'
+ }
+ }
+
+ _getCharacterLiteral() {
+ if (!isEmpty(this.get('of'))) {
+ return this.get('of')
+ }
+ else if (this.get('ofAny')) {
+ return '.'
+ }
+ else if (this.get('ofGroup') > 0) {
+ return '\\' + this.get('ofGroup')
+ }
+ else if (!isEmpty(this.get('from'))) {
+ return '[' + this.get('from') + ']'
+ }
+ else if (!isEmpty(this.get('notFrom'))) {
+ return '[^' + this.get('notFrom') + ']'
+ }
+ else if (!isEmpty(this.get('like'))) {
+ return this.get('like')
+ }
+ }
+
+ getLiteral() {
+ return this._flushState().get('literal').join('')
+ }
+
+ _combineGroupNumberingAndGetLiteral(r) {
+ const literal = this._incrementGroupNumbering(
+ r.getLiteral(),
+ this.get('groupsUsed')
+ )
+ this.tap('groupsUsed', used => used + r._groupsUsed)
+ return literal
+ }
+
+ _incrementGroupNumbering(literal, increment) {
+ if (increment > 0) {
+ literal = literal.replace(/[^\\]\\\d+/g, function(groupReference) {
+ const groupNumber = parseInt(groupReference.substring(2)) + increment
+ return groupReference.substring(0, 2) + groupNumber
+ })
+ }
+ return literal
+ }
+
+ getRegExp() {
+ this._flushState()
+
+ const literal = this.get('literal').join('')
+ const flags = this.get('flags')
+ return new RegExp(literal, flags)
+ }
+
+ _addFlag(flag) {
+ const flags = this.get('flags')
+ if (!flags.includes(flag)) this.addFlag(flag)
+
+ return this
+ }
+
+ _eitherLike(r) {
+ this._flushState()
+ const eitherLike = this._combineGroupNumberingAndGetLiteral(r)
+ return this.either(eitherLike)
+ }
+
+ _orLike(r) {
+ const either = this.get('either')
+ const or = this._combineGroupNumberingAndGetLiteral(r)
+
+ if (isEmpty(either)) {
+ const literal = this.getLiteral()
+ let lastLiteralIndex = lastIndex(literal)
+ let lastOr = literal[lastLiteralIndex]
+ lastOr = lastOr.substring(0, lastLiteralIndex)
+
+ literal[lastLiteralIndex] = lastOr
+ this.addLiteral('|(?:' + or + '))')
+ }
+ else {
+ this.addLiteral('(?:(?:' + either + ')|(?:' + or + '))')
+ }
+
+ return this._clear()
+ }
+}
+
+RegExpBuilder.ignoreCase = () => new RegExpBuilder().ignoreCase()
+RegExpBuilder.multiLine = () => new RegExpBuilder().multiLine()
+RegExpBuilder.globalMatch = () => new RegExpBuilder().globalMatch()
+RegExpBuilder.startOfInput = () => new RegExpBuilder().startOfInput()
+RegExpBuilder.startOfLine = () => new RegExpBuilder().startOfLine()
+RegExpBuilder.endOfInput = () => new RegExpBuilder().endOfInput()
+RegExpBuilder.endOfLine = () => new RegExpBuilder().endOfLine()
+RegExpBuilder.either = (r) => new RegExpBuilder().either(r)
+RegExpBuilder.neither = (r) => new RegExpBuilder().neither(r)
+RegExpBuilder.exactly = (n) => new RegExpBuilder().exactly(n)
+RegExpBuilder.min = (n) => new RegExpBuilder().min(n)
+RegExpBuilder.max = (n) => new RegExpBuilder().max(n)
+RegExpBuilder.ahead = (r) => new RegExpBuilder().ahead(r)
+RegExpBuilder.notAhead = (r) => new RegExpBuilder().notAhead(r)
+RegExpBuilder.then = (s) => new RegExpBuilder().then(s)
+RegExpBuilder.find = (s) => new RegExpBuilder().find(s)
+RegExpBuilder.some = (s) => new RegExpBuilder().some(s)
+RegExpBuilder.maybeSome = (s) => new RegExpBuilder().maybeSome(s)
+RegExpBuilder.maybe = (s) => new RegExpBuilder().maybe(s)
+RegExpBuilder.anything = () => new RegExpBuilder().anything()
+RegExpBuilder.anythingBut = (s) => new RegExpBuilder().anythingBut(s)
+RegExpBuilder.any = () => new RegExpBuilder().any()
+RegExpBuilder.lineBreak = () => new RegExpBuilder().lineBreak()
+RegExpBuilder.whitespace = () => new RegExpBuilder().whitespace()
+RegExpBuilder.notWhitespace = () => new RegExpBuilder().notWhitespace()
+RegExpBuilder.tab = () => new RegExpBuilder().tab()
+RegExpBuilder.digit = () => new RegExpBuilder().digit()
+RegExpBuilder.notDigit = () => new RegExpBuilder().notDigit()
+RegExpBuilder.letter = () => new RegExpBuilder().letter()
+RegExpBuilder.notLetter = () => new RegExpBuilder().notLetter()
+RegExpBuilder.lowerCaseLetter = () => new RegExpBuilder().lowerCaseLetter()
+RegExpBuilder.upperCaseLetter = () => new RegExpBuilder().upperCaseLetter()
+RegExpBuilder.append = (r) => new RegExpBuilder().append(r)
+RegExpBuilder.optional = (r) => new RegExpBuilder().optional(r)
diff --git a/examples/packages/minis/SwitchChain.js b/examples/packages/minis/SwitchChain.js
new file mode 100644
index 0000000..62bec36
--- /dev/null
+++ b/examples/packages/minis/SwitchChain.js
@@ -0,0 +1,113 @@
+const {Chain, ChainedSet, merge, eq, is} = require('../../../')
+
+const {isFunction, isBoolean, isArray, isString, isNull} = is
+const ignoredTypes = ['null', 'undefined', 'NaN']
+const simpleKindOf = x => (isArray(x) ? 'array' : isNull(x) ? 'null' : typeof x)
+
+// @TODO find the other SwitchChain that also has break?
+// needs more checks
+class Switch extends Chain {
+ constructor(value) {
+ super(value)
+ this.cases = new ChainedSet(this)
+ this.value = this.parent
+ }
+
+ static on(value) {
+ return new Switch(value)
+ }
+
+ // could be decorate
+ case(value, cb) {
+ let check = () => {
+ if (eq(this.value, value)) {
+ return cb()
+ }
+ return false
+ }
+
+ if (isFunction(value)) {
+ check = value
+ }
+
+ if (isBoolean(value)) {
+ check = () => {
+ if (value) {
+ return cb()
+ }
+ return false
+ }
+ }
+
+ this.cases.add(check)
+
+ return this
+ }
+
+ // auto ending
+ default(cb) {
+ return this.set('default', cb).end()
+ }
+
+ end() {
+ for (let [condition] of this.cases) {
+ const result = condition()
+ if (result) return result
+ }
+
+ return this.get('default')()
+ }
+}
+
+// could use say matcher super easily but the point is
+// being able to use the array, since === would not work with an array usually
+function DopeSwitch(one, two) {
+ const types = [one, two].map(simpleKindOf)
+ const [type1, type2] = types
+
+ if (ignoredTypes.includes(type1)) return two
+ if (ignoredTypes.includes(type2)) return one
+
+ /* prettier-ignore */
+ const result = Switch
+ .on(types)
+ // strings[]
+ .case(['string', 'string'], () => one + two)
+ .case(['array', 'string'], () => one.concat([two]))
+ .case(['string', 'array'], () => two.concat([one]))
+ // primitives
+ .case(['string', 'number'], () => [one, two])
+ .case(['number', 'string'], () => [one, two])
+ .case(['number', 'boolean'], () => [one, two])
+ .case(['boolean', 'string'], () => [one, two])
+ .case(['boolean', 'number'], () => [one, two])
+ // boolean[]
+ .case(['boolean', 'boolean'], () => one)
+ .case(['array', 'boolean'], () => one.concat([two]))
+ .case(['boolean', 'array'], () => one.concat([two]))
+ // number[]
+ .case(['number', 'number'], () => one + two)
+ .case(['array', 'number'], () => one.concat([two]))
+ .case(['number', 'array'], () => one.concat([two]))
+ // concat
+ .default(() => merge(one, two))
+
+ return result
+}
+
+function DopeSwitchDebug(one, two) {
+ const key = String([one, two])
+ return {[key]: DopeSwitch(one, two)}
+}
+
+const merges = [
+ DopeSwitchDebug(1, 1),
+ DopeSwitchDebug('1', 1),
+ DopeSwitchDebug([], 100),
+ DopeSwitchDebug({}, {eh: true}),
+ DopeSwitchDebug([], []),
+ DopeSwitchDebug([], {}),
+ DopeSwitchDebug(['duck', 'duck', 'duck'], ['goose']),
+]
+
+console.log(merges)
diff --git a/exports.js b/exports.js
new file mode 100644
index 0000000..21f1660
--- /dev/null
+++ b/exports.js
@@ -0,0 +1,75 @@
+/* eslint import/max-dependencies: "OFF" */
+
+/* @TODO add `exports.[name]` for es6 */
+
+const index = require('./src')
+// inc
+const includes = require('./src/deps/conditional/includes')
+const includesAll = require('./src/deps/conditional/includes/all')
+const includesAny = require('./src/deps/conditional/includes/any')
+// cond
+const all = require('./src/deps/conditional/all')
+const some = require('./src/deps/conditional/some')
+const not = require('./src/deps/conditional/not')
+const or = require('./src/deps/conditional/or')
+const and = require('./src/deps/conditional/and')
+// fp
+const fp = require('./src/deps/fp')
+// const native = require('./src/deps/native')
+// const regexp = require('./src/deps/regexp')
+// is
+const math = require('./src/deps/math')
+const util = require('./src/deps/util')
+const to = require('./src/deps/cast')
+const escapeDot = require('./src/deps/dot/escape')
+const dottable = require('./src/deps/dot/dottable')
+const segments = require('./src/deps/dot/segments')
+const paths = require('./src/deps/dot/paths')
+const array = require('./src/deps/array')
+const construct = require('./src/deps/construct')
+const addPooling = require('./src/deps/cache/pooler')
+const string = require('./src/deps/string')
+const encase = require('./src/deps/encase')
+const cast = require('./src/deps/cast')
+const loop = require('./src/deps/loop')
+const is = require('./src/deps/is/_all')
+const _ = require('./src/deps/_')
+
+const cache = {addPooling}
+const dots = {escapeDot, isDottable: dottable, segments, paths}
+
+const conditionsObj = {all, some, not, or, and}
+
+includes.all = includesAll
+includes.any = includesAny
+const includesObj = {
+ includes,
+ includesAll,
+ includesAny,
+ // all: includesAll,
+ // any: includesAny,
+}
+
+index.toMatcher = index.matcher.make
+
+Object.assign(
+ index,
+ includesObj,
+ conditionsObj,
+ fp,
+ is,
+ math,
+ to,
+ dots,
+ string,
+ array,
+ util,
+ construct,
+ cache,
+ encase,
+ cast,
+ loop,
+ _
+)
+
+module.exports = index
diff --git a/package.json b/package.json
index 5e85509..22f758a 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "chain-able",
- "version": "5.0.0",
+ "version": "5.0.0-beta.6",
"description": "interfaces that describe their intentions.",
"main:es6": "src/index.js",
"main:dev": "dists/dev/index.js",
@@ -54,7 +54,7 @@
"lint": "eslint",
"build": "make build",
"prepublish": "make prepublish",
- "_postpublish": "make clean"
+ "postpublish": "make postpublish"
},
"directories": {
"typings": "typings",
@@ -94,7 +94,9 @@
"sourceMap": true,
"instrument": false,
"cache": false,
- "include": ["./dist/**/*.js"],
+ "include": [
+ "./dist/**/*.js"
+ ],
"exclude": [
"_todos/**",
"_play/**",
@@ -109,19 +111,28 @@
"test-dist/built.js",
"test-dist/chainsaw/*.js"
],
- "_require": ["babel-register", "babel-core/register"],
+ "_require": [
+ "babel-register",
+ "babel-core/register"
+ ],
"lines": 85,
"statements": 85,
"functions": 85,
"branches": 70,
- "extension": [".js"],
- "reporter": ["lcov", "html", "text"]
+ "extension": [
+ ".js"
+ ],
+ "reporter": [
+ "lcov",
+ "html",
+ "text"
+ ]
},
"jest": {
"transformIgnorePatterns": [
"/node_modules/",
- "/_",
- "/examples",
+ "/_/",
+ "/examples/",
"/src/deps/_r|meta|external|env|primitives/",
"/src/deps/external/lodash/",
"/src/deps/external/",
@@ -146,10 +157,23 @@
"watch": false,
"cache": true,
"setupTestFrameworkScriptFile": "./test/__testsetup.js",
- "collectCoverageFrom": ["src/**/*.js", "test/**/*.js"],
+ "collectCoverageFrom": [
+ "src/**/*.js",
+ "test/**/*.js"
+ ],
"coveragePathIgnorePatterns": [
"\\\\node_modules\\\\",
"_modules",
+ "src/deps/regexp|native/*.js",
+ "src/deps/math/index|math.js",
+ "src/deps/loop/index|loop.js",
+ "src/deps/construct/index|construct.js",
+ "src/deps/string/index|string.js",
+ "src/deps/array/index|array.js",
+ "src/deps/array/insertAtIndex.js",
+ "src/deps/conditional/eqeq.js",
+ "src/deps/traversers/stringify.js",
+ "src/plugins/getterOnSet.js",
"src/deps/_r|meta|external|env|primitives",
"src/deps/external/lodash",
"src/deps/external",
@@ -161,6 +185,8 @@
"src/deps/util/flatten|charCodeAtZero.js",
"src/deps/is/class|node|stringOrNumber.js",
"src/deps/reduce/objects.js",
+ "src/deps/fp/fp.js",
+ "src/deps/fp/index.js",
"src/deps/symbols/index|species|spreadable.js",
"src/deps/index|uniq|eqCurry|typeof|insert-at-index|nonEnumerableTypes.js",
"src/compose/decorators.js",
@@ -170,11 +196,16 @@
"src/plugins/index|plugins.js",
"COMMENT/ignore-below-pass-along-indexes.COMMENT",
"src/is|dopemerge|matcher|validators|encase|dot|includes|cache|compose|reduce/index.js",
- "src/deps/is|dopemerge|matcher|validators|encase|dot|includes|cache|compose|reduce/index.js",
+ "src/deps/fp|is|dopemerge|matcher|validators|encase|dot|includes|cache|compose|reduce/index.js",
"src/index.web.js",
"src/index.js"
],
- "coverageReporters": ["json", "text", "lcov", "clover"],
+ "coverageReporters": [
+ "json",
+ "text",
+ "lcov",
+ "clover"
+ ],
"automock": false,
"bail": false,
"browser": false,
@@ -190,18 +221,27 @@
"test/is/index.js",
"test/chainsaw",
"test/traverse/index.js",
- "/examples"
+ "/examples",
+ "/fun"
]
},
"ava": {
- "files": ["!index.*.js", "test-dist/*.js"],
- "source": ["dist/**", "!src/**/*"],
+ "files": [
+ "!index.*.js",
+ "test-dist/*.js"
+ ],
+ "source": [
+ "dist/**",
+ "!src/**/*"
+ ],
"verbose": true,
"concurrency": 3,
"failFast": false,
"failWithoutAssertions": false,
"powerAssert": true,
- "require": ["babel-core/register"],
+ "require": [
+ "babel-core/register"
+ ],
"babel": "inherit"
},
"_optionalDependencies": {
@@ -209,9 +249,6 @@
"memwatch-next": "^0.3.0"
},
"devDependencies": {
- "humanize-url": "^1.0.1",
- "humanize-string": "^1.0.1",
- "string": "^3.3.3",
"@types/node": "^7.0.31",
"acorn": "^5.0.3",
"acorn-dynamic-import": "^2.0.2",
@@ -248,17 +285,24 @@
"funwithflags": "^1.0.2",
"fuse-box": "2.2.0-beta.21",
"gzip-size-cli": "^2.0.0",
+ "humanize-string": "^1.0.1",
+ "humanize-url": "^1.0.1",
"immutable": "^3.8.1",
"inspector-gadget": "^1.0.0",
"jest": "^20.0.4",
"jest-benchmark": "^0.0.0",
+ "js-beautify": "^1.6.14",
+ "jssmartcheck": "^0.2.3",
+ "jsverify": "^0.8.2",
"lodash": "^4.17.4",
"marked": "^0.3.6",
"mobx": "^3.1.14",
"module-alias": "^2.0.0",
"nyc": "^10.3.2",
"optimize-js": "^1.0.3",
+ "preact": "^8.2.1",
"ramda": "^0.24.1",
+ "react": "^15.6.1",
"rimraf": "^2.6.1",
"rollup": "^0.43.0",
"rollup-plugin-babili": "^3.0.0",
@@ -272,6 +316,7 @@
"rollup-plugin-typescript2": "^0.4.4",
"rollup-plugin-uglify": "^2.0.1",
"script-chain": "^0.0.9",
+ "string": "^3.3.3",
"traverse": "^0.6.6",
"treeify": "^1.0.1",
"tslint": "^5.4.3",
diff --git a/src/Chainable.js b/src/Chainable.js
index c9207a2..fc264d9 100644
--- a/src/Chainable.js
+++ b/src/Chainable.js
@@ -1,28 +1,57 @@
-const Iterator = require('./deps/symbols/iterator')
-const Instance = require('./deps/symbols/instance')
-const Primitive = require('./deps/symbols/primitive')
+/* eslint dot-notation: "OFF" */
+
+const ENV_DEVELOPMENT = require('./deps/env/dev')
+const SymbolIterator = require('./deps/symbols/iterator')
+const SymbolInstance = require('./deps/symbols/instance')
+const SymbolPrimitive = require('./deps/symbols/primitive')
const isPrototypeOf = require('./deps/is/prototypeOf')
const isMap = require('./deps/is/map')
const isSet = require('./deps/is/set')
+const isNull = require('./deps/is/null')
const isUndefined = require('./deps/is/undefined')
-const isFunction = require('./deps/is/function')
const isString = require('./deps/is/string')
+const isFunction = require('./deps/is/function')
const isFalse = require('./deps/is/false')
+const ownPropertyIs = require('./deps/is/ownPropertyIs')
+const noop = require('./deps/util/noop')
const ObjectKeys = require('./deps/util/keys')
-const ObjectDefine = require('./deps/define')
-const ignored = require('./deps/ignored')
-const ENV_DEVELOPMENT = require('./deps/env/dev')
+const ObjectDefine = require('./deps/util/define')
+const ignored = require('./deps/meta/ignored')
+const ArrayFrom = require('./deps/util/from')
+const keyValueToIterator = require('./deps/cast/keyValueToIterator')
+const hasOwnPropertyFlipped = require('./deps/flipped/hasOwnPropertyFlipped')
+const when = require('./deps/fp/when')
+const composer = require('./compose/composer')
+const pathSatisfies = require('./deps/fp/propSatisfies')
+
+const hasStore = hasOwnPropertyFlipped('store')
+const hasConstructMethod = pathSatisfies('construct', isFunction)
+const hasDestructorMethod = pathSatisfies('destructor', isFunction)
+// @TODO change from `||` to if else
const shouldClear = (key, property) =>
!ignored(key) &&
- (isMap(property) || isSet(property) || (property && property.store))
+ (isMap(property) || isSet(property) || hasStore(property))
+
-const ComposeChainable = Target => {
+// @TODO would just be `always(prop(name))`
+function valueMethod(name) {
+ return function() {
+ return this[name]
+ }
+}
+
+// const SymbolFor = x => x // Symbol.for
+// const ChainSymbol = SymbolFor('⛓')
+// const ChainExtendedSymbol = SymbolFor('🍬')
+
+// @TODO add back option to send args to parent
+const ComposeChainable = (Target, parentArgs) => {
/* istanbul ignore next: dev */
if (ENV_DEVELOPMENT) {
if (!Target || !Target.prototype) {
console.log({Target})
- throw new TypeError('did not have a super class / target base')
+ // throw new TypeError('did not have a super class / target base')
}
}
@@ -45,363 +74,380 @@ const ComposeChainable = Target => {
*
* @tests Chainable
* @types Chainable
+ *
*/
+
+
+ /**
+ * @since 0.0.1
+ * @memberOf Chainable
+ *
+ * @param {Chainable | any | ParentType} parent ParentType
+ * @constructor
+ *
+ * @example
+ *
+ * class ChainedMap extends Chainable {}
+ * const map = new ChainedMap()
+ * map.className
+ * //=> ChainedMap
+ *
+ */
+
+ // var Chainable = (function(superClass) {
+ // console.log('@TODO!!! ADD POOLED CACHE, ADD DESTRUCTOR, DESTRUCTOR NEEDS TO CALL META')
+ // // Chainable,
+ // // console.log(superClass)
+ // function _Chainable(parent) {
+ // console.log({parent, superClass})
+ // if (isFunction(superClass)) {
+ // console.log('super is fn', {superClass, parent})
+ // if (isUndefined(parentArgs)) {
+ // superClass.call(this, parent)
+ // }
+ // else {
+ // superClass.call(this)
+ // }
+ // }
+
+ // // @TODO remove this if
+ // // if (parent)
+ // if (hasConstructMethod(this)) this.construct(parent)
+ // // .bind(this, true)
+ // if (!hasDestructor(this)) this.destructor = this.clear
+ // this.className = this.constructor.name
+ // this.parent = parent
+ // // @NOTE needed by babel & ts, buble is not-compat
+ // return this
+ // }
+ // Object.defineProperty(_Chainable, ChainSymbol, {value: ChainSymbol})
+ // // _Chainable[ChainSymbol] = ChainSymbol
+ // return _Chainable
+ // // if (isUndefined(superClass)) {
+ // // ChainableObject.create(Parent)
+ // // }
+ // })
+
+ // constructor(parent) {
+ // if (isUndefined(parentArgs)) super()
+ // else super(parent)
+ //
+ // // @TODO remove this
+ // if (parent) this.parent = parent
+ // if (hasConstructMethod(this)) this.construct(parent)
+ //
+ // this.className = this.constructor.name
+ // this.destructor = this.clear // .bind(this, true)
+ //
+ // // @NOTE needed by babel & ts, buble is not-compat
+ // return this
+ // }
+
class Chainable extends Target {
- /**
- * @since 0.0.1
- * @memberOf Chainable
- *
- * @param {Chainable | any | ParentType} parent ParentType
- * @constructor
- *
- * @example
- *
- * class ChainedMap extends Chainable {}
- * const map = new ChainedMap()
- * map.className
- * //=> ChainedMap
- *
- */
constructor(parent) {
super()
- if (parent) this.parent = parent
+
+ // if (hasConstructMethod(this)) this.construct(parent)
this.className = this.constructor.name
+ this.parent = parent
}
+ }
- /**
- * @desc Iterator for looping values in the store
- *
- * @memberOf Chainable
- * @since 0.5.0
- *
- * @type {generator}
- * @return {Object} {value: undefined | any, done: true | false}
- *
- * @NOTE assigned to a variable so buble ignores it
- * @see https://github.com/sindresorhus/quick-lru/blob/master/index.js
- * @see https://stackoverflow.com/questions/36976832/what-is-the-meaning-of-symbol-iterator-in-this-context
- * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/iterator
- * @tests iteration
- * @see this.store
- *
- * @example
- *
- * const chain = new Chain().set('eh', 1)
- * for (var [key, val] of chain) console.log({[key]: val})
- * //=> {eh: 1}
- *
- * @example
- *
- * *[Symbol.iterator](): void { for (const item of this.store) yield item }
- *
- * @example
- *
- * const {ChainedSet} = require('chain-able')
- * const set = new ChainedSet()
- * set.add('eh')
- *
- * for (const arr of set) {
- * const [key, val] = arr
- *
- * key
- * //=> 0
- *
- * val
- * //=> 'eh'
- *
- * arr.length
- * //=> 2
- * }
- *
- */
- [Iterator]() {
- const values = this.values()
- const size = this.store.size
- const entries = this.entries ? this.entries() : 0
- const keys = entries === 0 ? new Array(size) : ObjectKeys(entries)
-
- return {
- i: 0,
- next() {
- let i = this.i
- let key = i
- const val = values[i]
- if (entries) key = keys[i]
-
- // done - no more values, or iteration reached size
- if ((isUndefined(key) && isUndefined(val)) || size <= i) {
- return {value: undefined, done: true}
- }
-
- this.i++
-
- // return
- return {value: [key, val], done: false}
- },
- }
+ Chainable.prototype.destructor = function() {
+ if (hasDestructorMethod(Target.prototype)) {
+ Target.prototype.destructor.call(this)
}
+ this.clear()
+ this.parent = undefined
+ }
- /**
- * @desc for ending nested chains
- * @since 0.4.0
- * @memberOf Chainable
- *
- * @return {Chainable | any}
- *
- * @see Chainable.parent
- * @see FactoryChain
- *
- * @example
- *
- * const parent = 'eh'
- * const child = newChain(parent)
- * child.end()
- * //=> 'eh'
- *
- */
- end() {
- return this.parent
- }
+ // pre-initialize type && allocation?
+ Chainable.prototype.className = Chainable.constructor.name
+ // Chainable.prototype.construct = noop
+ // Chainable.prototype.destructor = noop
- /**
- * @desc when the condition is true,
- * trueBrancher is called,
- * else, falseBrancher is called
- *
- * @memberOf Chainable
- * @since 4.0.0 <- added string-as-has(condition)
- * @since 2.0.0
- *
- * @param {boolean | string} condition when string, checks this.get
- * @param {Function} [trueBrancher=Function] called when true
- * @param {Function} [falseBrancher=Function] called when false
- * @return {Chainable} @chainable
- *
- * @example
- *
- *
- * const prod = process.env.NODE_ENV === 'production'
- * chains.when(prod, c => c.set('prod', true), c => c.set('prod', false))
- *
- *
- */
- when(condition, trueBrancher, falseBrancher) {
- if (condition) {
- if (isFunction(trueBrancher)) {
- if (isString(condition)) {
- if (this.get(condition)) {
- trueBrancher(this)
- }
- }
- else {
- trueBrancher(this)
- }
- }
- }
- else if (isFunction(falseBrancher)) {
- falseBrancher(this)
- }
-
- return this
- }
+ // @TODO
+ // https://github.com/facebook/immutable-js/blob/master/src/Hash.js
+ // http://werxltd.com/wp/2010/05/13/javascript-implementation-of-javas-string-hashcode-method/
+ // observe on every `set` ?
+ Chainable.hashCode = function() {
+ // this.store.size
+ // this.className
+ }
- /**
- * @desc clears the map,
- * goes through this properties,
- * calls .clear if they are instanceof Chainable or Map
- *
- * @memberOf Chainable
- * @since 4.0.0 (moved only to Chainable, added option to clear this keys)
- * @since 0.4.0 (in ChainedMap)
- * @since 0.3.0 (in Chainable)
- *
- * @param {boolean | undefined} [clearPropertiesThatAreChainLike=true] checks properties on the object, if they are `chain-like`, clears them as well
- * @return {Chainable} @chainable
- *
- * @see https://github.com/fliphub/flipchain/issues/2
- * @see ChainedSet
- * @see ChainedMap
- *
- * @example
- *
- * const chain = new Chain()
- * chain.set('eh', 1)
- * chain.entries()
- * //=> {eh: 1}
- * chain.clear()
- * chain.entries()
- * //=> {}
- *
- */
- clear(clearPropertiesThatAreChainLike) {
- this.store.clear()
+ /**
+ * @desc for ending nested chains
+ * @since 0.4.0
+ * @memberOf Chainable
+ *
+ * @return {Chainable | any}
+ *
+ * @see Chainable.parent
+ * @see FactoryChain
+ *
+ * @example
+ *
+ * const parent = 'eh'
+ * const child = newChain(parent)
+ * child.end()
+ * //=> 'eh'
+ *
+ */
+ Chainable.prototype.end = valueMethod('parent')
- if (isFalse(clearPropertiesThatAreChainLike)) return this
+ /**
+ * @see fp/when
+ * @type {Function}
+ */
+ Chainable.prototype.when = when
- const keys = ObjectKeys(this)
- for (let k = 0; k < keys.length; k++) {
- const key = keys[k]
- const property = this[key]
- if (shouldClear(key, property)) this[key].clear()
- }
+ /**
+ * @desc clears the map,
+ * goes through this properties,
+ * calls .clear if they are instanceof Chainable or Map
+ *
+ * @memberOf Chainable
+ * @since 4.0.0 (moved only to Chainable, added option to clear this keys)
+ * @since 0.4.0 (in ChainedMap)
+ * @since 0.3.0 (in Chainable)
+ *
+ * @param {boolean | undefined} [clearPropertiesThatAreChainLike=true] checks properties on the object, if they are `chain-like`, clears them as well
+ * @return {Chainable} @chainable
+ *
+ * @see https://github.com/fliphub/flipchain/issues/2
+ * @see ChainedSet
+ * @see ChainedMap
+ *
+ * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/clear map-clear}
+ * @see {@link map-clear}
+ *
+ * @example
+ *
+ * const chain = new Chain()
+ * chain.set('eh', 1)
+ * chain.entries()
+ * //=> {eh: 1}
+ * chain.clear()
+ * chain.entries()
+ * //=> {}
+ *
+ */
+ Chainable.prototype.clear = function(clearPropertiesThatAreChainLike = true) {
+ this.store.clear()
- return this
- }
+ if (isFalse(clearPropertiesThatAreChainLike)) return this
- /**
- * @desc calls .delete on this.store.map
- * @since 0.3.0
- * @memberOf Chainable
- *
- * @param {Primitive} key on a Map: key referencing the value. on a Set: the index
- * @return {Chainable}
- *
- * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/has
- * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/has
- * @see ChainedSet
- * @see ChainedMap
- *
- * @example
- *
- * const chain = new Chain()
- * chain.set('eh', 1)
- * chain.get('eh')
- * // => 1
- * chain.delete('eh', 1)
- * chain.get('eh')
- * // => undefined
- *
- */
- delete(key) {
- this.store.delete(key)
- return this
- }
+ // @TODO
+ // filterMap(this, (value, key) => {
+ // if (shouldClear(key, value)) value.clear()
+ // })
- /**
- * @since 0.3.0
- * @memberOf Chainable
- *
- * @param {any} keyOrValue key when Map, value when Set
- * @return {boolean}
- *
- * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/has
- *
- * @example
- *
- * const chain = new Chain()
- * chain.set('eh', 1).has('eh')
- * //=> true
- * chain.has('canada')
- * //=> false
- *
- */
- has(keyOrValue) {
- return this.store.has(keyOrValue)
+ const keys = ObjectKeys(this)
+ for (let k = 0; k < keys.length; k++) {
+ const key = keys[k]
+ const property = this[key]
+ if (shouldClear(key, property)) this[key].clear()
}
- /**
- * @desc spreads the entries from ChainedMap.store.values
- * allocates a new array, adds the values from the iterator
- *
- * @memberOf Chainable
- * @since 0.4.0
- *
- * @return {Array} toArr(this.store.values())
- *
- * @NOTE look at Chainable.constructor to ensure not to use `new Array...`
- * @NOTE moved from ChainedMap and ChainedSet to Chainable @2.0.2
- * @NOTE this was [...] & Array.from(this.store.values())
- *
- * {@link https://kangax.github.io/compat-table/es6/#test-Array_static_methods compat-array-static-methods}
- * {@link https://stackoverflow.com/questions/20069828/how-to-convert-set-to-array set-to-array}
- * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/values mozilla-map-values}
- * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/values mozilla-set-values}
- *
- * @see {@link mozilla-map-values}
- * @see {@link mozilla-set-values}
- * @see {@link compat-array-static-methods}
- * @see {@link set-to-array}
- *
- *
- * @example
- *
- * const chain = new Chain()
- * chain.set('eh', 1)
- * chain.values()
- * //=> [1]
- *
- */
- values() {
- const allocated = new Array(this.store.size)
- let i = 0
- this.store.forEach(v => (allocated[i++] = v))
- return allocated
-
- // const size = this.store.size
- // const allocated = new Array(size)
- // // .forEach((value, index) => {
- //
- // const values = this.store.values()
- //
- // for (let index = 0; index < size; index++) {
- // // const value = values[index]
- // const value = values.next().value
- // // console.log({value, index, values})
- // allocated[index] = value
- // }
- //
- // return allocated
- }
+ return this
+ }
+ /**
+ * @desc calls .delete on this.store.map
+ * @since 0.3.0
+ * @memberOf Chainable
+ *
+ * @param {Primitive} key on a Map: key referencing the value. on a Set: the index
+ * @return {Chainable}
+ *
+ * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/delete mozilla-map-delete}
+ * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/delete mozilla-set-delete}
+ * @see {@link mozilla-map-delete}
+ * @see {@link mozilla-set-delete}
+ * @see ChainedSet
+ * @see ChainedMap
+ *
+ * @example
+ *
+ * const chain = new Chain()
+ * chain.set('eh', 1)
+ * chain.get('eh')
+ * //=> 1
+ *
+ * chain.delete('eh', 1)
+ * chain.get('eh')
+ * //=> undefined
+ *
+ */
+ Chainable.prototype['delete'] = function(key) {
+ this.store.delete(key)
+ return this
+ }
+
+ /**
+ * @desc checks whether the store has a value for a given key
+ * @memberOf Chainable
+ * @since 0.3.0
+ *
+ * @param {any} keyOrValue key when Map, value when Set
+ * @return {boolean} `this.store.has(keyOrValue)`
+ *
+ * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/has mozilla-map-has}
+ * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/has mozilla-set-has}
+ * @see {@link mozilla-map-has}
+ * @see {@link mozilla-set-has}
+ *
+ * @example
+ *
+ * const chain = new Chain()
+ * chain.set('eh', 1).has('eh')
+ * //=> true
+ * chain.has('canada')
+ * //=> false
+ *
+ */
+ Chainable.prototype.has = function(keyOrValue) {
+ return this.store.has(keyOrValue)
+ }
+
+ /**
+ * @desc spreads the entries from ChainedMap.store.values
+ * allocates a new array, adds the values from the iterator
+ *
+ * @memberOf Chainable
+ * @since 0.4.0
+ *
+ * @return {Array} toArr(this.store.values())
+ *
+ * @NOTE look at Chainable.constructor to ensure not to use `new Array...`
+ * @NOTE moved from ChainedMap and ChainedSet to Chainable @2.0.2
+ * @NOTE this was [...] & Array.from(this.store.values())
+ *
+ * {@link https://kangax.github.io/compat-table/es6/#test-Array_static_methods compat-array-static-methods}
+ * {@link https://stackoverflow.com/questions/20069828/how-to-convert-set-to-array set-to-array}
+ * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/values mozilla-map-values}
+ * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/values mozilla-set-values}
+ *
+ * @see {@link mozilla-map-values}
+ * @see {@link mozilla-set-values}
+ * @see {@link compat-array-static-methods}
+ * @see {@link set-to-array}
+ *
+ *
+ * @example
+ *
+ * const chain = new Chain()
+ * chain.set('eh', 1)
+ * chain.values()
+ * //=> [1]
+ *
+ */
+ Chainable.prototype.values = function() {
+ return ArrayFrom(this.store.values())
+ }
+
+ // --- symbols ---
+
+ /**
+ * @desc Iterator for looping values in the store
+ *
+ * @memberOf Chainable
+ * @since 0.5.0
+ * @version 5.0.0 <- uses.keys > keys(entries())
+ *
+ * @type {generator}
+ * @return {Object} {value: undefined | any, done: true | false}
+ *
+ * @NOTE assigned to a variable so buble ignores it
+ * @NOTE both Map & Set collections iterate with `[key, val]`
+ *
+ * @see https://www.typescriptlang.org/docs/handbook/iterators-and-generators.html
+ * @see http://exploringjs.com/es6/ch_iteration.html#_maps-1
+ * @see https://github.com/sindresorhus/quick-lru/blob/master/index.js
+ * @see https://stackoverflow.com/questions/36976832/what-is-the-meaning-of-symbol-iterator-in-this-context
+ * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/iterator
+ * @see this.store
+ *
+ * @tests iteration
+ *
+ * @example
+ *
+ * const chain = new Chain().set('eh', 1)
+ * for (var [key, val] of chain) console.log({[key]: val})
+ * //=> {eh: 1}
+ *
+ * @example
+ *
+ * *[Symbol.iterator](): void { for (const item of this.store) yield item }
+ *
+ * @example
+ *
+ * const {ChainedSet} = require('chain-able')
+ * const set = new ChainedSet()
+ * set.add('eh')
+ *
+ * for (const arr of set) {
+ * const [key, val] = arr
+ *
+ * key //=> 0
+ * val //=> 'eh'
+ * arr.length //=> 2
+ * }
+ *
+ */
+ Chainable.prototype[SymbolIterator] = function() {
+ return keyValueToIterator(this.keys(), this.values(), this.store.size)
+ }
+
+ /**
+ * @desc symbol method for toString, toJSON, toNumber
+ * @memberOf Chainable
+ * @since 1.0.2
+ * @version 2
+ *
+ * @param {string} hint enum[default, string, number]
+ * @return {Primitive}
+ *
+ * {@link http://2ality.com/2015/09/well-known-symbols-es6.html#default-tostring-tags well-known-symbols-es6}
+ * @see {@link well-known-symbols-es6}
+ *
+ * @example
+ *
+ * const chain = new Chain()
+ * chain.toNumber = () => 1
+ * +chain;
+ * //=> 1
+ * chain + 1
+ * //=>
+ *
+ * @example
+ *
+ * const chain = new Chain()
+ * chain.toString = () => 'eh'
+ * chain + ''
+ * //=> 'eh'
+ *
+ */
+ Chainable.prototype[SymbolPrimitive] = function(hint) {
+ /* prettier-ignore */
/**
- * @see http://2ality.com/2015/09/well-known-symbols-es6.html#default-tostring-tags
- * @since 1.0.2
- *
- * @memberOf Chainable
- *
- * @param {string} hint enum[default, string, number]
- * @return {Primitive}
- *
- * @example
- *
- * const chain = new Chain()
- * chain.toNumber = () => 1
- * +chain;
- * //=> 1
- * chain + 1
- * //=>
- *
- * @example
- *
- * const chain = new Chain()
- * chain.toString = () => 'eh'
- * chain + ''
- * //=> 'eh'
- *
+ * hint === 'number'
+ * `s`tring is 115
+ * `n`umber is 110
+ * 110 & 4 = 1
+ * 115 & 4 = 0
+ *
+ * if (hint === 'string' && this.toJSON) return this.toJSON()
+ * else if (hint === 'number' && this.toNumber) return this.toNumber()
*/
- [Primitive](hint) {
- /* prettier-ignore */
- /**
- * hint === 'number'
- * `s`tring is 115
- * `n`umber is 110
- * 110 & 4 = 1
- * 115 & 4 = 0
- *
- * if (hint === 'string' && this.toJSON) return this.toJSON()
- * else if (hint === 'number' && this.toNumber) return this.toNumber()
- */
- if (hint === 'number' && this.toNumber) return this.toNumber()
-
- // hint === 'string'
- if (this.toJSON) return this.toJSON()
-
- // hint === 'default'
- return this.toString()
- }
- }
+ if (hint === 'number' && this.toNumber) return this.toNumber()
- const ChainPrototype = Chainable.prototype
+ // hint === 'string'
+ if (this.toJSON) return this.toJSON()
+
+ // hint === 'default'
+ return this.toString()
+ }
/**
* @memberOf Chainable
@@ -409,27 +455,33 @@ const ComposeChainable = Target => {
* @method length
* @readonly
* @since 0.5.0
- * @example for (var i = 0; i < chain.length; i++)
* @see ChainedMap.store
* @return {number}
+ * @example for (var i = 0; i < chain.length; i++)
*/
- ObjectDefine(ChainPrototype, 'length', {
+ ObjectDefine(Chainable.prototype, 'length', {
enumerable: false,
get() {
return this.store.size
},
})
- ObjectDefine(ChainPrototype, Instance, {
+ ObjectDefine(Chainable.prototype, SymbolInstance, {
enumerable: false,
value: instance =>
- instance && (isPrototypeOf(ChainPrototype, instance) || instance.store),
+ instance &&
+ (isPrototypeOf(Chainable.prototype, instance) || hasStore(instance)),
})
+ // @TODO to wrap in toFunction but keep prototype
+ // return function(parent) {
+ // const instance = new Chainable(parent)
+ // // console.log({instance}, instance.end)
+ // return instance
+ // }
+
return Chainable
}
-const c = ComposeChainable(class {})
-
/**
* @since 3.0.0
* @func
@@ -442,6 +494,6 @@ const c = ComposeChainable(class {})
* //=> true
*
*/
-c.compose = ComposeChainable
+const c = composer(ComposeChainable, noop)
module.exports = c
diff --git a/src/ChainedMap.js b/src/ChainedMap.js
index 6fae7ac..76a476d 100644
--- a/src/ChainedMap.js
+++ b/src/ChainedMap.js
@@ -2,17 +2,19 @@ const isUndefined = require('./deps/is/undefined')
const MergeChain = require('./MergeChain')
const MethodChain = require('./MethodChain')
const ChainedMapBase = require('./ChainedMapBase')
+const composer = require('./compose/composer')
/**
* @desc ChainedMap composer
* @category Chainable
* @category Map
+ * @memberOf ChainedMapBase
* @class ChainedMap
* @since 0.0.1
* @alias ComposeMap
* @extends {ChainedMapBase}
*
- * @param {Class | Object | Composable} [SuperClass=ChainedMapBase] class to extend
+ * @param {Class | Object | Composable} [Target=ChainedMapBase] class to extend
* @return {Class} ChainedMap
*
* @see ChainedMapBase
@@ -28,89 +30,96 @@ const ChainedMapBase = require('./ChainedMapBase')
* //=> true
*
*/
-const CM = SuperClass => {
- const Composed =
- SuperClass === ChainedMapBase
- ? SuperClass
- : ChainedMapBase.compose(SuperClass)
- class ChainedMap extends Composed {
- /* prettier-ignore */
- /* @private */
- methods(names) { return this.method(names) }
+const ComposeChainedMap = Target => {
+ let ChainedMap = Target
- /**
- * @desc the way to easily start building methods when using chainable instances
- *
- * @since 4.0.0
- * @category methods
- * @alias methods
- *
- * @param {string | Array | Primitive} names method names to add to the object
- * @return {MethodChain} @chainable
- *
- * @see MethodChain
- *
- * @example
- *
- * const chain = new Chain()
- * chain.method('eh').build()
- * chain.eh(true)
- * chain.get('eh')
- * // => true
- *
- */
- method(names) {
- return new MethodChain(this).name(names)
- }
+ // @NOTE compose now does this
+ // const Composed =
+ // Target === ChainedMapBase || Target.constructor.name === ChainedMapBase.constructor.name
+ // ? Target
+ // : ChainedMapBase.compose(Target)
+
+ // class ChainedMap extends Composed {}
+
+ /* prettier-ignore */
+ /* @private */
+ ChainedMap.prototype.methods = function(names) { return this.method(names) }
+
+ /**
+ * @desc the way to easily start building methods when using chainable instances
+ *
+ * @since 4.0.0
+ * @category methods
+ * @alias methods
+ *
+ * @param {string | Array | Primitive} names method names to add to the object
+ * @return {MethodChain} @chainable
+ *
+ * @see MethodChain
+ *
+ * @example
+ *
+ * const chain = new Chain()
+ * chain.method('eh').build()
+ * chain.eh(true)
+ * chain.get('eh')
+ * //=> true
+ *
+ */
+ ChainedMap.prototype.method = function(names) {
+ return new MethodChain(this).name(names)
+ }
- /**
- * @desc merges an object with the current store
- * @since 0.4.0
- * @category merge
- *
- * @param {Object} obj object to merge
- * @param {Function | null} [handleMergeFn=undefined] return the merger to the callback
- * @return {ChainedMap} @chainable
- *
- * @TODO needs to pass in additional opts somehow...
- * @see deps/dopemerge
- * @see MergeChain
- *
- * @example
- *
- * const chain = new Chain()
- * chain.set('eh', [1])
- * chain.merge({eh: [2]})
- * chain.get('eh')
- * // => [1, 2]
- *
- * @example
- *
- * const chain = new Chain()
- * chain.set('emptyArr', [])
- * chain.merge({emptyArr: []}, mergeChain =>
- * mergeChain.onExisting((a, b) => []).merger((a, b) => []).merge()
- * )
- * chain.get('emptyArr').length)
- * //=> 0
- *
- */
- merge(obj, handleMergeFn) {
- const merger = MergeChain.init(this)
- if (isUndefined(handleMergeFn)) {
- merger.merge(obj)
- }
- else {
- handleMergeFn(merger.obj(obj))
- }
- return this
+ /**
+ * @desc merges an object with the current store
+ * @since 0.4.0
+ * @category merge
+ *
+ * @param {Object} obj object to merge
+ * @param {Function | null} [handleMergeFn=undefined] return the merger to the callback
+ * @return {ChainedMap} @chainable
+ *
+ * @TODO needs to pass in additional opts somehow...
+ * @see deps/dopemerge
+ * @see MergeChain
+ *
+ * @example
+ *
+ * const chain = new Chain()
+ * chain.set('eh', [1])
+ * chain.merge({eh: [2]})
+ * chain.get('eh')
+ * //=> [1, 2]
+ *
+ * @example
+ *
+ * const chain = new Chain()
+ * chain.set('emptyArr', [])
+ * chain.merge({emptyArr: []}, mergeChain =>
+ * mergeChain.onExisting((a, b) => []).merger((a, b) => []).merge()
+ * )
+ * chain.get('emptyArr').length)
+ * //=> 0
+ *
+ */
+ ChainedMap.prototype.merge = function(obj, handleMergeFn) {
+ const merger = MergeChain.init(this)
+
+ if (isUndefined(handleMergeFn)) {
+ merger.merge(obj)
+ }
+ else {
+ handleMergeFn(merger.obj(obj))
}
+
+ return this
}
+
return ChainedMap
}
-const cm = CM(ChainedMapBase)
-cm.compose = CM
-module.exports = cm
+const composed = composer(ComposeChainedMap, ChainedMapBase)
+
+module.exports = composed
diff --git a/src/ChainedMapBase.js b/src/ChainedMapBase.js
index 8b37635..f7cfdb9 100644
--- a/src/ChainedMapBase.js
+++ b/src/ChainedMapBase.js
@@ -1,12 +1,18 @@
+const SHORTHANDS_KEY = require('./deps/meta/SHORTHANDS_KEY')
const Chainable = require('./Chainable')
+const ObjectKeys = require('./deps/util/keys')
+const ArrayFrom = require('./deps/util/from')
const dopemerge = require('./deps/dopemerge')
const reduce = require('./deps/reduce')
const reduceEntries = require('./deps/reduce/entries')
const isFunction = require('./deps/is/function')
const isUndefined = require('./deps/is/undefined')
-const ObjectKeys = require('./deps/util/keys')
const getMeta = require('./deps/meta')
-const SHORTHANDS_KEY = require('./deps/meta/shorthands')
+const hasOwnPropertyFlipped = require('./deps/flipped/hasOwnPropertyFlipped')
+const composer = require('./compose/composer')
+const newMap = require('./deps/construct/map')
+
+const hasMerge = hasOwnPropertyFlipped('merge')
/**
* this is to avoid circular requires
@@ -31,10 +37,12 @@ const SHORTHANDS_KEY = require('./deps/meta/shorthands')
* @prop {Meta} meta meta fn
* @prop {Map} store main store
*
+ * {@link https://tc39.github.io/ecma262/#sec-map-objects emca-map}
* {@link https://ponyfoo.com/articles/es6-maps-in-depth pony-map}
* {@link https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Map mozilla-map}
* @see {@link pony-map}
* @see {@link mozilla-map}
+ * @see {@link emca-map}
*
* @see ChainedMap
* @see Chainable
@@ -43,9 +51,8 @@ const SHORTHANDS_KEY = require('./deps/meta/shorthands')
* @see ChainedMap
*
*/
-
const ComposeChainedMapBase = Target => {
- return class ChainedMapBase extends Target {
+ class ChainedMapBase extends Target {
/**
* @param {ChainedMapBase | Chainable | ParentType | any} parent ParentType
* @constructor
@@ -59,217 +66,254 @@ const ComposeChainedMapBase = Target => {
*/
constructor(parent) {
super(parent)
-
this.store = new Map()
this.meta = getMeta(this)
}
+ }
- /**
- * @desc tap a value with a function
- * @modifies this.store.get(name)
- * @memberOf ChainedMapBase
- * @version 0.7.0
- * @since 4.0.0-alpha.1 <- moved from transform & shorthands
- *
- * @param {string | any} name key to `.get`
- * @param {Function} fn function to tap with
- * @return {Chain} @chainable
- *
- * {@link https://github.com/sindresorhus/awesome-tap awesome-tap}
- * {@link https://github.com/midknight41/map-factory map-factory}
- * {@link https://github.com/webpack/tapable tapable}
- * @see {@link tapable}
- *
- * @see ChainedMapBase.set
- * @see ChainedMapBase.get
- *
- * @example
- *
- * chain
- * .set('moose', {eh: true})
- * .tap('moose', moose => {moose.eh = false; return moose})
- * .get('moose')
- *
- * // => {eh: false}
- *
- * @example
- *
- * const entries = new Chain()
- * .set('str', 'emptyish')
- * .tap('str', str => str + '+')
- * .set('arr', [1])
- * .tap('arr', arr => arr.concat([2]))
- * .entries()
- *
- * //=> {str: 'emptyish+', arr: [1, 2]}
- *
- */
- tap(name, fn) {
- return this.set(name, fn(this.get(name), dopemerge))
- }
+ // const constructRef = Target.prototype.construct
+ // ChainedMapBase.prototype.construct = function() {
+ // this.store = new Map()
+ // this.meta = getMeta(this)
+ // if (constructRef) constructRef.call(this)
+ // }
- /**
- * @desc checks each property of the object
- * calls the chains accordingly
- *
- * @memberOf ChainedMapBase
- * @since 0.5.0
- *
- * @param {Object} obj object with functions to hydrate from
- * @return {Chainable} @chainable
- *
- * @TODO could also add parsing stringified
- *
- * @example
- *
- * const from = new Chain().from({eh: true})
- * const eh = new Chain().set('eh', true)
- * eq(from, eh)
- * // => true
- *
- */
- from(obj) {
- const keys = ObjectKeys(obj)
+ /**
+ * @desc tap a value with a function
+ * @modifies this.store.get(name)
+ * Invokes interceptor with the obj, and then returns obj.
+ * The primary purpose of this method is to "tap into" a method chain, in
+ * order to perform operations on intermediate results within the chain.
+ *
+ * @memberOf ChainedMapBase
+ * @version 0.7.0
+ * @since 4.0.0-alpha.1 <- moved from transform & shorthands
+ *
+ * @param {string | any} name key to `.get`
+ * @param {Function} fn function to tap with
+ * @return {Chain} @chainable
+ *
+ * {@link https://github.com/jashkenas/underscore/blob/master/underscore.js#L1161 underscore-tap}
+ * {@link https://github.com/ramda/ramda/blob/master/src/internal/_xtap.js ramda-xtap}
+ * {@link https://github.com/ramda/ramda/blob/master/src/tap.js ramda-tap}
+ * {@link https://github.com/sindresorhus/awesome-tap awesome-tap}
+ * {@link https://github.com/midknight41/map-factory map-factory}
+ * {@link https://github.com/webpack/tapable tapable}
+ * @see {@link underscore-tap}
+ * @see {@link tapable}
+ * @see {@link ramda-tap}
+ *
+ * @see ChainedMapBase.set
+ * @see ChainedMapBase.get
+ *
+ * @example
+ *
+ * chain
+ * .set('moose', {eh: true})
+ * .tap('moose', moose => {moose.eh = false; return moose})
+ * .get('moose')
+ *
+ * //=> {eh: false}
+ *
+ * @example
+ *
+ * const entries = new Chain()
+ * .set('str', 'emptyish')
+ * .tap('str', str => str + '+')
+ * .set('arr', [1])
+ * .tap('arr', arr => arr.concat([2]))
+ * .entries()
+ *
+ * //=> {str: 'emptyish+', arr: [1, 2]}
+ *
+ */
+ ChainedMapBase.prototype.tap = function(name, fn) {
+ // get value, tap it, set it
+ return this.set(name, fn(this.get(name), dopemerge))
+ }
- for (let k = 0; k < keys.length; k++) {
- const key = keys[k]
- const val = obj[key]
- const fn = this[key]
+ /**
+ * @version 5.0.0 <- moved into ChainedMapBase & ChainedSet for less monomorphic usage
+ * @since 5.0.0-beta.7
+ * @return {Array} keys
+ *
+ * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/keys mozilla-set-keys}
+ * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/keys mozilla-map-keys}
+ * @see {@link mozilla-map-keys}
+ * @see {@link mozilla-set-keys}
+ *
+ * @example
+ *
+ * Chain.set('eh', 1).keys()
+ * //=> ['eh']
+ *
+ */
+ ChainedMapBase.prototype.keys = function() {
+ return ArrayFrom(this.store.keys())
+ }
- if (fn && fn.merge) {
- fn.merge(val)
- }
- else if (isFunction(fn)) {
- fn.call(this, val)
- }
- else {
- this.set(key, val)
- }
- }
+ /**
+ * @desc checks each property of the object
+ * calls the chains accordingly
+ *
+ * @memberOf ChainedMapBase
+ * @since 0.5.0
+ *
+ * @param {Object} obj object with functions to hydrate from
+ * @return {Chainable} @chainable
+ *
+ * @TODO could also add parsing stringified
+ *
+ * @example
+ *
+ * const from = new Chain().from({eh: true})
+ * const eh = new Chain().set('eh', true)
+ * eq(from, eh)
+ * //=> true
+ *
+ */
+ ChainedMapBase.prototype.from = function(obj) {
+ const keys = ObjectKeys(obj)
- return this
- }
+ for (let k = 0; k < keys.length; k++) {
+ const key = keys[k]
+ const value = obj[key]
+ const fn = this[key]
- /**
- * @desc shorthand methods, from strings to functions that call .set
- * @since 0.4.0
- * @memberOf ChainedMapBase
- *
- * @param {Array} methods decorates/extends an object with new shorthand functions to get/set
- * @return {ChainedMapBase} @chainable
- *
- * @example
- *
- * const chain1 = new Chain()
- * chain1.extend(['eh'])
- *
- * const chain2 = new Chain()
- * chain2.eh = val => this.set('eh', val)
- *
- * eq(chain2.eh, chain1.eh)
- * //=> true
- *
- */
- extend(methods) {
- methods.forEach(method => {
- this.meta(SHORTHANDS_KEY, method)
- this[method] = value => this.set(method, value)
- })
- return this
+ if (hasMerge(fn)) {
+ fn.merge(value)
+ }
+ else if (isFunction(fn)) {
+ fn.call(this, value)
+ }
+ else {
+ this.set(key, value)
+ }
}
- /**
- * @desc spreads the entries from ChainedMapBase.store (Map)
- * return store.entries, plus all chain properties if they exist
- *
- * @memberOf ChainedMapBase
- * @version 4.0.0 <- improved reducing
- * @since 0.4.0
- *
- * @param {boolean} [chains=false] if true, returns all properties that are chains
- * @return {Object} reduced object containing all properties from the store, and when `chains` is true, all instance properties, and recursive chains
- *
- * //
- *
- * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/entries mozilla-map-entries}
- * @see {@link mozilla-map-entries}
- *
- * @example
- *
- * map.set('a', 'alpha').set('b', 'beta').entries()
- * //=> {a: 'alpha', b: 'beta'}
- *
- */
- entries(chains) {
- const reduced = reduce(this.store)
- if (isUndefined(chains)) return reduced
+ return this
+ }
- const reducer = reduceEntries(reduced)
- reducer(this)
- reducer(reduced)
- return reduced
- }
+ /**
+ * @desc shorthand methods, from strings to functions that call .set
+ * @since 0.4.0
+ * @memberOf ChainedMapBase
+ *
+ * @param {Array} methods decorates/extends an object with new shorthand functions to get/set
+ * @return {ChainedMapBase} @chainable
+ *
+ * @example
+ *
+ * const chain1 = new Chain()
+ * chain1.extend(['eh'])
+ *
+ * const chain2 = new Chain()
+ * chain2.eh = val => this.set('eh', val)
+ *
+ * eq(chain2.eh, chain1.eh)
+ * //=> true
+ *
+ */
+ ChainedMapBase.prototype.extend = function(methods) {
+ methods.forEach(method => {
+ this.meta(SHORTHANDS_KEY, method)
+ this[method] = value => this.set(method, value)
+ })
+ return this
+ }
- /**
- * @desc get value for key path in the Map store
- * ❗ `debug` is a special key and is *not* included into .store
- * it goes onto .meta
- *
- * @memberOf ChainedMapBase
- * @version 4.0.0 <- moved debug here
- * @since 0.4.0
- *
- * @param {Primitive} key Primitive data key used as map property to reference the value
- * @return {any} value in .store at key
- *
- * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/get mozilla-map-get}
- * @see {@link mozilla-map-get}
- *
- * @example
- *
- * const chain = new Chain()
- * chain.set('eh', true)
- * chain.get('eh')
- * //=> true
- *
- * chain.get('nope')
- * //=> undefined
- *
- */
- get(key) {
- if (key === 'debug') return this.meta.debug
- return this.store.get(key)
- }
+ /**
+ * @desc spreads the entries from ChainedMapBase.store (Map)
+ * return store.entries, plus all chain properties if they exist
+ *
+ * @memberOf ChainedMapBase
+ * @version 4.0.0 <- improved reducing
+ * @since 0.4.0
+ *
+ * @param {boolean} [chains=false] if true, returns all properties that are chains
+ * @return {Object} reduced object containing all properties from the store, and when `chains` is true, all instance properties, and recursive chains
+ *
+ * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/entries mozilla-map-entries}
+ * @see {@link mozilla-map-entries}
+ * @see deps/reduce/entries
+ *
+ * @example
+ *
+ * map.set('a', 'alpha').set('b', 'beta').entries()
+ * //=> {a: 'alpha', b: 'beta'}
+ *
+ */
+ ChainedMapBase.prototype.entries = function(chains) {
+ const reduced = reduce(this.store)
+ if (isUndefined(chains)) return reduced
- /**
- * @desc sets the value using the key on store
- * adds or updates an element with a specified key and value
- *
- * @memberOf ChainedMapBase
- * @since 0.4.0
- *
- * @param {Primitive} key Primitive to reference the value
- * @param {any} value any data to store
- * @return {ChainedMapBase} @chainable
- *
- * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/set mozilla-map-set}
- *
- * @see {@link mozilla-map-set}
- * @see ChainedMapBase.store
- *
- * @example
- *
- * const chain = new Chain()
- * chain.set('eh', true)
- * chain.get('eh')
- * //=> true
- *
- */
- set(key, value) {
- this.store.set(key, value)
- return this
- }
+ const reducer = reduceEntries(reduced)
+ reducer(this)
+ reducer(reduced)
+ return reduced
+ }
+
+ /**
+ * @desc get value for key path in the Map store
+ * ❗ `debug` is a special key and is *not* included into .store
+ * it goes onto .meta
+ *
+ * @memberOf ChainedMapBase
+ * @version 4.0.0 <- moved debug here
+ * @since 0.4.0
+ *
+ * @param {Primitive} key Primitive data key used as map property to reference the value
+ * @return {any} value in .store at key
+ *
+ * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/get mozilla-map-get}
+ * @see {@link mozilla-map-get}
+ *
+ * @example
+ *
+ * const chain = new Chain()
+ * chain.set('eh', true)
+ * chain.get('eh')
+ * //=> true
+ *
+ * chain.get('nope')
+ * //=> undefined
+ *
+ */
+ ChainedMapBase.prototype.get = function(key) {
+ // @TODO move this back out...
+ if (key === 'debug') return this.meta.debug
+ return this.store.get(key)
+ }
+
+ /**
+ * @desc sets the value using the key on store
+ * adds or updates an element with a specified key and value
+ *
+ * @memberOf ChainedMapBase
+ * @since 0.4.0
+ *
+ * @param {Primitive} key Primitive to reference the value
+ * @param {any} value any data to store
+ * @return {ChainedMapBase} @chainable
+ *
+ * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/set mozilla-map-set}
+ * @see {@link mozilla-map-set}
+ * @see ChainedMapBase.store
+ *
+ * @example
+ *
+ * const chain = new Chain()
+ * chain.set('eh', true)
+ * chain.get('eh')
+ * //=> true
+ *
+ */
+ ChainedMapBase.prototype.set = function(key, value) {
+ this.store.set(key, value)
+ return this
}
+
+ return ChainedMapBase
}
/**
@@ -291,7 +335,7 @@ const ComposeChainedMapBase = Target => {
* //=> true
*
*/
-const cmc = ComposeChainedMapBase(Chainable)
-cmc.compose = ComposeChainedMapBase
-module.exports = cmc
+const composed = composer(ComposeChainedMapBase, Chainable)
+
+module.exports = composed
diff --git a/src/ChainedSet.js b/src/ChainedSet.js
index 05a5975..aeb1d8c 100644
--- a/src/ChainedSet.js
+++ b/src/ChainedSet.js
@@ -1,10 +1,13 @@
const Chainable = require('./Chainable')
const toarr = require('./deps/to-arr')
+const arrayOfIndexes = require('./deps/array/arrayOfIndexes')
/**
* @class
* @category Chainable
* @category Set
+ * @memberOf Chainable
+ * @member ChainedSet
*
* @TODO could add .first .last ?
* @NOTE had Symbol.isConcatSpreadable but it was not useful
@@ -34,76 +37,106 @@ class ChainedSet extends Chainable {
super(parent)
this.store = new Set()
}
+}
- /**
- * @desc appends a new element with a specified value to the end of the .store
- * @since 0.4.0
- * @param {any} value any value to add to **end** of the store
- * @return {ChainedSet} @chainable
- * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/add
- *
- * @example
- *
- * const people = new ChainedSet()
- * people
- * .add('sam')
- * .add('sue')
- *
- * for (let name of people) console.log(name)
- * //=> sam, sue
- */
- add(value) {
- this.store.add(value)
- return this
- }
+/**
+ * @version 5.0.0 <- moved into ChainedMapBase & ChainedSet for less monomorphic usage
+ * @since 5.0.0-beta.6
+ * @memberOf ChainedSet
+ *
+ * @return {Array} keys
+ *
+ * @example
+ *
+ * Chain.set('eh', 1).keys()
+ * //=> ['eh']
+ *
+ */
+ChainedSet.prototype.keys = function() {
+ return arrayOfIndexes(this.store.size)
+}
- /**
- * @since 0.4.0
- * @desc inserts the value at the **beginning** of the Set
- * @param {any} value any value to add to **beginning** the store
- * @return {ChainedSet} @chainable
- *
- * @example
- *
- * const people = new ChainedSet()
- * people
- * .add('sue')
- * .prepend('first')
- *
- * for (let name of people) console.log(name)
- * //=> first, sue
- */
- prepend(value) {
- this.store = new Set([value].concat(super.values()))
- return this
- }
- /**
- * @desc merge any Array/Set/Iteratable/Concatables into the array, at the end
- * @since 0.4.0
- *
- * @param {Array | Set | Concatable} arr values to merge in and append
- * @return {ChainedSet} @chainable
- *
- * @example
- *
- * const people = new ChainedSet()
- * people
- * .add('sam')
- * .add('sue')
- * .prepend('first')
- * .merge(['merged'])
- *
- * for (let name of people) console.log(name)
- * //=> first, sam, sue, merged
- */
- merge(arr) {
- const mergeable = toarr(arr)
- for (let i = 0; i < mergeable.length; i++) {
- this.store.add(mergeable[i])
- }
- return this
+/**
+ * @desc appends a new element with a specified value to the end of the .store
+ * @since 0.4.0
+ * @memberOf ChainedSet
+ *
+ * @param {any} value any value to add to **end** of the store
+ * @return {ChainedSet} @chainable
+ *
+ * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/add mozilla-set-add}
+ * {@link https://github.com/lodash/lodash/blob/master/.internal/addSetEntry.js#L9 lodash-add-set-entry}
+ * @see {@link mozilla-set-add}
+ * @see {@link lodash-add-set-entry}
+ *
+ * @example
+ *
+ * const people = new ChainedSet()
+ * people
+ * .add('sam')
+ * .add('sue')
+ *
+ * for (let name of people) console.log(name)
+ * //=> sam, sue
+ *
+ */
+ChainedSet.prototype.add = function(value) {
+ this.store.add(value)
+ return this
+}
+
+/**
+ * @desc inserts the value at the **beginning** of the Set
+ * @since 0.4.0
+ * @memberOf ChainedSet
+ *
+ * @param {any} value any value to add to **beginning** the store
+ * @return {ChainedSet} @chainable
+ *
+ * @example
+ *
+ * const people = new ChainedSet()
+ * people
+ * .add('sue')
+ * .prepend('first')
+ *
+ * for (let name of people) console.log(name)
+ * //=> first, sue
+ *
+ */
+ChainedSet.prototype.prepend = function(value) {
+ this.store = new Set([value].concat(this.values()))
+ return this
+}
+
+/**
+ * @desc merge any Array/Set/Iteratable/Concatables into the array, at the end
+ * @since 0.4.0
+ * @memberOf ChainedSet
+ *
+ * @param {Array | Set | Concatable} arr values to merge in and append
+ * @return {ChainedSet} @chainable
+ *
+ * @example
+ *
+ * const people = new ChainedSet()
+ * people
+ * .add('sam')
+ * .add('sue')
+ * .prepend('first')
+ * .merge(['merged'])
+ *
+ * for (let name of people) console.log(name)
+ * //=> first, sam, sue, merged
+ *
+ */
+ChainedSet.prototype.merge = function(arr) {
+ const mergeable = toarr(arr)
+ for (let i = 0; i < mergeable.length; i++) {
+ this.store.add(mergeable[i])
}
+ return this
}
module.exports = ChainedSet
diff --git a/src/FactoryChain.js b/src/FactoryChain.js
index 58f9adc..d68ce10 100644
--- a/src/FactoryChain.js
+++ b/src/FactoryChain.js
@@ -2,6 +2,7 @@ const ENV_DEBUG = require('./deps/env/debug')
const ChainedMap = require('./ChainedMap')
const isUndefined = require('./deps/is/undefined')
const isTrue = require('./deps/is/true')
+const newSet = require('./deps/construct/set')
const ON_CHAIN_UP_DOWN_KEY = 'onChainUpDown'
const ON_DONE_KEY = 'onDone'
@@ -9,14 +10,19 @@ const ON_DONE_KEY = 'onDone'
/**
* @extends {ChainedMapBase}
* @inheritdoc
+ *
+ * @since 1.0.0
+ *
* @prop {Object} data
* @prop {Set} _calls
* @type {Map}
*
* {@link http://robdodson.me/javascript-design-patterns-factory/ abstract-factory-pattern}
+ * @see {@link abstract-factory-pattern}
*
* @member FactoryChain
* @category Chainable
+ *
* @tests FactoryChain
* @types FactoryChain
*/
diff --git a/src/MergeChain.js b/src/MergeChain.js
index 8ca33d1..038383d 100644
--- a/src/MergeChain.js
+++ b/src/MergeChain.js
@@ -7,7 +7,9 @@ const isUndefined = require('./deps/is/undefined')
const isTrue = require('./deps/is/true')
const isMapish = require('./deps/is/mapish')
const ObjectKeys = require('./deps/util/keys')
-const SHORTHANDS_KEY = require('./deps/meta/shorthands')
+const constructInit = require('./deps/fp/constructInit')
+const EMPTY_OBJ = require('./deps/native/EMPTY_OBJ')
+const SHORTHANDS_KEY = require('./deps/meta/SHORTHANDS_KEY')
const ENV_DEVELOPMENT = require('./deps/env/dev')
const ENV_DEBUG = require('./deps/env/debug')
@@ -51,9 +53,9 @@ class MergeChain extends ChainedMapBase {
* //=> Map { 'eh' => 2, 'coo' => 'oo' }
*
*/
- static init(parent) {
- return new MergeChain(parent)
- }
+ // static init(parent) {
+ // return new MergeChain(parent)
+ // }
/**
* @inheritdoc
@@ -92,7 +94,7 @@ class MergeChain extends ChainedMapBase {
*/
merger(opts) {
if (isFunction(opts)) return this.set(MERGER_KEY, opts)
- return this.set(MERGER_OPTIONS_KEY, opts)
+ else return this.set(MERGER_OPTIONS_KEY, opts)
}
// [v] messes comments on conditional brace style
@@ -129,7 +131,7 @@ class MergeChain extends ChainedMapBase {
const opts = get(MERGER_OPTIONS_KEY)
const obj = obj2 || get(OBJ_KEY)
const merger = get(MERGER_KEY)
- const shorthands = parent.meta ? parent.meta(SHORTHANDS_KEY) : {}
+ const shorthands = parent.meta ? parent.meta(SHORTHANDS_KEY) : EMPTY_OBJ
const keys = ObjectKeys(obj)
// @@debugger
@@ -313,6 +315,8 @@ class MergeChain extends ChainedMapBase {
}
}
+constructInit(MergeChain)
+
/**
* @memberOf MergeChain
* @method onExisting
diff --git a/src/MethodChain.js b/src/MethodChain.js
index d9c7655..a851753 100644
--- a/src/MethodChain.js
+++ b/src/MethodChain.js
@@ -15,10 +15,10 @@
*/
// core
-const ChainedMap = require('./ChainedMapBase')
-const SHORTHANDS_KEY = require('./deps/meta/shorthands')
+const SHORTHANDS_KEY = require('./deps/meta/SHORTHANDS_KEY')
const ENV_DEVELOPMENT = require('./deps/env/dev')
const ENV_DEBUG = require('./deps/env/debug')
+const ChainedMap = require('./ChainedMapBase')
// plugins
const schemaMethod = require('./plugins/schema')
const typesPlugin = require('./plugins/types')
@@ -31,14 +31,14 @@ const autoGetSetPlugin = require('./plugins/autoGetSet')
// obj
const hasOwnProperty = require('./deps/util/hasOwnProperty')
const getDescriptor = require('./deps/util/getDescriptor')
-const ObjectDefine = require('./deps/define')
+const ObjectDefine = require('./deps/util/define')
const ObjectKeys = require('./deps/util/keys')
const ObjectAssign = require('./deps/util/assign')
// utils
const toarr = require('./deps/to-arr')
-const argumentor = require('./deps/argumentor')
-const camelCase = require('./deps/camel-case')
-const markForGarbageCollection = require('./deps/gc')
+const argumentor = require('./deps/cast/argumentor')
+const camelCase = require('./deps/string/camelCase')
+// const markForGarbageCollection = require('./deps/gc')
// is
const isObj = require('./deps/is/obj')
const isArray = require('./deps/is/array')
@@ -46,6 +46,8 @@ const isUndefined = require('./deps/is/undefined')
const isTrue = require('./deps/is/true')
const isFalse = require('./deps/is/false')
const isObjWithKeys = require('./deps/is/objWithKeys')
+const addPoolingTo = require('./deps/cache/pooler')
+const defaultTo = require('./deps/cast/defaultTo')
const DEFAULTED_KEY = 'defaulted'
const METHOD_KEYS = [
@@ -76,6 +78,8 @@ function aliasFactory(name, parent, aliases) {
}
}
+const defaultToTrue = defaultTo(true)
+
// @TODO to use as a function
// function _methods() {}
// _methods.use(obj) {
@@ -88,6 +92,7 @@ function aliasFactory(name, parent, aliases) {
// }
let methodFactories = {}
+const ENV_DEBUGS = true
/**
* ❗ using `+` will call `.build()` in a shorthand fashion
@@ -112,13 +117,47 @@ let methodFactories = {}
class MethodChain extends ChainedMap {
constructor(parent) {
// timer.start('methodchain')
-
super(parent)
+ this.construct(parent)
+ }
+
+ construct(parent) {
+ if (ENV_DEBUGS) {
+ console.log('construct')
+ }
+ // @NOTE super(parent) only in constructor!!!
+ // if (isUndefined(this.parent))
+ this.parent = parent
+
+ // --- these are scoped with parent arg,
+ // --- !!!!!!! they could use `this.parent` though to make them reusable !!!
+ const set = this.set.bind(this)
+ this.newThis = () => MethodChain.getPooled(this.parent)
+ // default argument...
+ this.encase = x => set('encase', this.parent[x] || x || true)
+ this.returns = (x, callReturns) =>
+ set('returns', x || this.parent).callReturns(callReturns)
+
+ // @NOTE shorthands.bindMethods
+ this.bind = target =>
+ set('bind', isUndefined(target) ? this.parent : target)
+
+ // shortest method name, could also check hasOwnProperty
+ // once we add these, we can re-pool unscoped methods easily
+ if (isUndefined(this.alias)) this.setupOnce()
+
+ // need this every time...
+ this.plugin(typesPlugin)
+ }
+
+ setupOnce() {
+ if (ENV_DEBUGS) {
+ console.log('setup once')
+ }
// ----------------
const set = this.set.bind(this)
- this.newThis = () => new MethodChain(parent)
this.toNumber = () => this.build(0)
/**
@@ -141,18 +180,10 @@ class MethodChain extends ChainedMap {
else return this.name(name)
}
- // default argument...
- this.encase = x => {
- return set('encase', parent[x] || x || true)
- }
-
// alias
this.then = this.onValid.bind(this)
this.catch = this.onInvalid.bind(this)
- this.returns = (x, callReturns) =>
- set('returns', x || parent).callReturns(callReturns)
-
// @NOTE replaces shorthands.chainWrap
this.chainable = this.returns
@@ -181,18 +212,12 @@ class MethodChain extends ChainedMap {
this.camelCase = () => set('camel', true)
- // @NOTE: x = true is much prettier, but compiles badly
- const defaultToTrue = x => (isUndefined(x) ? true : x)
this.define = x => set('define', defaultToTrue(x))
this.getSet = x => set('getSet', defaultToTrue(x))
// @TODO unless these use scoped vars, they should be on proto
- // @NOTE shorthands.bindMethods
- this.bind = target => set('bind', isUndefined(target) ? parent : target)
this.autoGetSet = () => this.plugin(autoGetSetPlugin)
- this.plugin(typesPlugin)
-
if (isObjWithKeys(methodFactories)) {
ObjectKeys(methodFactories).forEach(factoryName => {
this[factoryName] = arg => methodFactories[factoryName].call(this, arg)
@@ -203,6 +228,19 @@ class MethodChain extends ChainedMap {
}
}
+ destructor() {
+ if (ENV_DEBUGS) {
+ console.log('destructoor')
+ }
+
+ // remove refs to unused
+ this.clear()
+ this.parent = undefined
+ // require('fliplog').quick(this)
+ // delete this.parent
+ // markForGarbageCollection(this)
+ }
+
/**
* @desc setup methods to build
* @category builder
@@ -342,7 +380,9 @@ class MethodChain extends ChainedMap {
// remove refs to unused
this.clear()
delete this.parent
- markForGarbageCollection(this)
+ MethodChain.release(this)
+
+ // markForGarbageCollection(this)
// very fast - timer & ensuring props are cleaned
// timer.stop('gc').log('gc')
@@ -775,9 +815,23 @@ class MethodChain extends ChainedMap {
* //=> 1 *
*
*/
-MethodChain.add = function addMethodFactories(methodFactory) {
+addPoolingTo(MethodChain)
+
+// const MethodChainFunction = MethodChain.getPooled
+function MethodChainFunction(parent) {
+ // return new MethodChain(parent)
+ // require('fliplog').quick({parent})
+
+ // require('fliplog').data(MethodChain.instancePool).echo()
+ const instance = MethodChain.getPooled(parent)
+ // require('fliplog').data({instance}).echo()
+ // require('fliplog').data(MethodChain.instancePool).echo()
+ return instance
+}
+
+MethodChainFunction.add = function addMethodFactories(methodFactory) {
ObjectAssign(methodFactories, methodFactory)
}
-methodFactories = MethodChain.add
+methodFactories = MethodChainFunction.add
-module.exports = MethodChain
+module.exports = MethodChainFunction
diff --git a/src/TraverseChain.js b/src/TraverseChain.js
index f94a9c7..e5b2190 100644
--- a/src/TraverseChain.js
+++ b/src/TraverseChain.js
@@ -1,7 +1,7 @@
const ChainedMapBase = require('./ChainedMapBase')
const traverse = require('./deps/traverse')
const isTrue = require('./deps/is/true')
-const matchFactory = require('./deps/matcher/any-key-val')
+const matchFactory = require('./deps/matcher/testKeysVals')
const ENV_DEBUG = require('./deps/env/debug')
const TRAVERSED_KEY = 1
@@ -13,7 +13,7 @@ const EXTENSION_KEYS = ['obj', 'keys', 'vals', 'onNonMatch', 'onMatch', 'clone']
* @extends {ChainedMapBase}
*
* @memberOf Chainable
- * @member Traverse
+ * @memberOf Traverse
* @see deps/traverse
* @category traverse
* @types TraverseChain
@@ -46,20 +46,24 @@ module.exports = class Traverser extends ChainedMapBase {
.extend(EXTENSION_KEYS)
.keys([])
.vals([])
- .onMatch((arg, traverser) => traverser.remove())
+ // key,
+ .onMatch((arg, traverser) => {
+ // no return needed
+ traverser.remove()
+ })
}
/**
* @desc runs traverser, checks the tests, calls the onMatch
* @modifies this.cleaned
*
+ * @memberOf TraverseChain
* @alias call
* @since 1.0.0
+ *
* @param {boolean} [shouldReturn=false] returns traversed object
* @return {any} this.obj/data cleaned
*
- * @memberOf TraverseChain
- *
* @example
*
* const traversed = new Chain()
@@ -96,16 +100,18 @@ module.exports = class Traverser extends ChainedMapBase {
// diff between keys and val is order of arg in ^ tester
const matcher = matchFactory(keys, vals)
- /* istanbul-ignore next: debug */
+ /* istanbul ignore next: debug */
if (ENV_DEBUG) {
console.log('matcher for traverse...', keys, vals)
}
// bound to the traverser
traverse(result).forEach(function(key, x, traverser) {
- if (traverser.isRoot) return
- if (matcher(key, x)) {
- /* istanbul-ignore next: debug */
+ if (traverser.isRoot) {
+ // nothing
+ }
+ else if (matcher(key, x)) {
+ /* istanbul ignore next: debug */
if (ENV_DEBUG) {
console.log('------- match ------- ', key, x)
}
@@ -113,7 +119,7 @@ module.exports = class Traverser extends ChainedMapBase {
onMatch(x, traverser)
}
else if (onNonMatch) {
- /* istanbul-ignore next: debug */
+ /* istanbul ignore next: debug */
if (ENV_DEBUG) {
console.log('------- NONmatch ------- ', key, x)
}
@@ -127,6 +133,8 @@ module.exports = class Traverser extends ChainedMapBase {
}
/**
+ * @ignore
+ * @version 5.0.0-beta.5 @depreciated
* value traversed in traverse
* @since 1.0.0
* @see TraverseChain.traverse
@@ -187,7 +195,7 @@ module.exports = class Traverser extends ChainedMapBase {
* }
*
*/
- traversed() {
- return this.get(TRAVERSED_KEY)
- }
+ // traversed() {
+ // return this.get(TRAVERSED_KEY)
+ // }
}
diff --git a/src/chainPlus.js b/src/chainPlus.js
new file mode 100644
index 0000000..650e00e
--- /dev/null
+++ b/src/chainPlus.js
@@ -0,0 +1,178 @@
+/** @ignore 🚧 wip */
+
+const ignored = require('./deps/meta/ignored')
+const getMeta = require('./deps/meta/meta')
+const Chain = require('./compose/compose')
+const throttle = require('./deps/_/throttle')
+const isFunction = require('./deps/is/function')
+const isString = require('./deps/is/string')
+const curry = require('./deps/fp/curry')
+const bind = require('./deps/fp/bind')
+const toArr = require('./deps/to-arr')
+const camelCase = require('./deps/string/camelCase')
+const eq = require('./deps/traversers/eq')
+const isEmpty = require('./deps/is/empty')
+const escapeDot = require('./deps/dot/escape')
+const not = require('./deps/conditional/not')
+const ObjectKeys = require('./deps/util/keys')
+
+// @TODO pass in factories first, like bind, get, set, has, ifElse
+module.exports = (chain) => {
+ // could also do `before` & `after` diffs for keys when instantiating
+ // chain.sponge = () => {
+ // mapKeys(chain, key => {
+ // if (!ignored(key)) return
+ //
+ // // larger... faster... (than inlining 1 if statement...)
+ // const value = chain[key]
+ // if (isFunction(value)) return
+ //
+ // // what if conflict?
+ // chain.set(key, value)
+ // })
+ // }
+ chain.addPooling = () => {
+ // addPoolingTo(Chain)
+ chain.release = () => {
+ // Chain.release(chain)
+ chain.clear(true)
+ chain.meta = undefined
+ chain.meta = getMeta(chain)
+ }
+ chain.init = chain.getPooled = parent => Chain.getPooled(parent)
+ }
+
+ chain._ifElse = (condition, fn = null) => {
+ const ifElse = {}
+ ifElse.then = cb => {
+ ifElse._then = cb
+ return (condition.call(chain) ? cb.call(chain) : ifElse)
+ }
+ ifElse.else = cb => {
+ ifElse._else = cb
+ return (!condition.call(chain) ? cb.call(chain) : ifElse)
+ }
+ ifElse.elseIf = chain.ifElse
+ return ifElse
+ }
+
+ // THIS WAY, THIS IS LIKE .when which is called every change
+ chain.ifElse = (condition, fn = null) => {
+ const ifElse = chain._ifElse(condition)
+ // chain.observe('*', debounce(() => {
+ // if (ifElse._then) ifElse._then.call(chain)
+ // if (ifElse._else) ifElse._else.call(chain)
+ // }), 10)
+ chain.observe('*', throttle(() => {
+ if (ifElse._then) ifElse._then.call(chain)
+ if (ifElse._else) ifElse._else.call(chain)
+ }), 5)
+
+ // chain.observe('*', changed => {
+ // require('fliplog').data({changed}).echo()
+ // if (ifElse._then) ifElse._then.call(chain)
+ // if (ifElse._else) ifElse._else.call(chain)
+ // })
+ return ifElse
+ }
+
+ const _eq = curry(2, eq)
+ // @TODO when passing `propIs` and using a non-function, use `propeq`
+ // chain.prop = curry(2, chain.propEq)
+ chain.propEq = (prop, value) => eq(chain.get(prop), value)
+ chain.propIs = (prop, fn) => {
+ if (isString(fn)) {
+ fn = _eq(fn)
+ }
+ if (!isFunction(fn)) {
+ // require('fliplog').quick({fn})
+ }
+ return fn(chain.get(prop))
+ }
+
+ // chain.propIsNot = not(chain.propIs)
+ chain.freezeProp = prop => {
+ const frozen = chain.get(prop)
+ chain.transform(prop, data => frozen)
+ }
+ chain.propIsNot = (prop, fn) => not(chain.propIs(prop, fn))
+ chain.propEq = curry(2, chain.propEq)
+ chain.propIs = curry(2, chain.propIs)
+ chain.propIsNot = curry(2, chain.propIsNot)
+ chain.transform = curry(2, bind(chain.transform, chain))
+ chain.observe = curry(2, bind(chain.observe, chain))
+ chain.set = bind(chain.set, chain)
+
+ // @NOTE could curry 3, but that forces an else... bah
+ chain.when = curry(2, chain.when)
+
+ const _transforms = (prop, transforms) =>
+ transforms.forEach(transform => chain.transform(prop, transform))
+ chain.transforms = curry(2, _transforms)
+
+ // @TODO when prefix, could do so much like
+ // `{ehView} = chain` for prefix
+ // `{viewEh} = chain` for postfix
+ //
+ // const {get, set} = chain.boundMethods('get,set')
+ // bindMethods, scopedMethods
+ chain.boundMethods = (methods, prefix = '') => {
+ const bound = {}
+ const bounds = toArr(methods).forEach(method =>
+ bound[method] = bind(chain[method], chain)
+ )
+ return bound
+ }
+
+ // ignore transform and observe
+ chain.setSilent = curry(2, (key, prop) => {
+ chain.store.set(key, prop)
+ return chain
+ })
+
+ // partial, `view`
+ chain.view = prop => () => chain.get(prop)
+ chain.lense = prop => {
+ // @TODO allow using every single `is` as property of the `is` returned
+ //
+ // [x] also return a destructurable obj with camel like
+ // [prop] + '-View'
+ const obj = {
+ escapeDot: () => {
+ prop = escapeDot(prop)
+ return chain
+ },
+ has: () => chain.has(prop),
+ get: () => chain.get(prop),
+ view: chain.view(prop),
+ eq: chain.propEq(prop),
+ is: chain.propIs(prop),
+ not: chain.propIsNot(prop),
+ freeze: () => chain.freezeProp(prop),
+ // update, adjust
+ // set: chain.set(prop),
+ set: val => chain.set(prop, val),
+ setSilent: val => chain.setSilent(prop, val),
+ transform: chain.transform(prop),
+ observe: chain.observe(prop),
+ transforms: chain.transforms(prop),
+ }
+
+ // clone: true
+ // obj.mapKeys()
+ ObjectKeys(obj).forEach(key => {
+ const destructurableKey = camelCase(key + '-' + prop)
+ const destructurableReverse = camelCase(prop + '-' + key)
+ obj[destructurableKey] = obj[key]
+ obj[destructurableReverse] = obj[key]
+ })
+
+ return obj
+ }
+
+ chain.unobserve = observer =>
+ chain.meta('observe').delete(observer)
+ chain.untransform = transformer =>
+ chain.meta('transform').delete(transformer)
+ return chain
+}
diff --git a/src/compose/DotProp.js b/src/compose/DotProp.js
index a8c5198..bde1e12 100644
--- a/src/compose/DotProp.js
+++ b/src/compose/DotProp.js
@@ -4,6 +4,8 @@
const dot = require('../deps/dot')
const isDot = require('../deps/is/dot')
+// const accessor = x => x.split('.')[0]
+
/**
* @desc checks if this.meta.dot != false & isDot(key) - scoped
*
@@ -142,7 +144,9 @@ module.exports = Target => {
if (shouldDot(key, this)) {
// first accessor
// @example: `canada` in `canada.eh`
- const prop = key.split('.').shift()
+ // @TODO could use `first`
+ // @NOTE was `.shift` but this is the only `.shift` anywhere
+ const prop = key.split('.')[0]
// we already know it is .dot, call super instead
// if (!super.has(prop)) super.set(prop, {})
@@ -156,6 +160,7 @@ module.exports = Target => {
// is already by ref, but be extra safe, + observables
return set.call(this, prop, data[prop], key)
}
+
return set.call(this, key, val)
}
diff --git a/src/compose/Observe.js b/src/compose/Observe.js
index d5d13fa..42457d6 100644
--- a/src/compose/Observe.js
+++ b/src/compose/Observe.js
@@ -1,15 +1,18 @@
const toarr = require('../deps/to-arr')
const traverse = require('../deps/traverse')
-// const eq = require('../deps/traversers/eq')
const match = require('../deps/matcher')
const getPathSegments = require('../deps/dot/segments')
-const dot = require('../deps/dot')
-const OBSERVERS_KEY = require('../deps/meta/observers')
+const dotSet = require('../deps/dot/set')
+const newMap = require('../deps/construct/map')
+const OBSERVERS_KEY = require('../deps/meta/OBSERVERS_KEY')
+const ENV_DEBUG = require('../deps/env/debug')
-const {eq} = traverse
+// @TODO export better, this adds extra size
+const {eq, clone} = traverse
/**
- * scoped clones
+ * @TODO auto-clear when near full, have cache-class with pooling
+ * @desc scoped clones
* @private
* @type {Map}
*/
@@ -41,6 +44,14 @@ let objs = new Map()
* @see deps/traverse
* @see DotProp
*
+ * {@link https://msdn.microsoft.com/en-us/library/dd456845(v=vs.110).aspx microsoft}
+ * {@link https://github.com/Hypercubed/ hypercubed}
+ * {@link http://eliperelman.com/fn.js/ fn-is}
+ * {@link https://github.com/knockout/knockout/blob/master/src/subscribables/observable.js knockoutjs-observable}
+ * {@link https://www.npmjs.com/package/simple-observable simple-observable}
+ * {@link https://github.com/canjs/can-observation can-js-observation}
+ * [ minimal OR simple OR microjs OR tiny observable ]
+ *
* {@link https://github.com/iluwatar/java-design-patterns/tree/master/observer observer-pattern}
* {@link https://github.com/ReactiveX/rxjs/blob/master/src/Subscriber.ts reactivex}
* {@link https://github.com/sindresorhus/awesome-observables awesome-observables}
@@ -121,8 +132,17 @@ module.exports = Target => {
*
*/
Target.prototype.observe = function chainObserve(properties, fn) {
+ if (ENV_DEBUG) {
+ console.log('observe', {properties, fn})
+ }
+
const props = toarr(properties)
const hashKey = props.join('_')
+
+ if (ENV_DEBUG) {
+ console.log('observe', {[hashKey]: props})
+ }
+
let data = {}
/* prettier-ignore */
@@ -134,9 +154,18 @@ module.exports = Target => {
// @@debugger
+ if (ENV_DEBUG) {
+ console.log({m, key: changed.key, objs, data, hashKey})
+ }
+
+ // @NOTE faster
+ if (m.length === 0) return
+
+ // update data
for (let i = 0; i < m.length; i++) {
const segments = getPathSegments(m[i])
- dot.set(data, segments, this.get(segments))
+ // console.log({segments, m, i, v: m[i]})
+ dotSet(data, segments, this.get(segments))
}
/**
@@ -156,7 +185,7 @@ module.exports = Target => {
/**
* it did change - clone it for next deepEquals check
*/
- objs.set(hashKey, traverse(data).clone())
+ objs.set(hashKey, clone(data))
/**
* call the observer - it matched & data changed
@@ -164,5 +193,6 @@ module.exports = Target => {
fn.call(this, data, this)
})
}
+
return Target
}
diff --git a/src/compose/Shorthands.js b/src/compose/Shorthands.js
index 3ae55bb..e0e1e30 100644
--- a/src/compose/Shorthands.js
+++ b/src/compose/Shorthands.js
@@ -1,9 +1,15 @@
+/* eslint dot-notation: "OFF" */
+
/**
* @since 2.0.0
*/
const isUndefined = require('../deps/is/undefined')
const isFunction = require('../deps/is/function')
-const isFalse = require('../deps/is/false')
+const hasOwnPropertyFlipped = require('../deps/flipped/hasOwnPropertyFlipped')
+const identity = require('../deps/fp/identity')
+const defaultToNoop = require('../deps/flipped/defaultToNoop')
+
+const hasMeta = hasOwnPropertyFlipped('meta')
/**
* @class Shorthands
@@ -42,173 +48,167 @@ const isFalse = require('../deps/is/false')
*
*/
module.exports = Target => {
- return class Shorthands extends Target {
- // --- helpers ---
+ class Shorthands extends Target {
constructor(parent) {
super(parent)
-
- if (parent && parent.meta) {
- this.meta.debug = parent.meta.debug
- }
- else {
- this.debug(false)
- }
+ this.debug(hasMeta(parent) ? parent.meta.debug : false)
}
+ }
+ // const constructs = defaultToNoop(Target.prototype.construct)
- // https://github.com/fluents/chain-able/issues/32
- // find(key, data = this.entries(true)) {
- // let val = null
- // const matcher = new RegExp(key.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&'))
- // // console.debug(`key: ${key} `)
- // const cb = (x, traverser) => {
- // if (matcher.test(traverser.key) || traverser.path.includes(key)) {
- // val = x
- // traverser.stop()
- // // console.error({x})
- // }
- // // console.debug(`path: ${traverser.path.join('.')} prop: ${traverser.key}`)
- // // console.dir({x, path: traverser.path, key: traverser.key})
- // }
- //
- // traverse(data).forEach(function(x) {
- // cb(x, this)
- // })
- // return val
- // }
+ /**
+ * @version 2.0.0 <- was constructor
+ * @version 5.0.0 <- made as construct, meta check as call method > set
+ *
+ * @param {*} parent @see Chainable
+ * @return {void}
+ */
+ // Target.prototype.construct = function(parent) {
+ // constructs.call(this, parent)
+ // // this.debug(hasMeta(parent) ? parent.meta.debug : false)
+ // }
- /**
- * @desc sets on store not this.set for easier extension
- *
- * @since 4.0.0 <- moved from Extend to Shorthands
- * @since 0.2.0
- *
- * @param {boolean} [should=true] shouldDebug
- * @return {Chainable} @chainable
- *
- * @NOTE is inherited by any chain with a parent with .meta.debug
- *
- * @example
- *
- * const Chain = require('chain-able')
- * const chain = new Chain()
- * chain.debug()
- *
- * chain.get('debug')
- * //=> true
- *
- * // not in entries
- * chain.entries()
- * //=> {}
- *
- */
- debug(should) {
- this.meta.debug = isUndefined(should) ? true : should
- return this
- }
+ /**
+ * @desc sets on store not this.set for easier extension
+ *
+ * @since 4.0.0 <- moved from Extend to Shorthands
+ * @since 0.2.0
+ *
+ * @param {boolean} [should=true] shouldDebug
+ * @return {Chainable} @chainable
+ *
+ * @NOTE is inherited by any chain with a parent with .meta.debug
+ *
+ * @example
+ *
+ * const Chain = require('chain-able')
+ * const chain = new Chain()
+ * chain.debug()
+ *
+ * chain.get('debug')
+ * //=> true
+ *
+ * // not in entries
+ * chain.entries()
+ * //=> {}
+ *
+ */
+ Shorthands.prototype.debug = function(should) {
+ // @NOTE if this is trying to inherit,
+ // and we have shorthands above ChainedMap somehow
+ // because of the `construct`, error, lame
+ if (!this.meta) return this
+ this.meta.debug = isUndefined(should) ? true : should
+ return this
+ }
- /**
- * @desc sets a value **only** when .has is false
- * aka set if the value has not been set
- *
- * @memberOf ShorthandChain
- * @since 1.0.2
- *
- * @param {Primitive} name key to set if it has not been done so already
- * @param {any} value value to set when key has not been already set
- * @return {ShorthandChain} @chainable
- *
- * @see ChainedMapBase.set
- *
- * @example
- *
- * const chain = new Chain()
- *
- * chain.set('eh', true)
- *
- * // eh is already set ^, ignored
- * chain.setIfEmpty('eh', false)
- *
- * chain.get('eh')
- * //=> true
- *
- * @example
- *
- * new Chain().setIfEmpty('canada', true).entries()
- * //=> {canada: true}
- *
- * @example
- *
- * // longhand way to do the same thing
- * if (chain.has('eh') === false) {
- * chain.set('eh', false)
- * }
- *
- * // or using .when
- * chain.when(!chain.has('eh'), instance => instance.set('eh', false))
- *
- */
- setIfEmpty(name, value) {
- if (isFalse(this.has(name))) return this.set(name, value)
- else return this
- }
+ /**
+ * @desc sets a value **only** when .has is false
+ * aka set if the value has not been set
+ *
+ * @memberOf ShorthandChain
+ * @since 1.0.2
+ * @version 4.0.0 <- changed to be prototype method (not extension prototype)
+ * @version 3.0.0 <- changed to use `this.has` vs `isFalse(this.has)`
+ * @version 2.0.0 <- fixed but forgot to return conditionally
+ *
+ * @param {Primitive} name key to set if it has not been done so already
+ * @param {any} value value to set when key has not been already set
+ * @return {ShorthandChain} @chainable
+ *
+ * @see ChainedMapBase.set
+ *
+ * @example
+ *
+ * const chain = new Chain()
+ *
+ * chain.set('eh', true)
+ *
+ * // eh is already set ^, ignored
+ * chain.setIfEmpty('eh', false)
+ *
+ * chain.get('eh')
+ * //=> true
+ *
+ * @example
+ *
+ * new Chain().setIfEmpty('canada', true).entries()
+ * //=> {canada: true}
+ *
+ * @example
+ *
+ * // longhand way to do the same thing
+ * if (chain.has('eh') === false) {
+ * chain.set('eh', false)
+ * }
+ *
+ * // or using .when
+ * chain.when(!chain.has('eh'), instance => instance.set('eh', false))
+ *
+ */
+ Shorthands.prototype.setIfEmpty = function(name, value) {
+ if (this.has(name)) return this
+ else return this.set(name, value)
+ }
- /**
- * @desc returns any value passed in
- * return a value at the end of a chain regardless
- *
- * @memberOf ShorthandChain
- * @since 3.0.0
- *
- * @param {any} value value to return at the end of a chain
- * @return {any} value
- *
- * @example
- *
- * const chain = new Chain()
- *
- * const saveAndDebug = env => chain
- * .from({env: env.NODE_ENV})
- * .return(JSON.stringify(env))
- *
- * console.log(saveAndDebug(process.env))
- * //=> value of process.env
- */
- return(value) {
- return value
- }
+ /**
+ * @desc returns any value passed in
+ * return a value at the end of a chain regardless
+ *
+ * @memberOf ShorthandChain
+ * @since 3.0.0
+ *
+ * @see fp/identity
+ * @param {any} value value to return at the end of a chain
+ * @return {any} value
+ *
+ * @example
+ *
+ * const chain = new Chain()
+ *
+ * const saveAndDebug = env => chain
+ * .from({env: env.NODE_ENV})
+ * .return(JSON.stringify(env))
+ *
+ * console.log(saveAndDebug(process.env))
+ * //=> value of process.env
+ *
+ */
+ Shorthands.prototype['return'] = identity
- /**
- * @desc wrap a value, if it's a Function call it, return this
- * aka execute something and return this
- *
- * @memberOf ShorthandChain
- * @since 2.0.0
- * @param {Function | any} fn function to call, or just any value
- * @return {ShorthandChain} @chainable
- *
- * @example
- *
- * const {eh} = chain.wrap(chain => chain.eh = true)
- * //=> true
- *
- * @example
- *
- * new Chain()
- * .wrap(encased => encased.fn = arg => {
- * throw new Error('encased yo')
- * })
- * .method('fn')
- * .encase()
- * .catch(error => {
- * //=> Error('encasedYo')
- * })
- * .build()
- * .fn(true)
- *
- */
- wrap(fn) {
- if (isFunction(fn)) fn.call(this, this)
- return this
- }
+ /**
+ * @desc wrap a value, if it's a Function call it, return this
+ * aka execute something and return this
+ *
+ * @memberOf ShorthandChain
+ * @since 2.0.0
+ * @param {Function | any} fn function to call, or just any value
+ * @return {ShorthandChain} @chainable
+ *
+ * @example
+ *
+ * const {eh} = chain.wrap(chain => chain.eh = true)
+ * //=> true
+ *
+ * @example
+ *
+ * new Chain()
+ * .wrap(encased => encased.fn = arg => {
+ * throw new Error('encased yo')
+ * })
+ * .method('fn')
+ * .encase()
+ * .catch(error => {
+ * //=> Error('encasedYo')
+ * })
+ * .build()
+ * .fn(true)
+ *
+ */
+ Shorthands.prototype.wrap = function(fn) {
+ if (isFunction(fn)) fn.call(this, this)
+ return this
}
+
+ return Shorthands
}
diff --git a/src/compose/Transform.js b/src/compose/Transform.js
index ff0af1d..9bbc127 100644
--- a/src/compose/Transform.js
+++ b/src/compose/Transform.js
@@ -1,15 +1,16 @@
const TraverseChain = require('../TraverseChain')
+const curry = require('../deps/fp/curry')
const isObj = require('../deps/is/obj')
const isTrue = require('../deps/is/true')
-const isFalse = require('../deps/is/false')
+const isFalsy = require('../deps/is/falsy')
const isUndefined = require('../deps/is/undefined')
const ObjectKeys = require('../deps/util/keys')
const dotPropPaths = require('../deps/dot/paths')
-const TRANSFORMERS_KEY = require('../deps/meta/transformers')
-const OBSERVERS_KEY = require('../deps/meta/observers')
+const TRANSFORMERS_KEY = require('../deps/meta/TRANSFORMERS_KEY')
+const OBSERVERS_KEY = require('../deps/meta/OBSERVERS_KEY')
/**
- * @param {Class | Composable} Target composable class
+ * @param {Class | Composable} Target composable class
* @return {TransformChain} class
* @example
* compose(class {})
@@ -37,7 +38,7 @@ module.exports = Target => {
* {@link https://github.com/iluwatar/java-design-patterns/tree/master/state state-pattern}
* {@link https://github.com/iluwatar/java-design-patterns/tree/master/strategy strategy-pattern}
*/
- // return class Transform extends Target {
+ // class Transform extends Target
// -------------------------------------------
/**
@@ -53,14 +54,26 @@ module.exports = Target => {
* @example
* TAKE FROM TRAVERSECHAIN
*/
- Target.prototype.traverse = function traverseChain(useThis = false) {
+ Target.prototype.traverse = function traverseChain(useThis) {
/* prettier-ignore */
return new TraverseChain(this)
- .obj(isFalse(useThis)
- ? this.entries(true)
- : isTrue(useThis)
- ? this
- : useThis
+ .obj(
+ // @NOTE
+ // defaultTo(false, useThis)
+ // defaulting arg to false is shorter
+ // & faster than void 0 inline checks
+ // that mutate arguments (when transpiled)
+ isFalsy(useThis)
+ ? this.entries(true)
+ : isTrue(useThis)
+ ? this
+ : useThis
+
+ // isFalse(useThis)
+ // ? this.entries(true)
+ // : isTrue(useThis)
+ // ? this
+ // : useThis
)
}
@@ -114,6 +127,8 @@ module.exports = Target => {
* @inheritdoc
* @since 1.0.0
*
+ * @TODO curry
+ *
* @param {Primitive} key key to set with
* @param {any} val value to set for key
* @param {undefined | string | Array} dotPropKey special key used for initializing dot prop values in an optimized way to keep reference
@@ -136,6 +151,7 @@ module.exports = Target => {
// get
const observers = this.meta(OBSERVERS_KEY)
+ // @TODO !isEmpty
// skip the below if we have no observers
if (!observers.length) {
return this
@@ -153,6 +169,27 @@ module.exports = Target => {
return this
}
+ // @TODO
+ // // https://stackoverflow.com/questions/31158902/is-it-possible-to-sort-a-es6-map-object
+ // ordered(comperator = null) {
+ // // this.set = this.before(this.set)
+ // this.set = (key, value) => {
+ // // have to iterate over the keys before setting
+ // // and then after merging in values, update
+ // if (this.store.has(key)) {
+ // // first
+ // let keys = this.store.keys()
+ // if (isFunction(comperator)) keys = keys.sort(comperator)
+ //
+ // // after
+ // const store = this.store
+ // this.store = new Map()
+ // keys.forEach(keyInOrder => this.store.set(key, store.get(key)))
+ // store.clear()
+ // }
+ // }
+ // }
+
// --- remap ---
/**
* @desc remap properties from 1 to another, for example, apis with inconsistent naming
@@ -187,8 +224,7 @@ module.exports = Target => {
*
*/
Target.prototype.remap = function chainRemap(from, to) {
- let remap = from
- if (!isObj(from)) remap = {[from]: to}
+ let remap = isObj(from) ? from : {[from]: to}
/* prettier-ignore */
ObjectKeys(remap).forEach(key => this.transform(key, val => {
diff --git a/src/compose/compose.js b/src/compose/compose.js
index b7122fa..4676e09 100644
--- a/src/compose/compose.js
+++ b/src/compose/compose.js
@@ -1,5 +1,10 @@
+const ENV_DEBUG = require('../deps/env/debug')
const isUndefined = require('../deps/is/undefined')
+const isInstanceOf = require('../deps/is/instanceOf')
+const flattenForIn = require('../deps/loop/flattenForIn')
+const defaultTo = require('../deps/cast/defaultTo')
const Chainable = require('../Chainable')
+const ChainedMapBase = require('../ChainedMapBase')
const ChainedMap = require('../ChainedMap')
const Observe = require('./Observe')
const Shorthands = require('./Shorthands')
@@ -7,11 +12,14 @@ const Transform = require('./Transform')
const DotProp = require('./DotProp')
const ComposableExtensions = [Observe, Shorthands, Transform, DotProp]
+const isOfInstanceObj = isInstanceOf(Object)
/**
* @desc compose chains all the way up from Chainable
* @since 3.0.0
*
+ * @NOTE @IMPORTANT ...really strange, when I do `.compose` in a compose class, say ChainedMap, it loops this... but not .composer...
+ *
* @param {Class | Function | undefined} [target=ChainedMap] class or function to extend
* @param {Array | undefined} [extensions=[Observe, Shorthands, Transform, DotProp]] Array of extensions to compose together left to right
* @return {Class | Function} composed
@@ -19,9 +27,15 @@ const ComposableExtensions = [Observe, Shorthands, Transform, DotProp]
* @tutorial examples/playground/compose
* @tutorial examples/babel/decorators
*
+ * {@link http://js-bits.blogspot.ca/2010/08/javascript-inheritance-done-right.html javascript-inheritance-done-right}
+ * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain mozilla_Inheritance_and_the_prototype_chain}
+ * @see {@link mozilla_Inheritance_and_the_prototype_chain}
+ * @see {@link javascript-inheritance-done-right}
+ *
+ * @func
* @name compose
- * @func compose
* @member compose
+ *
* @tests compose
* @types compose
* @symb 🎼
@@ -67,27 +81,40 @@ const ComposableExtensions = [Observe, Shorthands, Transform, DotProp]
* //=> true
*
*/
-function compose(target, extensions) {
+function _compose(target, extensions) {
+ // let extend = defaultTo(ComposableExtensions, extensions)
let extend = isUndefined(extensions) ? ComposableExtensions : extensions
let composed = target
- if (target && target instanceof Object) {
- composed = ChainedMap.compose(Chainable.compose(target))
+ if (isOfInstanceObj(target)) {
+ // @NOTE now that we can add composers,
+ // it SHOULD start at the top :-)
+
+ composed = Chainable.composer(composed)
+ composed = ChainedMapBase.composer(composed)
+ composed = ChainedMap.composer(composed)
+
+ // composed = ChainedMap.composer(composed)
+ // composed = ChainedMap.composer(ChainedMapBase.compose(Chainable.compose(target)))
}
else {
composed = ChainedMap
}
for (let index = 0; index < extend.length; index++) {
- composed = extend[index](composed) || composed || ChainedMap
+ composed = extend[index](composed)
+
+ // @TODO ensure it is safe to ignore these
+ // || composed || ChainedMap
}
+ flattenForIn(composed)
return composed
}
-compose.Observe = Observe
-compose.Shorthands = Shorthands
-compose.Transform = Transform
-compose.DotProp = DotProp
+_compose.Observe = Observe
+_compose.Shorthands = Shorthands
+_compose.Transform = Transform
+_compose.DotProp = DotProp
-module.exports = compose
+module.exports = _compose
diff --git a/src/compose/composer.js b/src/compose/composer.js
new file mode 100644
index 0000000..fe32950
--- /dev/null
+++ b/src/compose/composer.js
@@ -0,0 +1,65 @@
+// eslint-disable-next-line
+'use strict'
+
+// @see compose note on looping, this solves that
+const isUndefined = require('../deps/is/undefined')
+const isFunction = require('../deps/is/function')
+const setToArray = require('../deps/cast/setToArray')
+const reduceArray = require('../deps/loop/reduce/reduceArray')
+
+const ENV_DEBUG = false
+
+// .codePointAt(0).toString()
+
+// '🎼'
+const COMPOSER_KEY = '127932'
+
+// '🎩'
+const TOP_BASE_CLASS_KEY = '127913'
+
+const callCurrent = (accumulated, current) => {
+ return current(accumulated)
+}
+
+// @NOTE 'top' is a global property o.o
+module.exports = function addCompose(fn, defaultTop) {
+ if (ENV_DEBUG) {
+ console.log('composer_args', {fn, defaultTop})
+ }
+
+ let composed = fn(defaultTop)
+
+ if (ENV_DEBUG) {
+ console.log('composer_add_compose_composed', {composed})
+ }
+
+ if (isUndefined(composed.composer)) {
+ // only one compose fn
+ composed.composer = function(SuperClass, options) {
+ if (ENV_DEBUG) {
+ console.log('composer_composer', {composed, SuperClass})
+ }
+
+ // @NOTE scoping issues if this is only set once
+ // if (!composed[TOP_BASE_CLASS_KEY]) {
+ composed[TOP_BASE_CLASS_KEY] = SuperClass
+
+ let arr = setToArray(composed[COMPOSER_KEY])
+ const composition = reduceArray(arr, callCurrent, composed[TOP_BASE_CLASS_KEY])
+
+ if (ENV_DEBUG) {
+ console.log('composer_composed', {arr, composition})
+ }
+
+ return composition
+ }
+
+ composed[COMPOSER_KEY] = new Set()
+ }
+
+ if (isFunction(fn)) {
+ composed[COMPOSER_KEY].add(fn)
+ }
+
+ return composed
+}
diff --git a/src/compose/decorators.js b/src/compose/decorators.js
index afed9d0..950b0a1 100644
--- a/src/compose/decorators.js
+++ b/src/compose/decorators.js
@@ -1,3 +1,4 @@
+// @see https://github.com/mobxjs/mobx/blob/master/src/utils/decorators.ts
const MethodChain = require('../MethodChain')
const compose = require('../compose')
diff --git a/src/deps/_/README.md b/src/deps/_/README.md
new file mode 100644
index 0000000..122c950
--- /dev/null
+++ b/src/deps/_/README.md
@@ -0,0 +1 @@
+https://github.com/dcorb/debounce-throttle
diff --git a/src/deps/_/_.js b/src/deps/_/_.js
new file mode 100644
index 0000000..f7d9a45
--- /dev/null
+++ b/src/deps/_/_.js
@@ -0,0 +1,6 @@
+const debounce = require('./debounce')
+const delay = require('./delay')
+const memoize = require('./memoize')
+const throttle = require('./throttle')
+
+module.exports = {debounce, throttle, delay, memoize}
diff --git a/src/deps/_/debounce.js b/src/deps/_/debounce.js
new file mode 100644
index 0000000..f97f2f0
--- /dev/null
+++ b/src/deps/_/debounce.js
@@ -0,0 +1,241 @@
+const isUndefined = require('../is/undefined')
+const isFunction = require('../is/function')
+const isObj = require('../is/obj')
+const noop = require('../util/noop')
+const toInteger = require('../cast/toInteger')
+
+
+// underscore.js
+// Returns a function, that, as long as it continues to be invoked, will not
+// be triggered. The function will be called after it stops being called for
+// N milliseconds. If `immediate` is passed, trigger the function on the
+// leading edge, instead of the trailing.
+
+/**
+ * Creates a debounced function that delays invoking `func` until after `wait`
+ * milliseconds have elapsed since the last time the debounced function was
+ * invoked. The debounced function comes with a `cancel` method to cancel
+ * delayed `func` invocations and a `flush` method to immediately invoke them.
+ * Provide `options` to indicate whether `func` should be invoked on the
+ * leading and/or trailing edge of the `wait` timeout. The `func` is invoked
+ * with the last arguments provided to the debounced function. Subsequent
+ * calls to the debounced function return the result of the last `func`
+ * invocation.
+ *
+ * **Note:** If `leading` and `trailing` options are `true`, `func` is
+ * invoked on the trailing edge of the timeout only if the debounced function
+ * is invoked more than once during the `wait` timeout.
+ *
+ * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
+ * until the next tick, similar to `setTimeout` with a timeout of `0`.
+ *
+ * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
+ * for details over the differences between `debounce` and `throttle`.
+ *
+ * @since 5.0.0-beta.5
+ *
+ * @param {Function} func The function to debounce.
+ * @param {number} [wait=0] The number of milliseconds to delay.
+ * @param {Object} [options={}] The options object.
+ * @param {boolean} [options.leading=false]
+ * Specify invoking on the leading edge of the timeout.
+ * @param {number} [options.maxWait]
+ * The maximum time `func` is allowed to be delayed before it's invoked.
+ * @param {boolean} [options.trailing=true]
+ * Specify invoking on the trailing edge of the timeout.
+ * @return {Function} Returns the new debounced function.
+ *
+ * @fork 0.1.0
+ * @category Function
+ * @func
+ *
+ * {@link https://github.com/lodash/lodash/blob/master/debounce.js lodash-debounce}
+ * @see {@link lodash-debounce}
+ *
+ * @example
+ *
+ * // Avoid costly calculations while the window size is in flux.
+ * jQuery(window).on('resize', debounce(calculateLayout, 150))
+ *
+ * // Invoke `sendMail` when clicked, debouncing subsequent calls.
+ * jQuery(element).on('click', debounce(sendMail, 300, {
+ * 'leading': true,
+ * 'trailing': false
+ * }))
+ *
+ * // Ensure `batchLog` is invoked once after 1 second of debounced calls.
+ * const debounced = debounce(batchLog, 250, { 'maxWait': 1000 })
+ * const source = new EventSource('/stream')
+ * jQuery(source).on('message', debounced)
+ *
+ * // Cancel the trailing debounced invocation.
+ * jQuery(window).on('popstate', debounced.cancel)
+ *
+ */
+function debounce(func, wait, options) {
+ let lastArgs
+ let lastThis
+ let maxWait
+ let result
+ let timerId
+ let lastCallTime
+
+ let lastInvokeTime = 0
+ let leading = false
+ let maxing = false
+ let trailing = true
+
+ // @TODO this would be coercing
+ if (!isFunction(func)) {
+ func = noop
+ // throw new TypeError('Expected a function')
+ }
+ // defaultTo(0)
+ wait = toInteger(wait)
+ // const optionsHas = hasIn(options)
+
+ if (isObj(options)) {
+ leading = !!options.leading
+ maxing = 'maxWait' in options
+ maxWait = maxing ? Math.max(toInteger(options.maxWait), wait) : maxWait
+ trailing = 'trailing' in options ? !!options.trailing : trailing
+ }
+
+ function invokeFunc(time) {
+ const args = lastArgs
+ const thisArg = lastThis
+
+ lastArgs = lastThis = undefined
+ lastInvokeTime = time
+ result = func.apply(thisArg, args)
+ return result
+ }
+
+ function leadingEdge(time) {
+ // Reset any `maxWait` timer.
+ lastInvokeTime = time
+ // Start the timer for the trailing edge.
+ timerId = setTimeout(timerExpired, wait)
+ // Invoke the leading edge.
+ return leading ? invokeFunc(time) : result
+ }
+
+ function remainingWait(time) {
+ const timeSinceLastCall = time - lastCallTime
+ const timeSinceLastInvoke = time - lastInvokeTime
+ const timeWaiting = wait - timeSinceLastCall
+
+ return maxing
+ ? Math.min(timeWaiting, maxWait - timeSinceLastInvoke)
+ : timeWaiting
+ }
+
+ function shouldInvoke(time) {
+ const timeSinceLastCall = time - lastCallTime
+ const timeSinceLastInvoke = time - lastInvokeTime
+
+ // Either this is the first call, activity has stopped and we're at the
+ // trailing edge, the system time has gone backwards and we're treating
+ // it as the trailing edge, or we've hit the `maxWait` limit.
+ return (isUndefined(lastCallTime) || (timeSinceLastCall >= wait) ||
+ (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait))
+ }
+
+ function timerExpired() {
+ const time = Date.now()
+ if (shouldInvoke(time)) {
+ return trailingEdge(time)
+ }
+
+ // Restart the timer.
+ timerId = setTimeout(timerExpired, remainingWait(time))
+ }
+
+ function trailingEdge(time) {
+ timerId = undefined
+
+ // Only invoke if we have `lastArgs` which means `func` has been
+ // debounced at least once.
+ if (trailing && lastArgs) {
+ return invokeFunc(time)
+ }
+ lastArgs = lastThis = undefined
+ return result
+ }
+
+ function cancel() {
+ if (!isUndefined(timerId)) {
+ clearTimeout(timerId)
+ }
+ lastInvokeTime = 0
+ lastArgs = lastCallTime = lastThis = timerId = undefined
+ }
+
+ function flush() {
+ return isUndefined(timerId) ? result : trailingEdge(Date.now())
+ }
+
+ function debounced(...args) {
+ const time = Date.now()
+ const isInvoking = shouldInvoke(time)
+
+ lastArgs = args
+ lastThis = this
+ lastCallTime = time
+
+ if (isInvoking) {
+ if (isUndefined(timerId)) {
+ return leadingEdge(lastCallTime)
+ }
+ if (maxing) {
+ // Handle invocations in a tight loop.
+ timerId = setTimeout(timerExpired, wait)
+ return invokeFunc(lastCallTime)
+ }
+ }
+ if (isUndefined(timerId)) {
+ timerId = setTimeout(timerExpired, wait)
+ }
+ return result
+ }
+
+ debounced.cancel = cancel
+ debounced.flush = flush
+
+ return debounced
+}
+
+module.exports = debounce
+
+
+// underscore js version
+// module.exports = function(func, wait, immediate) {
+// let timeout
+// let result
+//
+// const later = function(context, args) {
+// timeout = null
+// if (args) result = func.apply(context, args)
+// }
+//
+// const debounced = restArgs(function(args) {
+// if (timeout) clearTimeout(timeout)
+// if (immediate) {
+// const callNow = !timeout
+// timeout = setTimeout(later, wait)
+// if (callNow) result = func.apply(this, args)
+// }
+// else {
+// timeout = delay(later, wait, this, args)
+// }
+//
+// return result
+// })
+//
+// debounced.cancel = function() {
+// clearTimeout(timeout)
+// timeout = null
+// }
+//
+// return debounced
+// }
diff --git a/src/deps/_/delay.js b/src/deps/_/delay.js
new file mode 100644
index 0000000..13df374
--- /dev/null
+++ b/src/deps/_/delay.js
@@ -0,0 +1,37 @@
+const curry = require('../fp/curry')
+
+/**
+ * Delays a function for the given number of milliseconds, and then calls
+ * it with the arguments supplied.
+ *
+ * @since 5.0.0-beta.5
+ *
+ * @param {Function} func The function to delay.
+ * @param {number} wait The number of milliseconds to delay invocation.
+ * @param {...*} [args] The arguments to invoke `func` with.
+ * @return {number} Returns the timer id.
+ *
+ * @curried 2
+ * @func
+ * @fork 0.1.0
+ * @category Function
+ *
+ * {@link https://github.com/jashkenas/underscore/blob/master/underscore.js#L818 underscore-delay}
+ * {@link https://github.com/lodash/lodash/blob/master/delay.js lodash-delay}
+ * @see {@link lodash-delay}
+ * @see {@link underscore-delay}
+ *
+ * @example
+ *
+ * delay(text => console.log(text), 1000, 'later')
+ * //=> Logs 'later' after one second.
+ *
+ */
+function delay(func, wait, ...args) {
+ // return setTimeout(func, +wait || 0, ...args)
+ return setTimeout(function() {
+ return func.apply(this, args)
+ }, wait)
+}
+
+module.exports = curry(2, delay)
diff --git a/src/deps/_/index.js b/src/deps/_/index.js
new file mode 100644
index 0000000..599a0c4
--- /dev/null
+++ b/src/deps/_/index.js
@@ -0,0 +1 @@
+module.exports = require('./_')
diff --git a/src/deps/_/memoize.js b/src/deps/_/memoize.js
new file mode 100644
index 0000000..e68ce92
--- /dev/null
+++ b/src/deps/_/memoize.js
@@ -0,0 +1,3 @@
+/**
+ * {@link https://github.com/jashkenas/underscore/blob/master/underscore.js#L807 underscore-memoize}
+ */
diff --git a/src/deps/_/throttle.js b/src/deps/_/throttle.js
new file mode 100644
index 0000000..43504d6
--- /dev/null
+++ b/src/deps/_/throttle.js
@@ -0,0 +1,135 @@
+const isObj = require('../is/obj')
+const isIn = require('../is/in')
+const noop = require('../util/noop')
+const toBoolean = require('../cast/toBoolean')
+const debounce = require('./debounce')
+
+/**
+ * - Returns a function, that, when invoked, will only be triggered at most once
+ * during a given window of time. Normally, the throttled function will run
+ * as much as it can, without ever going more than once per `wait` duration;
+ * but if you'd like to disable the execution on the leading edge, pass
+ * `{leading: false}`. To disable execution on the trailing edge, ditto.
+ * - Creates a throttled function that only invokes `func` at most once per
+ * every `wait` milliseconds. The throttled function comes with a `cancel`
+ * method to cancel delayed `func` invocations and a `flush` method to
+ * immediately invoke them. Provide `options` to indicate whether `func`
+ * should be invoked on the leading and/or trailing edge of the `wait`
+ * timeout. The `func` is invoked with the last arguments provided to the
+ * throttled function. Subsequent calls to the throttled function return the
+ * result of the last `func` invocation.
+ *
+ * @NOTE If `leading` and `trailing` options are `true`, `func` is
+ * invoked on the trailing edge of the timeout only if the throttled function
+ * is invoked more than once during the `wait` timeout.
+ *
+ * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
+ * until to the next tick, similar to `setTimeout` with a timeout of `0`.
+ *
+ * @since 5.0.0-beta.1
+ *
+ * @param {Function} func The function to throttle.
+ * @param {number} [wait=0] The number of milliseconds to throttle invocations to.
+ * @param {Object} [options={}] The options object.
+ * @param {boolean} [options.leading=true]
+ * Specify invoking on the leading edge of the timeout.
+ * @param {boolean} [options.trailing=true]
+ * Specify invoking on the trailing edge of the timeout.
+ * @return {Function} Returns the new throttled function.
+ *
+ * @fork 0.1.0
+ * @category Function
+ *
+ * {@link https://github.com/andrewplummer/Sugar/blob/master/lib/function.js#L172 sugar-throttle}
+ * {@link https://github.com/lodash/lodash/blob/master/throttle.js lodash-throttle}
+ * {@link https://css-tricks.com/debouncing-throttling-explained-examples/ debounce-vs-throttle-difference-explained}
+ * @see {@link debounce-vs-throttle-difference-explained}
+ * @see {@link lodash-throttle}
+ * @see {@link sugar-throttle}
+ *
+ * @example
+ *
+ * // Avoid excessively updating the position while scrolling.
+ * jQuery(window).on('scroll', throttle(updatePosition, 100))
+ *
+ * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes.
+ * const throttled = throttle(renewToken, 300000, { 'trailing': false })
+ * jQuery(element).on('click', throttled)
+ *
+ * // Cancel the trailing throttled invocation.
+ * jQuery(window).on('popstate', throttled.cancel)
+ *
+ */
+module.exports = function throttle(func, wait, options) {
+ let leading = true
+ let trailing = true
+
+ if (typeof func !== 'function') {
+ func = noop
+ // throw new TypeError('Expected a function')
+ }
+ if (isObj(options)) {
+ leading = isIn(options, 'leading')
+ ? toBoolean(options.leading)
+ : leading
+
+ trailing = isIn(options, 'trailing')
+ ? toBoolean(options.trailing)
+ : trailing
+ }
+
+ return debounce(func, wait, {
+ 'leading': leading,
+ 'maxWait': wait,
+ 'trailing': trailing,
+ })
+}
+
+// is underscore.js version
+// function(func, wait, options = {}) {
+// let timeout
+// let thisArg
+// let args
+// let result
+// let previous = 0
+//
+// const later = function() {
+// previous = options.leading === false ? 0 : Date.now()
+// timeout = null
+// result = func.apply(thisArg, args)
+// if (!timeout) thisArg = args = null
+// }
+//
+// const throttled = function() {
+// const now = Date.now()
+// if (!previous && options.leading === false) previous = now
+//
+// const remaining = wait - (now - previous)
+// thisArg = this
+// args = arguments
+//
+// if (remaining <= 0 || remaining > wait) {
+// if (timeout) {
+// clearTimeout(timeout)
+// timeout = null
+// }
+//
+// previous = now
+// result = func.apply(thisArg, args)
+//
+// if (!timeout) thisArg = args = null
+// }
+// else if (!timeout && options.trailing !== false) {
+// timeout = setTimeout(later, remaining)
+// }
+// return result
+// }
+//
+// throttled.cancel = function() {
+// clearTimeout(timeout)
+// previous = 0
+// timeout = thisArg = args = null
+// }
+//
+// return throttled
+// }
diff --git a/src/deps/argumentor.js b/src/deps/argumentor.js
deleted file mode 100644
index 1c3120b..0000000
--- a/src/deps/argumentor.js
+++ /dev/null
@@ -1,26 +0,0 @@
-/**
- * @desc turns arguments into an array, used as a util, for opt
- *
- * @since 3.0.0
- * @return {Array}
- *
- * @see https://github.com/aretecode/awesome-deopt
- * @see https://github.com/petkaantonov/bluebird/wiki/Optimization-killers
- *
- * @example
- *
- * function eh() {
- * const args = argumentor.apply(null, arguments).slice(1)
- *
- * console.log(args)
- * //=> [1, 10, 100]
- * }
- * eh(0, 1, 10, 100)
- *
- */
-module.exports = function() {
- const len = arguments.length
- const args = new Array(len > 1 ? len - 1 : 0)
- for (let i = 0; i < len; ++i) args[i] = arguments[i]
- return args
-}
diff --git a/src/deps/array/array.js b/src/deps/array/array.js
new file mode 100644
index 0000000..4cceb71
--- /dev/null
+++ b/src/deps/array/array.js
@@ -0,0 +1,22 @@
+/* istanbul ignore: @docblocks @member */
+
+const flatten = require('./flatten')
+const flattenRecursive = require('./flattenRecursive')
+const concat = require('./concat')
+const insertAtIndex = require('./insertAtIndex')
+const uniq = require('./uniq')
+const preAllocate = require('./preAllocate')
+
+/**
+ * @symb []
+ * @member array
+ * @type {Object}
+ */
+module.exports = {
+ flatten,
+ concat,
+ insertAtIndex,
+ flattenRecursive,
+ uniq,
+ preAllocate,
+}
diff --git a/src/deps/array/arrayOfIndexes.js b/src/deps/array/arrayOfIndexes.js
new file mode 100644
index 0000000..b266013
--- /dev/null
+++ b/src/deps/array/arrayOfIndexes.js
@@ -0,0 +1,27 @@
+const preAllocate = require('../array/preAllocate')
+
+/**
+ * @desc start from 0, fill with numbers until index
+ * @name arrayOfIndexes
+ * @since 5.0.0-beta.6
+ * @memberOf array
+ *
+ * @param {number} x number to fill an array of
+ * @return {Array}
+ *
+ * @example
+ *
+ * arrayOfIndexes(3)
+ * //=> [0, 1, 2]
+ *
+ */
+module.exports = x => {
+ const array = preAllocate(x)
+ let index = 0
+
+ while (index <= x) {
+ array[index] = index++
+ }
+
+ return array
+}
diff --git a/src/deps/array/concat.js b/src/deps/array/concat.js
new file mode 100644
index 0000000..96a9693
--- /dev/null
+++ b/src/deps/array/concat.js
@@ -0,0 +1,53 @@
+const toarr = require('../to-arr')
+
+/**
+ * @desc concat two values, coerce to arrays
+ * @since 4.0.0
+ * @memberOf array
+ *
+ * @param {Array | *} one toArr1
+ * @param {Array | *} two toArr2
+ * @return {Array} [one, two]
+ *
+ * @name concatArray
+ * @alias concatArray
+ *
+ * @func
+ * @see deps/to-arr
+ *
+ * @example
+ *
+ * concat([1], [2]) //=> [1, 2]
+ * concat([1], 2) //=> [1, 2]
+ * concat(1, 2) //=> [1, 2]
+ * concat(new Set([1]), 2) //=> [1, 2]
+ *
+ * // kind of weird...
+ * concat(null, 2) //=> [2]
+ * concat(undefined, 2) //=> [2]
+ * concat(1, null) //=> [1, null]
+ *
+ */
+module.exports = (one, two) => toarr(one || []).concat(toarr(two))
+
+// merge 1-2 arrays
+// function concat(set1, set2) {
+// set1 = set1 || []
+// set2 = set2 || []
+// var idx
+// var len1 = set1.length
+// var len2 = set2.length
+// var result = []
+//
+// idx = 0
+// while (idx < len1) {
+// result[result.length] = set1[idx]
+// idx += 1
+// }
+// idx = 0
+// while (idx < len2) {
+// result[result.length] = set2[idx]
+// idx += 1
+// }
+// return result
+// }
diff --git a/src/deps/array/flatten.js b/src/deps/array/flatten.js
new file mode 100644
index 0000000..2c636e9
--- /dev/null
+++ b/src/deps/array/flatten.js
@@ -0,0 +1,31 @@
+/**
+ * @desc flatten multi-dimensional arrays in 1 line
+ * @since 4.0.0
+ * @memberOf array
+ *
+ * @param {Array} x array(s) to flatten
+ * @return {Array} flattened arrays
+ *
+ * {@link https://stackoverflow.com/questions/10865025/merge-flatten-an-array-of-arrays-in-javascript stack-overflow-flatten}
+ * {@link https://github.com/andrewplummer/Sugar/blob/master/lib/array.js#L202 sugar-flatten}
+ * {@link https://github.com/jashkenas/underscore/blob/master/underscore.js#L527 underscore-flatten}
+ * @see {@link underscore-flatten}
+ * @see {@link sugar-flatten}
+ * @see {@link stack-overflow-flatten}
+ *
+ * @example
+ *
+ * flatten([[1], [2]])
+ * //=> [1, 2]
+ * flatten([[1], 2])
+ * //=> [1, 2]
+ * flatten(1)
+ * //=> [1]
+ *
+ */
+module.exports = x => [].concat.apply([], x)
+
+// function flatten(arr) {
+// const flat = [].concat(...arr)
+// return flat.some(Array.isArray) ? flatten(flat) : flat
+// }
diff --git a/src/deps/array/flattenRecursive.js b/src/deps/array/flattenRecursive.js
new file mode 100644
index 0000000..e2a27ab
--- /dev/null
+++ b/src/deps/array/flattenRecursive.js
@@ -0,0 +1,52 @@
+const isArrayLike = require('../is/arrayLike')
+// const toarr = require('../to-arr')
+
+/**
+ * `flatten` is a helper function that returns a fully recursive
+ *
+ * @memberOf array
+ * @since 5.0.0-beta.6
+ *
+ * @param {Array} list multi-dimensional array-like list
+ * @return {Array<*>} flattened list
+ *
+ * @see array/flatten
+ *
+ * @example
+ *
+ * flattenRecursive([[0, [1]]])
+ * //=> [0, 1]
+ *
+ */
+module.exports = function flattenRecursive(list) {
+ // if (!isArrayLike(list)) return toarr(list)
+ if (!isArrayLike(list)) return []
+
+ // starting values
+ let result = []
+ let idx = 0
+ let listLen = list.length
+ // nested
+ let value
+ let nestedIdx
+
+ while (idx < listLen) {
+ // go deeper if needed
+ if (isArrayLike(list[idx])) {
+ value = flattenRecursive(list[idx])
+ nestedIdx = 0
+
+ while (nestedIdx < value.length) {
+ result[result.length] = value[nestedIdx++]
+ }
+ }
+ // just `push`, non-array value
+ else {
+ result[result.length] = list[idx]
+ }
+
+ idx += 1
+ }
+
+ return result
+}
diff --git a/src/deps/array/index.js b/src/deps/array/index.js
new file mode 100644
index 0000000..beed40a
--- /dev/null
+++ b/src/deps/array/index.js
@@ -0,0 +1 @@
+module.exports = require('./array.js')
diff --git a/src/deps/array/indexOf.js b/src/deps/array/indexOf.js
new file mode 100644
index 0000000..37670e6
--- /dev/null
+++ b/src/deps/array/indexOf.js
@@ -0,0 +1,31 @@
+/**
+ * A specialized version of `indexOf` which performs strict equality
+ * comparisons of values, i.e. `===`.
+ *
+ * @memberOf array
+ * @since 5.0.0-beta.1
+ *
+ * @param {Array} array The array to inspect.
+ * @param {*} value The value to search for.
+ * @param {number} fromIndex The index to search from.
+ * @return {number} Returns the index of the matched value, else `-1`.
+ *
+ * @example
+ *
+ * indexOf([10], 10) //=> 0
+ * indexOf([], 10) //=> -1
+ *
+ */
+function strictIndexOf(array, value, fromIndex) {
+ let index = fromIndex - 1
+ const {length} = array
+
+ while (++index < length) {
+ if (array[index] === value) {
+ return index
+ }
+ }
+ return -1
+}
+
+module.exports = strictIndexOf
diff --git a/src/deps/array/insert-at-index.js b/src/deps/array/insert-at-index.js
deleted file mode 100644
index 57169c2..0000000
--- a/src/deps/array/insert-at-index.js
+++ /dev/null
@@ -1,18 +0,0 @@
-// http://stackoverflow.com/questions/7032550/javascript-insert-an-array-inside-another-array
-// http://stackoverflow.com/questions/1348178/a-better-way-to-splice-an-array-into-an-array-in-javascript/41465578#41465578
-// http://stackoverflow.com/questions/38060705/replace-element-at-specific-position-in-an-array-without-mutating-it
-// function insertArrAt(array, index, arrayToInsert) {
-// // Array.prototype.splice.apply(array, [index, 0].concat(arrayToInsert))
-// // return array.slice.apply([index, 0].concat(arrayToInsert))
-// return array.slice(index, 0).apply([index, 0].concat(arrayToInsert))
-// return array
-// }
-
-module.exports = function insertAtIndex(arr, index, val) {
- if (index < arr.length) {
- return [...arr.slice(0, index), ...val, ...arr.slice(index + 1)]
- }
- else {
- return [...arr, ...Array(index - arr.length), ...val]
- }
-}
diff --git a/src/deps/array/insertAtIndex.js b/src/deps/array/insertAtIndex.js
new file mode 100644
index 0000000..6df7653
--- /dev/null
+++ b/src/deps/array/insertAtIndex.js
@@ -0,0 +1,51 @@
+/**
+ * @desc put a value at any index in an array
+ * @since ? was in insert-at-index dep...
+ * @memberOf array
+ *
+ * @see http://stackoverflow.com/questions/7032550/javascript-insert-an-array-inside-another-array
+ * @see http://stackoverflow.com/questions/1348178/a-better-way-to-splice-an-array-into-an-array-in-javascript/41465578#41465578
+ * @see http://stackoverflow.com/questions/38060705/replace-element-at-specific-position-in-an-array-without-mutating-it
+ *
+ * @param {Array} arr array to put value in at index
+ * @param {number} index index to put valu eat
+ * @param {*} val value to put at index
+ * @return {Array} array with new value at index
+ *
+ * @example
+ *
+ * insertAtIndex(['zero-1', 'one-2'], 1, 1) //=> ['zero-1', 1, 'one-two']
+ *
+ */
+module.exports = function insertAtIndex(arr, index, val) {
+ if (index < arr.length) {
+ return [...arr.slice(0, index), ...val, ...arr.slice(index + 1)]
+ }
+ else {
+ return [...arr, ...Array(index - arr.length), ...val]
+ }
+}
+
+// @TODO test
+// const insertAt = require('../')
+//
+// const list = [0, 1, 2, 3, 4]
+// const eh = ['canada', 'moose']
+//
+// const inserted = insertAt(list, 2, eh)
+// const expected = [0, 1, 'canada', 'moose', 3, 4]
+//
+// expected.forEach((expect, i) => {
+// console.assert(expect === inserted[i], 'same at the same index')
+// })
+// console.log('all assertions passed :-)')
+
+
+/// another way of writing it, this one does not use spread
+//
+// function insertArrAt(array, index, arrayToInsert) {
+// // Array.prototype.splice.apply(array, [index, 0].concat(arrayToInsert))
+// // return array.slice.apply([index, 0].concat(arrayToInsert))
+// return array.slice(index, 0).apply([index, 0].concat(arrayToInsert))
+// return array
+// }
diff --git a/src/deps/array/preAllocate.js b/src/deps/array/preAllocate.js
new file mode 100644
index 0000000..43e1df4
--- /dev/null
+++ b/src/deps/array/preAllocate.js
@@ -0,0 +1,57 @@
+const LARGE_ARRAY_SIZE = require('../native/LARGE_ARRAY_SIZE')
+const isNumberPrimitive = require('../is/numberPrimitive')
+const isArray = require('../is/array')
+const size = require('../util/size')
+const from0 = require('../util/numberFromZero')
+// const lengthMinusOne = require('../util/lengthMinusOne')
+// const lengthFrom0 = require('../util/lengthFromZero')
+
+// @TODO also ensure we coerce this number...?
+// @NOTE calls from0 twice but inlined makes less diff than adding pointer
+const arrFrom0 = x => new Array(from0(x) > LARGE_ARRAY_SIZE ? 0 : from0(x))
+
+/**
+ * @desc make a new empty Array filled with a pre-allocated-length-from-zero
+ * @memberOf array
+ * @name preAllocate
+ * @since 5.0.0
+ * @func
+ *
+ * @param {Object|Array|number} x array or object to return an empty array.of.fill (pre-allocated)
+ * @return {Array} preallocated array full of undefined
+ *
+ * @TODO not sure about pre-allocating objects?
+ *
+ * {@link https://github.com/facebook/react/blob/8f4d30737def9fa3456149826414643b5cbbe4bf/docs/docs/optimizing-performance.md react-opt}
+ * {@link https://thewayofcode.wordpress.com/tag/array-pre-allocation/ the-way-of-code-array}
+ * {@link https://www.html5rocks.com/en/tutorials/speed/v8/#toc-topic-numbers html-5-rocks-v8}
+ * @see {@link html5-rocks-v8}
+ * @see {@link the-way-of-code-array}
+ * @see {@link react-opt}
+ * @see is/numberPrimitive
+ * @see is/array
+ * @see util/size
+ *
+ * @NOTE could be an `||` but it's annoying how it deopts sometimes (arr checks)
+ *
+ * @example
+ *
+ * preAllocate({eh: true})
+ * //=> {}
+ *
+ * preAllocate([1, 2, 10])
+ * //=> [undefined, undefined, undefined]
+ *
+ * preAllocate(2)
+ * //=> [undefined, undefined]
+ *
+ */
+module.exports = function preAllocate(x) {
+ // @TODO now that size is better, this can just be...
+ // return arrFrom0(size(x))
+ return isNumberPrimitive(x)
+ ? arrFrom0(x)
+ : isArray(x)
+ ? arrFrom0(x.length)
+ : arrFrom0(size(x))
+}
diff --git a/src/deps/array/shuffle.js b/src/deps/array/shuffle.js
new file mode 100644
index 0000000..dd4fedb
--- /dev/null
+++ b/src/deps/array/shuffle.js
@@ -0,0 +1,40 @@
+const isNill = require('../is/nullOrUndefined')
+
+// @TODO need to finish `copy/`
+
+/**
+ * Creates an array of shuffled values, using a version of the
+ * [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle).
+ *
+ * @since 0.1.0
+ * @category Array
+ *
+ * @param {Array} array The array to shuffle.
+ * @return {Array} Returns the new shuffled array.
+ *
+ * {@link https://github.com/lodash/lodash/blob/master/shuffle.js lodash-shuffle}
+ * @see {@link lodash-shuffle}
+ *
+ * @example
+ *
+ * shuffle([1, 2, 3, 4])
+ * //=> [4, 1, 3, 2]
+ *
+ */
+// module.exports = function shuffle(array) {
+// const length = isNill(array) ? 0 : array.length
+// if (!length) return []
+//
+// let index = -1
+// const lastIndex = length - 1
+// const result = copyArray(array)
+//
+// while (++index < length) {
+// const rand = index + Math.floor(Math.random() * (lastIndex - index + 1))
+// const value = result[rand]
+// result[rand] = result[index]
+// result[index] = value
+// }
+//
+// return result
+// }
diff --git a/src/deps/array/spliceIn.js b/src/deps/array/spliceIn.js
new file mode 100644
index 0000000..9ff46db
--- /dev/null
+++ b/src/deps/array/spliceIn.js
@@ -0,0 +1,52 @@
+const preAllocate = require('./preAllocate')
+
+/**
+ * @name spliceIn
+ * @since 5.0.0 beta.6
+ * @memberOf array
+ *
+ * @param {Array} array array to splice
+ * @param {number} idx index to splice at
+ * @param {*} val value to replace at index
+ * @param {boolean} [canEdit=false] should mutate
+ * @return {Array}
+ *
+ * {@link https://github.com/facebook/immutable-js/blob/master/src/Map.js#L930 immutable-js-splice-in}
+ * @see {@link immutable-js-splice-in}
+ * @see array/insertAtIndex
+ *
+ * @example
+ *
+ * spliceIn(['zero', 'one'], 1, 'wan')
+ * //=> ['zero', 'wan']
+ *
+ * spliceIn(['zero', 'one'], 0, 'wan')
+ * //=> ['wan', 'one']
+ *
+ * spliceIn(['zero', 'one'], 0, 'wan', true)
+ * //=> ['wan', 'one']
+ *
+ */
+module.exports = function spliceIn(array, idx, val, canEdit) {
+ const newLen = array.length + 1
+
+ if (canEdit && idx + 1 === newLen) {
+ array[idx] = val
+ return array
+ }
+
+ const newArray = preAllocate(newLen)
+ let after = 0
+
+ for (let ii = 0; ii < newLen; ii++) {
+ if (ii === idx) {
+ newArray[ii] = val
+ after = -1
+ }
+ else {
+ newArray[ii] = array[ii + after]
+ }
+ }
+
+ return newArray
+}
diff --git a/src/deps/array/spliceOut.js b/src/deps/array/spliceOut.js
new file mode 100644
index 0000000..1866c86
--- /dev/null
+++ b/src/deps/array/spliceOut.js
@@ -0,0 +1,48 @@
+const preAllocate = require('./preAllocate')
+
+/**
+ * @name spliceIn
+ * @since 5.0.0 beta.6
+ * @memberOf array
+ *
+ * @param {Array} array array to splice
+ * @param {number} idx index to splice at
+ * @param {boolean} [canEdit=false] should mutate
+ * @return {Array}
+ *
+ * {@link https://github.com/facebook/immutable-js/blob/master/src/Map.js#L930 immutable-js-splice-in}
+ * @see {@link immutable-js-splice-in}
+ *
+ * @example
+ *
+ * spliceIn(['zero', 'one'], 1)
+ * //=> ['zero']
+ *
+ * spliceIn(['zero', 'one'], 0)
+ * //=> ['one']
+ *
+ * spliceIn(['zero', 'one'], 0, true)
+ * //=> ['one']
+ *
+ */
+module.exports = function spliceOut(array, idx, canEdit) {
+ const newLen = array.length - 1
+
+ // @TODO why no `shift` ?
+ if (canEdit && idx === newLen) {
+ array.pop()
+ return array
+ }
+
+ const newArray = preAllocate(newLen)
+
+ let after = 0
+ for (let ii = 0; ii < newLen; ii++) {
+ if (ii === idx) {
+ after = 1
+ }
+ newArray[ii] = array[ii + after]
+ }
+
+ return newArray
+}
diff --git a/src/deps/array/uniq.js b/src/deps/array/uniq.js
index 6c851c7..0fec748 100644
--- a/src/deps/array/uniq.js
+++ b/src/deps/array/uniq.js
@@ -1,2 +1,38 @@
-// eslint-disable-next-line prefer-includes/prefer-includes
+/* eslint prefer-includes/prefer-includes: "OFF" */
+
+/**
+ * @desc use in array.filter(uniq) to de-dupe values using indexOf
+ * @since 0.1.0
+ * @memberOf array
+ *
+ * @param {*} value value in array iteration
+ * @param {number} index current index
+ * @param {Array} arr array being iterated, `thisArg` when using .filter
+ * @return {Array} de-duped/uniqued array
+ *
+ * @func
+ * @name uniq
+ * @alias unique
+ *
+ * {@link https://github.com/lodash/lodash/blob/master/uniq.js lodash-uniq}
+ * {@link https://github.com/mobxjs/mobx/blob/master/src/utils/utils.ts#L58 mobx-uniq}
+ * {@link https://github.com/jashkenas/underscore/blob/master/underscore.js#L559 underscore-uniq}
+ * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter mozilla-array-filter}
+ * @see {@link mozilla-array-filter}
+ * @see {@link underscore-uniq}
+ * @see {@link mobx-uniq}
+ * @see {@link lodash-uniq}
+ *
+ * @example
+ *
+ * var list = [
+ * 1, 2, 3,
+ * 1, 2, 3,
+ * 1, 2, 3
+ * ]
+ *
+ * list.filter(uniq)
+ * //=> [1, 2, 3]
+ *
+ */
module.exports = (value, index, arr) => arr.indexOf(value) === index
diff --git a/src/deps/cache/cache.js b/src/deps/cache/cache.js
new file mode 100644
index 0000000..c08549c
--- /dev/null
+++ b/src/deps/cache/cache.js
@@ -0,0 +1 @@
+module.exports = new Map()
diff --git a/src/deps/gc.js b/src/deps/cache/gc.js
similarity index 86%
rename from src/deps/gc.js
rename to src/deps/cache/gc.js
index e9c5a4d..d377a12 100644
--- a/src/deps/gc.js
+++ b/src/deps/cache/gc.js
@@ -1,7 +1,8 @@
-const ObjectProperties = require('./util/props')
-const traverse = require('./traverse')
-const isObj = require('./is/obj')
-const isArray = require('./is/array')
+const ObjectProperties = require('../util/props')
+const traverse = require('../traverse')
+const isObj = require('../is/obj')
+const isArray = require('../is/array')
+const keys = require('../util/keysObjOrArray')
// function gc() {
// if (typeof window !== 'undefined') window.global = window
@@ -9,6 +10,12 @@ const isArray = require('./is/array')
// }
/**
+ * @since 4.0.0
+ * @desc remove all methods, mark for garbage collection
+ *
+ * @param {Object} obj object to traverse and clear
+ * @return {void}
+ *
* @see https://stackoverflow.com/questions/1947995/when-should-i-use-delete-vs-setting-elements-to-null-in-javascript
* @see https://v8project.blogspot.ca/2015/08/getting-garbage-collection-for-free.html
* @see https://github.com/natewatson999/js-gc
@@ -20,11 +27,6 @@ const isArray = require('./is/array')
* @TODO blacklist = [] param
* @TODO put all GC events into a cached map and debounce the operation
*
- * @since 4.0.0
- * @desc remove all methods, mark for garbage collection
- * @param {Object} obj object to traverse and clear
- * @return {void}
- *
* @example
*
* var scoped = {}
@@ -40,7 +42,8 @@ const isArray = require('./is/array')
*/
function markForGarbageCollection(obj) {
// @TODO: ArrayOrObj loop... like tons of libs do...
- let props = isObj(obj) ? ObjectProperties(obj) : obj //isArray(obj) ? obj
+ // let props = isObj(obj) ? ObjectProperties(obj) : obj //isArray(obj) ? obj
+ let props = keys(obj)
for (let p = 0; p < props.length; p++) {
if (isObj(obj[p])) {
diff --git a/src/deps/cache/index.js b/src/deps/cache/index.js
index c08549c..7e77318 100644
--- a/src/deps/cache/index.js
+++ b/src/deps/cache/index.js
@@ -1 +1 @@
-module.exports = new Map()
+module.exports = require('./cache')
diff --git a/src/deps/cache/oneArgumentPooler.js b/src/deps/cache/oneArgumentPooler.js
new file mode 100644
index 0000000..f5ccd89
--- /dev/null
+++ b/src/deps/cache/oneArgumentPooler.js
@@ -0,0 +1,42 @@
+/* eslint consistent-this: ["error", "Klass"] */
+
+const ENV_DEBUG = require('../env/debug')
+
+/**
+ * Static poolers. Several custom versions for each potential number of
+ * arguments. A completely generic pooler is easy to implement, but would
+ * require accessing the `arguments` object. In each of these, `this` refers to
+ * the Class itself, not an instance. If any others are needed, simply add them
+ * here, or in their own files.
+ *
+ * @since 5.0.0
+ * @memberOf pooler
+ *
+ * @param {Object} copyFieldsFrom obj with instance pool (arguments for constructor?)
+ * @return {Object} instance of Klass
+ *
+ * @example
+ *
+ * class Eh {}
+ * addPoolingTo(Eh)
+ * const eh = Eh.getPooled() //=> oneArgumentPooler(Eh)
+ * eh.release()
+ *
+ */
+module.exports = function oneArgumentPooler(copyFieldsFrom) {
+ const Klass = this
+ if (Klass.instancePool.length) {
+ const instance = Klass.instancePool.pop()
+ // require('fliplog').quick({Klass, instance, copyFieldsFrom})
+
+ // @TODO or a static construct!
+ // if (Klass.construct) Klass.construct.call(instance, copyFieldsFrom)
+ if (instance.construct) instance.construct(copyFieldsFrom)
+ else Klass.call(instance, copyFieldsFrom)
+
+ return instance
+ }
+ else {
+ return new Klass(copyFieldsFrom)
+ }
+}
diff --git a/src/deps/cache/pooler.js b/src/deps/cache/pooler.js
new file mode 100644
index 0000000..f471851
--- /dev/null
+++ b/src/deps/cache/pooler.js
@@ -0,0 +1,64 @@
+/* eslint consistent-this: ["error", "Klass"] */
+
+const ENV_DEBUG = require('../env/debug')
+const standardReleaser = require('./standardReleaser')
+const oneArgumentPooler = require('./oneArgumentPooler')
+
+/**
+ * @symb 🎱
+ * @member pooler
+ * @type {Object}
+ *
+ * {@link https://github.com/atheros/node-advanced-pool node-advanced-pool}
+ *
+ * {@link https://github.com/facebook/react/blob/master/src/renderers/shared/utils/PooledClass.js react-pooler}
+ * @see {@link react-pooler}
+ *
+ * @tests deps/pooler
+ * @types deps.cache.pooler
+ */
+const DEFAULT_POOLER = oneArgumentPooler
+const DEFAULT_POOL_SIZE = 10
+
+/**
+ * Augments `CopyConstructor` to be a poolable class, augmenting only the class
+ * itself (statically) not adding any prototypical fields. Any CopyConstructor
+ * you give this may have a `poolSize` property, and will look for a
+ * prototypical `destructor` on instances.
+ *
+ * @since 5.0.0
+ * @memberOf pooler
+ *
+ * @param {Function | Object} CopyConstructor Constructor that can be used to reset.
+ * @param {Function} pooler Customizable pooler.
+ * @return {Object} enhanced constructor, decorated with pooler
+ *
+ * @prop {Array} instancePool
+ * @prop {number} poolSize
+ * @prop {Function} release
+ * @prop {Function} getPooled
+ *
+ * @example
+ *
+ * class Eh {}
+ * addPoolingTo(Eh) // can optionally pass in pooler as second arg
+ * //=> Eh.instancePool = []
+ * //=> Eh.getPooled = pooler || singleArgumentPooler
+ * //=> Eh.poolSize = 10
+ * //=> Eh.release = standardReleaser
+ *
+ */
+function addPoolingTo(CopyConstructor, pooler) {
+ // Casting as any so that flow ignores the actual implementation and trusts
+ // it to match the type we declared
+ const NewKlass = CopyConstructor
+
+ NewKlass.instancePool = []
+ NewKlass.getPooled = pooler || DEFAULT_POOLER
+ if (!NewKlass.poolSize) NewKlass.poolSize = DEFAULT_POOL_SIZE
+ NewKlass.release = standardReleaser
+
+ return NewKlass
+}
+
+module.exports = addPoolingTo
diff --git a/src/deps/cache/standardReleaser.js b/src/deps/cache/standardReleaser.js
new file mode 100644
index 0000000..426206e
--- /dev/null
+++ b/src/deps/cache/standardReleaser.js
@@ -0,0 +1,41 @@
+/* eslint consistent-this: ["error", "Klass"] */
+
+const ENV_DEBUG = require('../env/debug')
+
+/**
+ * @desc call destructor on a pooled instance, put it back in the pool
+ * @since 5.0.0
+ * @memberOf pooler
+ *
+ * @param {Object} instance call destructor
+ * @return {void}
+ *
+ * @prop {Array} instancePool
+ * @prop {number} poolSize
+ * @prop {Function} destructor
+ *
+ * @example
+ *
+ * class Eh {}
+ * addPoolingTo(Eh)
+ * const eh = Eh.getPooled()
+ * eh.release()
+ *
+ */
+module.exports = function standardReleaser(instance) {
+ const Klass = this
+
+ if (ENV_DEBUG) {
+ if (instance instanceof Klass) {
+ throw new Error(
+ `Trying to release an instance
+ into a pool of a different type.`
+ )
+ }
+ }
+
+ instance.destructor()
+ if (Klass.instancePool.length < Klass.poolSize) {
+ Klass.instancePool.push(instance)
+ }
+}
diff --git a/src/deps/cache/weak.js b/src/deps/cache/weak.js
new file mode 100644
index 0000000..348f3a9
--- /dev/null
+++ b/src/deps/cache/weak.js
@@ -0,0 +1,12 @@
+const isWeakMapUsable = require('../is/weakMapUsable')
+
+let weakMap
+
+if (isWeakMapUsable) {
+ weakMap = new WeakMap()
+}
+// else {
+// weakMap =
+// }
+
+module.exports = weakMap
diff --git a/src/deps/cast/README.md b/src/deps/cast/README.md
new file mode 100644
index 0000000..fbec326
--- /dev/null
+++ b/src/deps/cast/README.md
@@ -0,0 +1,21 @@
+# cast
+> cast & coerce values
+
+# todo
+- [ ] `curry(2, coerce(type, arg))`
+- [ ] add `serialize` for persisting & hydrating with strings, using `new Function` as needed (mark in metadata)
+
+# resources
+- http://duktape.org/guide.html#type-conversion-and-testing
+
+# why?
+> TypeGuards
+
+(_the assumption based on research & testing the compiled code, though it is likely there are more things to check and more known unknowns_)
+
+- megamorphic code wrapping the monomorphic code is perfect
+- with the arg casting, it makes a solid decision tree, which ends up just becoming a `GO TO LINE#` -> `easily optimized cast function`
+"
+- this is how typescript should compile
+- this is likely why lodash has internal functions called `base`
+- the other way to handle it is throw errors with invalid types
\ No newline at end of file
diff --git a/src/deps/cast/argumentor.js b/src/deps/cast/argumentor.js
new file mode 100644
index 0000000..2c1459e
--- /dev/null
+++ b/src/deps/cast/argumentor.js
@@ -0,0 +1 @@
+module.exports = require('./argumentsToArray')
diff --git a/src/deps/cast/argumentsToArray.js b/src/deps/cast/argumentsToArray.js
new file mode 100644
index 0000000..ca25ed6
--- /dev/null
+++ b/src/deps/cast/argumentsToArray.js
@@ -0,0 +1,37 @@
+const preAllocate = require('../array/preAllocate')
+
+/**
+ * @desc turns arguments into an array, used as a util, for opt
+ *
+ * @name argumentor
+ * @version 2.0.0 <- use preAllocate
+ * @since 3.0.0
+ * @return {Array}
+ *
+ * {@link http://mrale.ph/blog/2015/11/02/crankshaft-vs-arguments-object.html crankshaft-vs-arguments}
+ * {@link https://github.com/jashkenas/underscore/blob/master/underscore.js#L109 underscore-rest-arts}
+ * {@link https://github.com/aretecode/awesome-deopt awesome-deopt}
+ * {@link https://github.com/petkaantonov/bluebird/wiki/Optimization-killers bluebird-optimization-killers}
+ * @see {@link crankshaft-vs-arguments}
+ * @see {@link bluebird-optimization-killers}
+ * @see {@link underscore-rest-arts}
+ * @see deps/util/lengthFromZero
+ * @see deps/array/preAllocate
+ *
+ * @example
+ *
+ * function eh() {
+ * const args = argumentor.apply(null, arguments).slice(1)
+ *
+ * console.log(args)
+ * //=> [1, 10, 100]
+ * }
+ * eh(0, 1, 10, 100)
+ *
+ */
+module.exports = function() {
+ const len = arguments.length
+ const args = preAllocate(len)
+ for (let i = 0; i < len; ++i) args[i] = arguments[i]
+ return args
+}
diff --git a/src/deps/cast/arrayToIterator.js b/src/deps/cast/arrayToIterator.js
new file mode 100644
index 0000000..2f126d2
--- /dev/null
+++ b/src/deps/cast/arrayToIterator.js
@@ -0,0 +1,58 @@
+/**
+ * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/values mozilla-array-values}
+ * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/entries mozilla-array-entries}
+ * {@link https://github.com/mobxjs/mobx/blob/master/src/utils/iterable.ts mobx-array-to-iteratable}
+ * {@link https://github.com/leebyron/iterall/ mobx-inspiration-iterall}
+ * @see {@link mozilla-array-values}
+ * @see {@link mozilla-array-entries}
+ * @see {@link mobx-array-to-iteratable}
+ * @see {@link mobx-inspiration-iterall}
+ * @memberOf cast
+ *
+ * @see Chainable[Symbol.Iterator] much preferred
+ *
+ * @TODO `Array.prototype.values ? x => Array.prototype.values.call(x)`
+ * @TODO examples
+ * @TODO tests
+ */
+
+const ENV_COMPAT = require('../env/compat')
+
+if (ENV_COMPAT) {
+ const SymbolIterator = require('../symbols/iterator')
+ const addHiddenFinalProp = require('../util/defineFinal')
+
+ // @@iterating
+ const IS_ITERATING_MARKER = '__$$iterating'
+
+ function arrayToIterator(array) {
+ // returning an array for entries(), values() etc for maps was a mis-interpretation of the specs..,
+ // yet it is quite convenient to be able to use the response both as array directly and as iterator
+ // it is suboptimal, but alas...
+ // invariant(array[IS_ITERATING_MARKER] !== true, 'Illegal state: cannot recycle array as iterator')
+ addHiddenFinalProp(array, IS_ITERATING_MARKER, true)
+
+ let idx = -1
+ addHiddenFinalProp(array, 'next', function next() {
+ idx++
+ return {
+ done: idx >= this.length,
+ value: idx < this.length ? this[idx] : undefined,
+ }
+ })
+ return array
+ }
+
+ function declareIterator(prototType, iteratorFactory) {
+ addHiddenFinalProp(prototType, SymbolIterator, iteratorFactory)
+ }
+
+ // @TODO improve
+ module.exports = {declareIterator, arrayToIterator}
+}
+else {
+ const invoke = require('../fp/invoke')
+ const ArrayEntries = require('../native/arrayEntries')
+
+ module.exports = invoke(ArrayEntries, 'call')
+}
diff --git a/src/deps/cast/arrayToObj.js b/src/deps/cast/arrayToObj.js
new file mode 100644
index 0000000..5c45bc9
--- /dev/null
+++ b/src/deps/cast/arrayToObj.js
@@ -0,0 +1,47 @@
+const isArray = require('../is/array')
+const getLength = require('../util/length')
+const castKey = require('./toKey')
+
+/**
+ * Converts lists into objects.
+ * Pass either
+ * 1. a single array of `[key, value]` pairs,
+ * 2. or two parallel arrays of the same length -- one of keys, and one of
+ * the corresponding values.
+ * Passing by pairs is the reverse of _.pairs.
+ * @since 5.0.0-beta.6
+ * @memberOf cast
+ *
+ * @alias fromPairs
+ *
+ * @param {Array} list list of keys, or of [key, value] pairs
+ * @param {Array} [values] values if not using pairs
+ * @return {Object}
+ *
+ * @see cast/pairs
+ *
+ * @example
+ * arrayToObj
+ */
+function arrayToObj(list, values) {
+ let result = {}
+
+ for (let i = 0, length = getLength(list); i < length; i++) {
+ // keys, values
+ if (values) {
+ result[list[i]] = values[i]
+ }
+ // fallback to list as an object as pairs,
+ else if (isArray(list[i])) {
+ result[list[i][0]] = list[i][1]
+ }
+ // cast key, values-as-keys
+ else {
+ result[castKey(list[i])] = list[i]
+ }
+ }
+
+ return result
+}
+
+module.exports = arrayToObj
diff --git a/src/deps/cast/arrayToSet.js b/src/deps/cast/arrayToSet.js
new file mode 100644
index 0000000..20af3ea
--- /dev/null
+++ b/src/deps/cast/arrayToSet.js
@@ -0,0 +1,21 @@
+const newSet = require('../construct/set')
+
+/**
+ * Object or Array into a Set
+ * @since 5.0.0-beta.6
+ * @memberOf cast
+ *
+ * @name arrayToSet
+ * @alias arrToSet
+ *
+ * @param {Array} array cast to Set
+ * @return {Set} Set(x)
+ *
+ */
+const arrayToSet = array => {
+ const aSet = newSet()
+ for (let key = 0; key < array.length; key++) aSet(array[key])
+ return aSet
+}
+
+module.exports = arrayToSet
diff --git a/src/deps/cast/asciiToArray.js b/src/deps/cast/asciiToArray.js
new file mode 100644
index 0000000..096a6fb
--- /dev/null
+++ b/src/deps/cast/asciiToArray.js
@@ -0,0 +1,13 @@
+/**
+ * Converts an ASCII `string` to an array.
+ * @since 5.0.0-beta.6
+ * @memberOf cast
+ *
+ * @param {string} string The string to convert.
+ * @returns {Array} Returns the converted array.
+ */
+function asciiToArray(string) {
+ return string.split('')
+}
+
+module.exports = asciiToArray
diff --git a/src/deps/cast/cast.js b/src/deps/cast/cast.js
new file mode 100644
index 0000000..052b259
--- /dev/null
+++ b/src/deps/cast/cast.js
@@ -0,0 +1,99 @@
+// primitive
+const boolean = require('./toBoolean')
+const string = require('./toString')
+const obj = require('./toObj')
+const toPlainObject = require('./toPlainObj')
+const toArguments = require('./toArguments')
+// number
+const number = require('./toNumber')
+const integer = require('./toInteger')
+const toInt32 = require('./toUint32')
+const toUint31 = require('./toUint31')
+const toUint32 = require('./toUint32')
+const toLength = require('./toLength')
+const toFinite = require('./toFinite')
+// array
+const array = require('./toArray')
+const pairs = require('./toPairs')
+const arrayToObj = require('./arrayToObj')
+const asciiToArray = require('./asciiToArray')
+const unicodeToArray = require('./unicodeToArray')
+const setToArray = require('./setToArray')
+const stringToArray = require('./stringToArray')
+const stringToCharCodes = require('./stringToCharCodes')
+const argumentsToArray = require('./argumentsToArray')
+// collection
+const objToMap = require('./objToMap')
+const arrayToSet = require('./arrayToSet')
+const setToPairs = require('./setToPairs')
+// iterator
+const iteratorToArray = require('./iteratorToArray')
+const arrayToIterator = require('./arrayToIterator')
+const keyValueToIterator = require('./keyValueToIterator')
+// other
+const toDate = require('./toDate')
+const defaultTo = require('./defaultTo')
+const toFunction = require('./toFunction')
+const toKey = require('./toKey')
+const toTestable = require('./toTestable')
+const toRegExp = require('./toRegExp')
+
+// const coerce = require('./coerce')
+
+const func = toFunction
+const objToArray = pairs
+const set = setToArray
+
+/**
+ * @symb 🕑 (for 2)
+ * @member cast
+ * @member to
+ * @type {Object}
+ */
+module.exports = {
+ array,
+ boolean,
+ integer,
+ number,
+ // map,
+ obj,
+ string,
+ // to
+ toArray: array,
+ toBoolean: boolean,
+ toInteger: integer,
+ toNumber: number,
+ toObj: obj,
+ toString: string,
+ // more casting
+ asciiToArray,
+
+ argumentsToArray,
+ iteratorToArray,
+ arrayToIterator,
+ arrayToObj,
+ unicodeToArray,
+ setToArray,
+ stringToArray,
+ stringToCharCodes,
+ objToArray,
+ objToMap,
+ toPlainObject,
+ toPlainObj: toPlainObject,
+ defaultTo,
+ arrayToSet,
+ toFunction,
+ // eh
+ toArguments,
+ toInt32,
+ toUint31,
+ toUint32,
+ toLength,
+ toFinite,
+ setToPairs,
+ keyValueToIterator,
+ toDate,
+ toKey,
+ toTestable,
+ toRegExp,
+}
diff --git a/src/deps/cast/coerce.js b/src/deps/cast/coerce.js
new file mode 100644
index 0000000..bcace33
--- /dev/null
+++ b/src/deps/cast/coerce.js
@@ -0,0 +1,14 @@
+// use in toArr & chained-set
+// const objToPairs = obj => {}
+//
+// const coerceTo = type => data => {
+// // toBoolean
+// // toString
+// // toObject
+// // toArray
+// // toMap
+// // toSet
+// }
+
+// - [ ] would be possible to coerce values in a function wrapper,
+// that way we can optimize some functions more predictably
diff --git a/src/deps/cast/defaultTo.js b/src/deps/cast/defaultTo.js
new file mode 100644
index 0000000..95286fa
--- /dev/null
+++ b/src/deps/cast/defaultTo.js
@@ -0,0 +1,40 @@
+const isNill = require('../is/nullOrUndefined')
+const curry = require('../fp/curry')
+
+/**
+ * Returns the second argument if it is not `null`, `undefined` or `NaN`
+ * otherwise the first argument is returned.
+ *
+ * @since 5.0.0-beta.5
+ * @memberOf cast
+ * @curried 2
+ *
+ * @param {*} value The default value.
+ * @param {*} arg `val` will be returned instead of `default` unless `val` is `null`, `undefined` or `NaN`.
+ * @return {*} The second value if it is not `null`, `undefined` or `NaN`, otherwise the default value
+ *
+ * {@link https://github.com/ramda/ramda/blob/master/src/defaultTo.js ramda-default-to}
+ * @see {@link ramda-default-to}
+ * @see is/real
+ *
+ * @func
+ * @fork v0.10.0
+ * @category Logic
+ * @sig a -> b -> a | b
+ *
+ * @example
+ *
+ * const defaultToOne = defaultTo(1)
+ *
+ * defaultToOne(0) //=> 1
+ * defaultToOne(null) //=> 1
+ * defaultToOne(undefined) //=> 1
+ * defaultToOne('eh') //=> 'eh'
+ *
+ * const NotEhNumber = Number(undefined)
+ * defaultToOne(NotEhNumber) //=> 1
+ *
+ */
+module.exports = curry(2, function defaultTo(value, arg) {
+ return isNill(arg) ? value : arg
+})
diff --git a/src/deps/cast/fromBufferToUint8Array.js b/src/deps/cast/fromBufferToUint8Array.js
new file mode 100644
index 0000000..94339ed
--- /dev/null
+++ b/src/deps/cast/fromBufferToUint8Array.js
@@ -0,0 +1,10 @@
+// @TODO https://github.com/fluents/chain-able/issues/59
+// `Wasm` does **not** understand node buffers, but thankfully a node buffer
+// is easy to convert to a native Uint8Array.
+module.exports = function fromBufferToUint8Array(buffer) {
+ var u = new Uint8Array(buffer.length)
+ for (var i = 0; i < buffer.length; ++i) {
+ u[i] = buffer[i]
+ }
+ return u
+}
diff --git a/src/deps/cast/fromIshToBoolean.js b/src/deps/cast/fromIshToBoolean.js
new file mode 100644
index 0000000..3bf3a8d
--- /dev/null
+++ b/src/deps/cast/fromIshToBoolean.js
@@ -0,0 +1,10 @@
+const {isTruish, isFalsish} = require('../regexp/matchBooleanish')
+const toBoolean = require('./toBoolean')
+
+const fromIshToBoolean = x => {
+ if (isTruish(x)) return true
+ else if (isFalsish(x)) return false
+ else return toBoolean(x)
+}
+
+module.exports = fromIshToBoolean
diff --git a/src/deps/cast/index.js b/src/deps/cast/index.js
new file mode 100644
index 0000000..81e3055
--- /dev/null
+++ b/src/deps/cast/index.js
@@ -0,0 +1 @@
+module.exports = require('./cast')
diff --git a/src/deps/cast/iteratorToArray.js b/src/deps/cast/iteratorToArray.js
new file mode 100644
index 0000000..f29d6a6
--- /dev/null
+++ b/src/deps/cast/iteratorToArray.js
@@ -0,0 +1,40 @@
+const preAllocate = require('../array/preAllocate')
+
+/**
+ * @desc convert an iterator into an array using
+ * @since 5.0.0-beta.6
+ * @memberOf cast
+ *
+ * @name iteratorToArray
+ * @alias arrayFromIterator
+ *
+ * @param {Iterator} iter iterator
+ * @return {Array<*>} iterator values
+ *
+ * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators mozilla-iterators-and-generators}
+ * @see {@link mozilla-iterators-and-generators}
+ * @see symbols/iterator
+ * @see array/preAllocate
+ *
+ * @example
+ *
+ * const map = new Map(Object.entries({eh: true}))
+ *
+ * iteratorToArray(map.keys())
+ * //=> ['eh']
+ *
+ * iteratorToArray(new Set([0, 1]).keys())
+ * //=> [0, 1]
+ *
+ */
+module.exports = function iteratorToArray(iter) {
+ const list = preAllocate(iter)
+ let next
+ let index = 0
+
+ while (!(next = iter.next()).done && index++) {
+ list[index] = next.value
+ }
+
+ return list
+}
diff --git a/src/deps/cast/keyValueToIterator.js b/src/deps/cast/keyValueToIterator.js
new file mode 100644
index 0000000..d725fef
--- /dev/null
+++ b/src/deps/cast/keyValueToIterator.js
@@ -0,0 +1,48 @@
+const isUndefined = require('../is/undefined')
+
+/**
+ * @name keyValueToIterator
+ * @since 5.0.0-beta.6
+ *
+ * @param {Array} keys array of keys
+ * @param {Array<*>} values array of values
+ * @param {number} size length/size
+ * @return {Iterator}
+ *
+ * @NOTE isSet(map) ? preAllocate(size) : map.keys() <- works, but too monomorphic
+ * @TODO could do prepack-style and have returned object reused?
+ *
+ * {@link https://tc39.github.io/ecma262/#sec-operations-on-iterator-objects emca-iterator-operations}
+ * {@link https://github.com/facebook/immutable-js/blob/master/src/Iterator.js#L19 immutable-js-iterator}
+ * @see {@link immutable-js-iterator}
+ * @see {@link emca-iterator-operations}
+ *
+ * @example
+ *
+ * keyValueToIterator([0, 1], ['one', 'two'], 2)
+ * //=> {value: [0, 'one'], done: false, i: 0}
+ * //=> {value: [1, 'two'], done: false, i: 1}
+ * //=> {value: undefined, done: true, i: 2}
+ *
+ */
+module.exports = function keyValueToIterator(keys, values, size) {
+ return {
+ i: 0,
+ next() {
+ let i = this.i
+ let key = i
+ const val = values[i]
+ key = keys[i]
+
+ // done - no more values, or iteration reached size
+ if ((isUndefined(key) && isUndefined(val)) || size <= i) {
+ return {value: undefined, done: true}
+ }
+
+ this.i++
+
+ // return
+ return {value: [key, val], done: false}
+ },
+ }
+}
diff --git a/src/deps/cast/mapToArray.js b/src/deps/cast/mapToArray.js
new file mode 100644
index 0000000..fee37a9
--- /dev/null
+++ b/src/deps/cast/mapToArray.js
@@ -0,0 +1,31 @@
+const preAllocate = require('../array/preAllocate')
+
+/**
+ * @desc Converts `map` to its key-value pairs.
+ * @since 5.0.0-beta.6
+ *
+ * @param {Object} map The map to convert.
+ * @return {Array} Returns the key-value pairs.
+ *
+ * {@link https://github.com/andrewplummer/Sugar/blob/master/lib/common.js#L1235 sugar-settoarray}
+ * {@link https://github.com/lodash/lodash/blob/master/.internal/mapToArray.js lodash-maptoarray}
+ * @see {@link lodash-maptoarray}
+ * @see {@link sugar-maptoarray}
+ * @see cast/pairs
+ *
+ * @example
+ * mapToArray(new Map(Object.entries({eh: true})))
+ * //=> [ ['eh', true] ]
+ */
+function mapToArray(map) {
+ let index = -1
+ const result = preAllocate(map.size)
+
+ map.forEach((value, key) => {
+ result[++index] = [key, value]
+ })
+
+ return result
+}
+
+module.exports = mapToArray
diff --git a/src/deps/cast/objToMap.js b/src/deps/cast/objToMap.js
new file mode 100644
index 0000000..60efd4c
--- /dev/null
+++ b/src/deps/cast/objToMap.js
@@ -0,0 +1,52 @@
+const newMap = require('../construct/map')
+const hasOwnProperty = require('../util/hasOwnProperty')
+
+/**
+ * Object into a Map
+ * @since 5.0.0-beta.6
+ * @memberOf cast
+ *
+ * @name objToMap
+ * @alias objectToMap
+ *
+ * @param {*} obj cast to Map
+ * @return {Map} Map(x)
+ *
+ * Object.keys(obj).forEach(key => map.set(key, obj[key]))
+ * @TODO use `forOwn`
+ * @TODO can just use obj.hasOwnProperty again?
+ *
+ * {@link https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/entries#Converting_an_Object_to_a_Map mozilla-obj-to-map}
+ * @see {@link mozilla-obj-to-map}
+ *
+ * @example
+ *
+ * const obj = {eh: 0}
+ * const map = objToMap(obj)
+ *
+ * map.has('eh')
+ * //=> true
+ *
+ * map.get('eh')
+ * //=> 0
+ *
+ * map.size
+ * //=> 1
+ *
+ */
+const objToMap = obj => {
+ const map = newMap()
+
+ // eslint-disable-next-line
+ for (let prop in obj) hasOwnProperty(obj, prop) && map.set(prop, obj[prop]);
+
+ return map
+}
+
+/**
+ * @TODO
+ * const map = pipe(entries, newMap)
+ * const map = newMap(Object.entries(obj))
+ */
+
+module.exports = objToMap
diff --git a/src/deps/cast/setToArray.js b/src/deps/cast/setToArray.js
new file mode 100644
index 0000000..6d6e414
--- /dev/null
+++ b/src/deps/cast/setToArray.js
@@ -0,0 +1,44 @@
+const preAllocate = require('../array/preAllocate')
+
+/**
+ * Set into Array
+ * @since 5.0.0-beta.6
+ * @memberOf cast
+ *
+ * @param {Set} set cast to Array
+ * @return {Array} Array(x)
+ *
+ * @name setToArray
+ * @alias setToArr
+ * @alias fromSetToArray
+ *
+ * {@link https://github.com/andrewplummer/Sugar/blob/master/lib/common.js#L1227 sugar-settoarray}
+ * {@link https://github.com/lodash/lodash/blob/master/.internal/setToArray.js lodash-settoarray}
+ * @see {@link lodash-settoarray}
+ * @see {@link sugar-settoarray}
+ * @see cast/set
+ *
+ * @example
+ *
+ * setToArray(new Set(['eh', 'oh']))
+ * //=> ['eh', 'oh']
+ *
+ */
+module.exports = function setToArray(set) {
+ // allocate an array with the size of the set
+ const allocated = preAllocate(set)
+
+ let index = 0
+
+ // @NOTE this can mess things up when using index from `forEach`
+ // and just add empty items
+ // @NOTE remember not to 1 line arrow useless return here
+ //
+ // is `forEach` fastest? is shortest?
+ set.forEach(value => {
+ allocated[index++] = value
+ // allocated[index] = value
+ })
+
+ return allocated
+}
diff --git a/src/deps/cast/setToPairs.js b/src/deps/cast/setToPairs.js
new file mode 100644
index 0000000..6ee3a64
--- /dev/null
+++ b/src/deps/cast/setToPairs.js
@@ -0,0 +1,43 @@
+const isTrue = require('../is/true')
+const preAllocate = require('../array/preAllocate')
+const toKey = require('./toKey')
+
+/**
+ * Converts `set` to its value-value pairs (_or index/key-value with useIndex_).
+ * @since 5.0.0-beta.7
+ * @memberOf cast
+ *
+ * @param {Set} set The set to convert.
+ * @param {boolean} [useIndex=false] use [index, value] rather than [value, value]
+ * @return {Array} Returns the value-value pairs.
+ *
+ * @name setToArray
+ * @alias setToArr
+ * @alias fromSetToArray
+ *
+ * {@link https://github.com/lodash/lodash/blob/master/.internal/setToPairs.js lodash-settopairs}
+ * @see {@link lodash-settopairs}
+ * @see cast/set
+ * @see cast/toKey
+ *
+ * @example
+ *
+ * setToPairs(new Set(['eh', 'oh']))
+ * //=> [['eh', 'eh'], ['oh', 'oh']]
+ *
+ * setToPairs(new Set(['eh', 'oh']), true)
+ * //=> [['0', 'eh'], ['1', 'oh']]
+ *
+ */
+function setToPairs(set, useIndex) {
+ let index = -1
+ const result = preAllocate(set)
+
+ set.forEach(value => {
+ result[++index] = [isTrue(useIndex) ? toKey(index) : value, value]
+ })
+
+ return result
+}
+
+module.exports = setToPairs
diff --git a/src/deps/cast/stringToArray.js b/src/deps/cast/stringToArray.js
new file mode 100644
index 0000000..63cb8e6
--- /dev/null
+++ b/src/deps/cast/stringToArray.js
@@ -0,0 +1,30 @@
+const hasUnicode = require('../string/hasUnicode')
+const asciiToArray = require('./asciiToArray')
+const unicodeToArray = require('./unicodeToArray')
+
+/**
+ * Converts `string` to an array, checks unicode & asci
+ * @since 5.0.0-beta.6
+ * @memberOf cast
+ *
+ * @name stringToArray
+ * @alias stringToArr
+ * @alias strToArr
+ *
+ * @param {string} string The string to convert.
+ * @return {Array} Returns the converted array. `Array(x)`
+ *
+ * {@link https://github.com/lodash/lodash/blob/master/.internal/stringToArray.js lodash-stringtoarray}
+ * @see {@link lodash-stringtoarray}
+ * @see string/hasUnicode
+ * @see cast/unicodeToArray
+ * @see cast/asciiToArray
+ *
+ * @example
+ * stringToArray('eh') //=> ['e', 'eh']
+ */
+function stringToArray(string) {
+ return hasUnicode(string) ? unicodeToArray(string) : asciiToArray(string)
+}
+
+module.exports = stringToArray
diff --git a/src/deps/cast/stringToCharCodes.js b/src/deps/cast/stringToCharCodes.js
new file mode 100644
index 0000000..7360f3d
--- /dev/null
+++ b/src/deps/cast/stringToCharCodes.js
@@ -0,0 +1,8 @@
+const charCodeAtZero = require('../string/charCodeAtZero')
+const stringToArray = require('./stringToArray')
+
+function stringToCharCodes(x) {
+ return stringToArray(x).map(charCodeAtZero)
+}
+
+module.exports = stringToCharCodes
diff --git a/src/deps/cast/toArguments.js b/src/deps/cast/toArguments.js
new file mode 100644
index 0000000..5b144b4
--- /dev/null
+++ b/src/deps/cast/toArguments.js
@@ -0,0 +1,17 @@
+function returnArguments() {
+ return arguments
+}
+
+/**
+ * Converts `array` to an `arguments` object.
+ * @since 5.0.0-beta.6
+ * @memberOf cast
+ * @alias castArguments
+ * @alias toArgs
+ *
+ * @param {Array} [array] The array to convert.
+ * @return {Object} Returns the converted `arguments` object.
+ */
+module.exports = function toArgs() {
+ return returnArguments.apply(undefined, arguments)
+}
diff --git a/src/deps/cast/toArray.js b/src/deps/cast/toArray.js
new file mode 100644
index 0000000..eb9f413
--- /dev/null
+++ b/src/deps/cast/toArray.js
@@ -0,0 +1,2 @@
+// https://github.com/lodash/lodash/blob/master/toArray.js
+module.exports = require('../to-arr')
diff --git a/src/deps/cast/toBoolean.js b/src/deps/cast/toBoolean.js
new file mode 100644
index 0000000..96ccd2b
--- /dev/null
+++ b/src/deps/cast/toBoolean.js
@@ -0,0 +1,29 @@
+/**
+ * @name toBoolean
+ * @alias toBool
+ *
+ * @since 5.0.0-beta.6
+ * @memberOf cast
+ *
+ * @param {*} x anything
+ * @return {boolean} !!x
+ *
+ * {@link https://tc39.github.io/ecma262/#sec-toboolean emca-toboolean}
+ * {@link https://github.com/chriso/validator.js/blob/master/src/lib/toBoolean.js validator-toboolean}
+ * @see {@link validator-toboolean}
+ * @see {@link emca-toboolean}
+ *
+ * @example
+ *
+ * toBoolean(0) //=> false
+ * toBoolean(1) //=> true
+ * toBoolean(true) //=> true
+ * toBoolean(false) //=> false
+ * toBoolean({} //=> true
+ *
+ */
+const toBoolean = function(x) {
+ return !!x
+}
+
+module.exports = toBoolean
diff --git a/src/deps/cast/toDate.js b/src/deps/cast/toDate.js
new file mode 100644
index 0000000..6eca6b1
--- /dev/null
+++ b/src/deps/cast/toDate.js
@@ -0,0 +1,37 @@
+const isNil = require('../is/nullOrUndefined')
+const isDate = require('../is/date')
+const isNumber = require('../is/number')
+const isString = require('../is/string')
+const isArray = require('../is/array')
+const newDate = require('../construct/date')
+
+/**
+ * convert values to dates
+ * @since 5.0.0-beta.7
+ *
+ * @param {Date | number | string | Array<*> | *} date value to cast to a Date
+ * @return {Date} it's a date!
+ *
+ * @example
+ * toDate()
+ * //=> new Date()
+ *
+ * toDate('october-31-1960')
+ * //=> Date.parse('october-31-1960')
+ *
+ * toDate(1000000)
+ * //=> new Date(1000000)
+ *
+ * // year, month [, date, hours, minutes, seconds, milliseconds]
+ * toDate([2014, 1, 1])
+ * //=> new Date(2014, 1, 1)
+ */
+module.exports = function toDate(date) {
+ // this is fallback too
+ // if (isNil(date)) return newDate()
+ if (isDate(date)) return date
+ if (isNumber(date)) return newDate(date)
+ if (isString(date)) return Date.parse(date)
+ if (isArray(date)) return newDate.apply(this, date)
+ else return newDate()
+}
diff --git a/src/deps/cast/toFinite.js b/src/deps/cast/toFinite.js
new file mode 100644
index 0000000..7a699a3
--- /dev/null
+++ b/src/deps/cast/toFinite.js
@@ -0,0 +1,59 @@
+const MAX_INTEGER = require('../native/MAX_INTEGER')
+const INFINITY = require('../native/INFINITY')
+const toNumber = require('./toNumber')
+
+/**
+ * Converts `value` to a finite number.
+ * @since 5.0.0-beta.7
+ * @memberOf cast
+ *
+ * @param {*} value The value to convert.
+ * @return {number} Returns the converted number.
+ *
+ * {@link https://github.com/lodash/lodash/blob/master/toFinite.js lodash-tofinite}
+ * @see {@link lodash-tofinite}
+ * @see is/finite
+ *
+ * @category Lang
+ * @fork 4.12.0
+ *
+ * @example
+ *
+ * toFinite(3.2)
+ * // => 3.2
+ *
+ * toFinite(Number.MIN_VALUE)
+ * // => 5e-324
+ *
+ * toFinite(Infinity)
+ * // => 1.7976931348623157e+308
+ *
+ * toFinite('3.2')
+ * // => 3.2
+ *
+ * toFinite(NaN)
+ * // => 0
+ *
+ */
+function toFinite(value) {
+ // silly check, since casting to number will return a nan at worst
+ // and 0 ? 0 : 0 ?
+ // AND NaN check is at the end anyway 0.0
+ // if (!value) return value === 0 ? value : 0
+
+ value = toNumber(value)
+
+ // when it is infinity,
+ // put it -1 * +Infinity,
+ // or +1 * -Infinity
+ if (value === INFINITY || value === -INFINITY) {
+ const sign = (value < 0 ? -1 : 1)
+ return sign * MAX_INTEGER
+ }
+
+ // @NOTE this just checks isNaN, should be gtg
+ // eslint-disable-next-line
+ return value === value ? value : 0
+}
+
+module.exports = toFinite
diff --git a/src/deps/cast/toFunction.js b/src/deps/cast/toFunction.js
new file mode 100644
index 0000000..de98d54
--- /dev/null
+++ b/src/deps/cast/toFunction.js
@@ -0,0 +1,47 @@
+const keys = require('../util/keys')
+const isObj = require('../is/obj')
+const isFunction = require('../is/function')
+const isClass = require('../is/class')
+const construct = require('../fp/construct')
+const always = require('../fp/always')
+
+/**
+ * @name toFunction
+ * @since 5.0.0-beta.6
+ * @memberOf cast
+ *
+ * @param {Class|Object|*} x class or object to wrap
+ * @param {Function|*} [onCall=null] not implemented, would be onConstruct/call
+ * @return {Function}
+ *
+ * @see fp/construct
+ * @see is/class
+ *
+ * @example
+ *
+ * class Eh {}
+ * const eh = toFunction(Eh)
+ *
+ * isInstanceOf(eh(), Eh)
+ * //=> true
+ *
+ */
+function toFunction(x, onCall = null) {
+ if (isClass(x)) {
+ return construct(x)
+ }
+ else if (isFunction(x)) {
+ return construct(x.length, (x))
+ }
+ else if (isObj(x)) {
+ // could bind
+ const first = keys(x).filter(key => isFunction(x[key]))[0]
+ if (isFunction(first)) return first
+ else return always(x)
+ }
+ // else if (isObj(x)) return construct(x)
+ else {
+ return always(x)
+ }
+}
+module.exports = toFunction
diff --git a/src/deps/cast/toIndex.js b/src/deps/cast/toIndex.js
new file mode 100644
index 0000000..a731379
--- /dev/null
+++ b/src/deps/cast/toIndex.js
@@ -0,0 +1,42 @@
+const size = require('../util/size')
+const isValidArrayIndex = require('../is/validArrayIndex')
+const isStringPrimitive = require('../is/stringPrimitive')
+const toInt32 = require('../cast/toInt32')
+const toLength = require('../cast/toLength')
+
+/**
+ * @name toIndex
+ * @alias castToIndex
+ *
+ * @since 5.0.0-beta.6
+ * @memberOf cast
+ *
+ * @param {number} index index to cast
+ * @param {number | Array} [list=1] number or array
+ * @return {number} valid index
+ *
+ * {@link https://github.com/facebook/immutable-js/blob/master/src/TrieUtils.js#L58 immutable-js-toindex}
+ * {@link https://tc39.github.io/ecma262/#sec-toindex emca-toindex}
+ * @see {@link emca-toindex}
+ * @see {@link immutable-js-toindex}
+ *
+ * @see cast/toLength
+ * @see cast/toInt32
+ * @see cast/toSize
+ * @see is/validArrayIndex
+ * @see is/stringPrimitive
+ */
+module.exports = function toIndex(index, list) {
+ if (isValidArrayIndex(index) && isStringPrimitive(index)) {
+ index = toInt32(index)
+ }
+
+ index = toLength(index)
+
+ // below 0, add index (keep above 0)
+ // else, index
+ return index < 0
+ // @NOTE ensure above 0 if index is way below 0
+ ? (size(list || 1) + index) || 1
+ : index
+}
diff --git a/src/deps/cast/toInt32.js b/src/deps/cast/toInt32.js
new file mode 100644
index 0000000..d990ef8
--- /dev/null
+++ b/src/deps/cast/toInt32.js
@@ -0,0 +1,38 @@
+const MAX_32_BIT = require('../native/MAX_32_BIT')
+const toInteger = require('./toInteger')
+
+/**
+ * ToInt32(argument)
+ * >> 0 is shorthand for toInt32
+ *
+ * @name toInt32
+ * @alias toSigned32
+ * @alias toInteger32
+ * @alias to32BitInteger
+ * @alias to32Bit
+ *
+ * @param {number} x any number
+ * @return {number} 32bit integer
+ *
+ * {@link http://2ality.com/2012/02/js-integers.html 2ality-integers}
+ * {@link https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/JSAPI_reference/JS::ToInt32 mozilla-toint32}
+ * {@link https://tc39.github.io/ecma262/#sec-toint32 emca-toint32}
+ * {@link https://github.com/facebook/immutable-js/blob/master/src/TrieUtils.js#L93 immutable-js-resolveindex}
+ * @see {@link emca-toint32}
+ * @see {@link immutable-js-resolveindex}
+ * @see {@link 2ality-integers}
+ *
+ * @see native/MAX_32_BIT
+ * @see cast/toInteger
+ *
+ * @example
+ *
+ * toInt32(Math.pow(2,32)) //=> 0
+ * toInt32(Math.pow(2,32)+1) //=> 1
+ *
+ */
+function toInt32(x) {
+ return toInteger(x) % MAX_32_BIT
+}
+
+module.exports = toInt32
diff --git a/src/deps/cast/toInteger.js b/src/deps/cast/toInteger.js
new file mode 100644
index 0000000..2f08a9f
--- /dev/null
+++ b/src/deps/cast/toInteger.js
@@ -0,0 +1,61 @@
+const isNaN = require('../is/NaN')
+const toNumber = require('./toNumber')
+
+/**
+ * @name toInteger
+ * @alias toInt
+ *
+ * @since 5.0.0-beta.6
+ * @memberOf cast
+ *
+ * @param {*} x anything
+ * @return {number} Number(x) if x is not nan
+ *
+ * {@link https://github.com/andrewplummer/Sugar/blob/master/lib/common.js#L322 sugar-topositiveinteger}
+ * {@link https://github.com/lodash/lodash/blob/master/toInteger.js lodash-tointeger}
+ * {@link https://github.com/chriso/validator.js/blob/master/src/lib/toInteger.js validator-tointeger}
+ * {@link https://tc39.github.io/ecma262/#sec-tointeger emca-tointeger}
+ * @see {@link emca-tointeger}
+ * @see {@link validator-tointeger}
+ * @see {@link lodash-tointeger}
+ * @see {@link sugar-topositiveinteger}
+ * @see cast/number
+ * @see is/NaN
+ *
+ * @example
+ *
+ * toInteger(10) // => 10
+ * toInteger(NaN) // => +0
+ * toInteger(+Infinity) // => +Infinity
+ * toInteger('100') // => +100
+ *
+ * @example
+ *
+ * toInteger(3.2)
+ * //=> 3
+ *
+ * toInteger(Number.MIN_VALUE)
+ * //=> 0
+ *
+ * toInteger(Infinity)
+ * //=> 1.7976931348623157e+308
+ *
+ * toInteger('3.2')
+ * //=> 3
+ *
+ */
+function toInteger(x) {
+ const number = toNumber(x)
+
+ if (isNaN(number)) {
+ return +0
+ }
+ else if (number === 0 || number === -Infinity || number === +Infinity) {
+ return number
+ }
+ else {
+ return Math.sign(number) * Math.floor(Math.abs(number))
+ }
+}
+
+module.exports = toInteger
diff --git a/src/deps/cast/toKey.js b/src/deps/cast/toKey.js
new file mode 100644
index 0000000..11b9ad8
--- /dev/null
+++ b/src/deps/cast/toKey.js
@@ -0,0 +1,60 @@
+const isStringPrimitive = require('../is/stringPrimitive')
+const isSymbol = require('../is/symbol')
+const isZeroish = require('../is/zeroish')
+const isMinusInfinity = require('../is/negativeInfinity')
+
+/**
+ * Converts `value` to a string key if it's not a string or symbol.
+ * Use non-numeric keys to prevent V8 performance issues
+ *
+ * @memberOf cast
+ * @since 5.0.0-beta.6
+ * @alias toProperty
+ * @alias toProp
+ *
+ * @param {*} value The value to inspect.
+ * @return {string|symbol} Returns the key.
+ *
+ * {@link https://github.com/facebook/react/pull/7232 react-tokey}
+ * {@link https://tc39.github.io/ecma262/#sec-topropertykey emca-topropertykey}
+ * {@link https://tc39.github.io/ecma262/#sec-canonicalnumericindexstring emca-canonicalnumericindexstring}
+ * @see {@link emca-canonicalnumericindexstring}
+ * @see {@link emca-topropertykey}
+ * @see {@link react-tokey}
+ *
+ * @example
+ *
+ * const symba = Symbol.for('symba')
+ * toKey(symba)
+ * //=> Symbol.for('symba')
+ *
+ * toKey(0)
+ * //=> '0'
+ *
+ * toKey('0')
+ * //=> '0'
+ *
+ * toKey(-Infinity)
+ * //=> '-0'
+ *
+ * toKey(-0)
+ * //=> '-0'
+ *
+ * toKey(null)
+ * //=> 'null'
+ *
+ *
+ */
+function toKey(value) {
+ if (isStringPrimitive(value) || isSymbol(value)) {
+ return value
+ }
+ else if (isZeroish(value) && isMinusInfinity(value)) {
+ return '-0'
+ }
+ else {
+ return '' + value
+ }
+}
+
+module.exports = toKey
diff --git a/src/deps/cast/toLength.js b/src/deps/cast/toLength.js
new file mode 100644
index 0000000..20cf497
--- /dev/null
+++ b/src/deps/cast/toLength.js
@@ -0,0 +1,62 @@
+const MAX_ARRAY_LENGTH = require('../native/MAX_ARRAY_LENGTH')
+const toInteger = require('./toInteger')
+
+/**
+ * Converts `value` to an integer suitable for use as the length of an
+ * array-like object.
+ *
+ * **Note:** This method is based on emca-toLength
+ * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
+ *
+ * @since 5.0.0-beta.7
+ * @memberOf cast
+ *
+ * @param {*} value The value to convert.
+ * @return {number} Returns the converted integer.
+ *
+ * @fork 4.0.0
+ * @category Lang
+ *
+ * {@link http://ecma-international.org/ecma-262/7.0/#sec-tolength emca-tolength}
+ * {@link https://github.com/lodash/lodash/blob/master/toLength.js lodash-tolength}
+ * {@link https://github.com/jashkenas/underscore/blob/master/underscore.js#L159 underscore-tolength}
+ * @see {@link underscore-tolength}
+ * @see {@link lodash-tolength}
+ * @see {@link emca-tolength}
+ *
+ * @example
+ *
+ * toLength(3.2)
+ * // => 3
+ *
+ * toLength(Number.MIN_VALUE)
+ * // => 0
+ *
+ * toLength(Infinity)
+ * // => 4294967295
+ *
+ * toLength('3.2')
+ * // => 3
+ *
+ */
+function toLength(value) {
+ value = toInteger(value)
+
+ if (value < 0) {
+ return 0
+ }
+ // @TODO why nor return 0?
+ // @TODO if env perf > size?... still, this should
+ // `goto` the last else, easy math
+ // else if (value === 0) {
+ // return value
+ // }
+ else if (value > MAX_ARRAY_LENGTH) {
+ return MAX_ARRAY_LENGTH
+ }
+ else {
+ return value
+ }
+}
+
+module.exports = toLength
diff --git a/src/deps/cast/toNumber.js b/src/deps/cast/toNumber.js
new file mode 100644
index 0000000..5f88b78
--- /dev/null
+++ b/src/deps/cast/toNumber.js
@@ -0,0 +1,87 @@
+// const isBoolean = require('../is/boolean')
+// const isObj = require('../is/objNotNull')
+// const isArray = require('../is/array')
+// const isNumberish = require('../is/numberish')
+// const SymbolPrimitive = require('../symbols/primitive')
+// const hasOwnProperty = require('../util/hasOwnProperty')
+
+/**
+ * @since 5.0.0-beta.6
+ * @memberOf cast
+ *
+ * @name toNumber
+ * @alias toNum
+ * @aka ToNumber
+ *
+ * @param {*} x number to cast to primitive number
+ * @return {number} +x
+ *
+ * {@link http://2ality.com/2012/04/number-encoding.html number-encoding-js}
+ * {@link http://speakingjs.com/es5/ch11.html speaking-js-numbers}
+ * {@link https://coderwall.com/p/5tlhmw/converting-strings-to-number-in-javascript-pitfalls coderwal-to-number}
+ * {@link http://ecma-international.org/ecma-262/7.0/#sec-tonumber emca-to-number}
+ * @see {@link emca-to-number}
+ * @see {@link coderwal-to-number}
+ * @see {@link speaking-js-numbers}
+ * @see {@link number-encoding-js}
+ *
+ * @TODO make this `toNumberPrimitive` while others could convert as codes
+ *
+ *
+ * @example
+ *
+ * toNumber('')
+ * //=> 0
+ * toNumber(' ')
+ * //=> 0
+ * toNumber('eh')
+ * //=> NaN
+ * toNumber('1')
+ * //=> 1
+ * toNumber(null)
+ * //=> 0
+ * toNumber(true)
+ * //=> 1
+ * toNumber(false)
+ * //=> 0
+ * toNumber('00')
+ * //=> 0
+ * toNumber(undefined)
+ * //=> NaN
+ * toNumber({})
+ * //=> NaN
+ * toNumber([])
+ * //=> 0
+ * toNumber([100, 200])
+ * //=> NaN
+ *
+ * @example
+ *
+ * var eh = {Symbol.toPrimitive: hint => hint === 'number' ? 100 : 'eh'}
+ * toNumber(eh)
+ * //=> 100
+ *
+ */
+function toNumber(x) {
+ // @NOTE
+ // if (isNumberish(x) || isBoolean(x)) {
+ // return +x
+ // }
+ // else if (isObj(x)) {
+ // if (hasOwnProperty(x, SymbolPrimitive)) return x[SymbolPrimitive]('number')
+ // else if (isArray(x)) return +x
+ // // this keeps it consistent with array?
+ // else return 0
+ // }
+
+ return +x
+
+ // @TODO
+ // +x || 0
+ //
+ // , coerceNaN = true
+ // const number = +x
+ // return isNotEhNumber(x) ? 0 : x
+}
+
+module.exports = toNumber
diff --git a/src/deps/cast/toObj.js b/src/deps/cast/toObj.js
new file mode 100644
index 0000000..698c3a1
--- /dev/null
+++ b/src/deps/cast/toObj.js
@@ -0,0 +1,38 @@
+const isNil = require('../is/nullOrUndefined')
+
+/**
+ * cast to object, instead of throwing (like in the spec), returns {} if nill
+ * @since 5.0.0-beta.6
+ * @memberOf cast
+ *
+ * @name toObj
+ * @alias toObject
+ *
+ * @param {*} x cast to object
+ * @return {Object} Object(x) || {}
+ *
+ * {@link http://ecma-international.org/ecma-262/7.0/#sec-toobject emca-toobject}
+ * {@link https://github.com/jashkenas/underscore/blob/master/underscore.js#L637 underscore-to-object}
+ * @see {@link underscore-to-object}
+ * @see {@link emca-toobject}
+ *
+ * @example
+ *
+ * toObj(null) //=> {}
+ *
+ * @example
+ *
+ * var obj = {eh: true}
+ * var objected = toObj(obj)
+ * obj === objected //=> true
+ *
+ */
+module.exports = function toObj(x) {
+ // @NOTE this is spec, but IMO, better to return false, or empty obj
+ // if (x === null || x === undefined) {
+ // throw new TypeError('Null or undefined passed to ToObject')
+ // }
+ // if (isNil(x)) return {}
+ // else return Object(x)
+ return Object(x)
+}
diff --git a/src/deps/cast/toPairs.js b/src/deps/cast/toPairs.js
new file mode 100644
index 0000000..c64e89b
--- /dev/null
+++ b/src/deps/cast/toPairs.js
@@ -0,0 +1,66 @@
+const ENV_COMPAT = require('../env/compat')
+const hasOwnProperty = require('../util/hasOwnProperty')
+
+/**
+ * Converts an object into an array of key, value arrays. Only the object's
+ * own properties are used.
+ * Note that the order of the output array is not guaranteed to be consistent
+ * across different JS platforms.
+ *
+ * @since 5.0.0-beta.5
+ * @memberOf cast
+ *
+ * @param {Object|Array} obj The object to extract from
+ * @return {Array} An array of key, value arrays from the object's own properties.
+ *
+ * @alias objToArray
+ * @alias objectToArray
+ * @alias objToArr
+ * @alias toEntries
+ *
+ * @func
+ * @fork v0.4.0
+ * @category Object
+ * @sig {String: *} -> [[String,*]]
+ *
+ * @TODO compat env version
+ *
+ * {@link https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/entries#Polyfill mozilla-object-entries}
+ * {@link https://github.com/lodash/lodash/blob/master/fromPairs.js lodash-from-pairs}
+ * {@link https://github.com/ramda/ramda/blob/master/src/pair.js ramda-to-pairs}
+ * {@link https://github.com/jashkenas/underscore/blob/master/underscore.js#L637 underscore-to-pairs}
+ * @see {@link mozilla-object-entries}
+ * @see {@link underscore-to-pairs}
+ * @see {@link ramda-to-pairs}
+ * @see {@link lodash-from-pairs}
+ * @see fromPairs
+ * @see util/hasOwnProperty
+ * @see cast/mapToArray
+ *
+ * @example
+ *
+ * toPairs({a: 1, b: 2, c: 3})
+ * //=> [['a', 1], ['b', 2], ['c', 3]]
+ *
+ * toPairs([])
+ * //=> [['a', 1], ['b', 2], ['c', 3]]
+ *
+ */
+module.exports = Object.entries
+
+if (ENV_COMPAT) {
+ // if (!module.exports),
+ // if there is no Object.entries,
+ // but we want to force compat so
+ module.exports = (function toPairs(obj) {
+ const pairs = []
+
+ for (let prop in obj) {
+ if (hasOwnProperty(prop, obj)) {
+ pairs[pairs.length] = [prop, obj[prop]]
+ }
+ }
+
+ return pairs
+ })
+}
diff --git a/src/deps/cast/toPlainObj.js b/src/deps/cast/toPlainObj.js
new file mode 100644
index 0000000..3d33682
--- /dev/null
+++ b/src/deps/cast/toPlainObj.js
@@ -0,0 +1,48 @@
+const toObj = require('./toObj')
+
+/**
+ * Converts `value` to a plain object flattening inherited enumerable string
+ * keyed properties of `value` to own properties of the plain object.
+ * @since 5.0.0-beta.5
+ * @memberOf cast
+ *
+ * @name toPlainObj
+ * @alias toPlainObj
+ * @alias castPlainObj
+ *
+ *
+ * @param {*} value The value to convert.
+ * @return {Object} Returns the converted plain object.
+ *
+ * @fork 3.0.0
+ * @category Lang
+ *
+ * @example
+ *
+ * function Foo() {
+ * this.b = 2
+ * }
+ *
+ * Foo.prototype.c = 3
+ *
+ * assign({ 'a': 1 }, new Foo)
+ * //=> { 'a': 1, 'b': 2 }
+ *
+ * assign({ 'a': 1 }, toPlainObject(new Foo))
+ * //=> { 'a': 1, 'b': 2, 'c': 3 }
+ *
+ */
+function toPlainObject(value) {
+ value = toObj(value)
+
+ const result = {}
+
+ // eslint-disable-next-line
+ for (const key in value) {
+ result[key] = value[value]
+ }
+
+ return result
+}
+
+module.exports = toPlainObject
diff --git a/src/deps/cast/toPrimitive.js b/src/deps/cast/toPrimitive.js
new file mode 100644
index 0000000..d395ac5
--- /dev/null
+++ b/src/deps/cast/toPrimitive.js
@@ -0,0 +1,22 @@
+const isNil = require('../is/nullOrUndefined')
+
+/**
+ * @since 5.0.0-beta.9
+ * @name toPrimitive
+ * @alias toValue
+ * @alias toValueOf
+ *
+ * @param {*} x value to convert to primitive
+ * @return {Primitive}
+ *
+ * {@link https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/valueOf mozilla_valueof}
+ * @see {@link mozilla_valueof}
+ *
+ * @example
+ * toPrimitive(10) //=> 10
+ */
+const toPrimitive = function(x) {
+ return isNil(x) ? x : x.valueOf()
+}
+
+module.exports = toPrimitive
diff --git a/src/deps/cast/toRegExp.js b/src/deps/cast/toRegExp.js
new file mode 100644
index 0000000..865ef91
--- /dev/null
+++ b/src/deps/cast/toRegExp.js
@@ -0,0 +1,41 @@
+const escapeStringRegExp = require('../string/escapeRegExp')
+const isStringPrimitive = require('../is/stringPrimitive')
+const isRegExp = require('../is/regexp')
+const newRegExp = require('../construct/regexp')
+const replaceEscapedStar = require('../string/escapedToDotStar')
+// const pipe = require('../fp/pipeTwo')
+
+/**
+ * @func
+ * @name toRegExp
+ * @memberOf cast
+ * @module to-regexp
+ * @extends escapeStringRegExp
+ *
+ * @param {string} x string to escape
+ * @return {RegExp} x -> RegExp
+ *
+ * @see deps/matcher
+ * @TODO flags as 2nd param?
+ *
+ * @example
+ *
+ * toRegExp('*')
+ * => '.*'
+ *
+ * toRegExp('eh')
+ * => 'eh'
+ *
+ */
+module.exports = x => {
+ if (isStringPrimitive(x)) {
+ return newRegExp(escapeStringRegExp(replaceEscapedStar(x)))
+ }
+ else if (isRegExp(x)) {
+ return x
+ }
+ else {
+ // always false regexp
+ return newRegExp('(?:)')
+ }
+}
diff --git a/src/deps/cast/toString.js b/src/deps/cast/toString.js
new file mode 100644
index 0000000..c2c23e4
--- /dev/null
+++ b/src/deps/cast/toString.js
@@ -0,0 +1,62 @@
+const EMPTY_STRING = require('../native/EMPTY_STRING')
+const mapArray = require('../loop/map/mapArray')
+const symbolToString = require('../symbols/toString')
+const isSymbol = require('../is/symbol')
+const isNill = require('../is/nullOrUndefined')
+const isArray = require('../is/array')
+const isString = require('../is/stringPrimitive')
+const castToKey = require('./toKey')
+
+/**
+ * Converts `value` to a string. An empty string is returned for `null`
+ * and `undefined` values. The sign of `-0` is preserved.
+ * @memberOf cast
+ * @since 5.0.0-beta.6
+ *
+ * @param {*} value The value to convert.
+ * @return {string} Returns the converted string.
+ *
+ * @fork 4.0.0
+ * @category Lang
+ *
+ * @see http://people.mozilla.org/~jorendorff/es6-draft.html#sec-tostring
+ * @see https://github.com/svaarala/duktape/issues/204
+ * @see https://github.com/substack/json-stable-stringify
+ * @see https://github.com/nickyout/fast-stable-stringify
+ * @see https://hacks.mozilla.org/2012/12/performance-with-javascript-string-objects/
+ *
+ * @example
+ *
+ * toString(null)
+ * //=> ''
+ *
+ * toString(-0)
+ * //=> '-0'
+ *
+ * toString([1, 2, 3])
+ * //=> '1,2,3'
+ *
+ */
+function castToString(value) {
+ if (isNill(value)) {
+ return EMPTY_STRING
+ }
+ // Exit early for strings to avoid a performance hit in some environments.
+ else if (isString(value)) {
+ return value
+ }
+ else if (isArray(value)) {
+ // Recursively convert values (susceptible to call stack limits).
+ return `${mapArray(value, other =>
+ (isNill(other) ? other : castToString(other)))}`
+ }
+ else if (isSymbol(value)) {
+ return symbolToString.call(value)
+ }
+ // e.g. isNumber
+ else {
+ return castToKey(value)
+ }
+}
+
+module.exports = castToString
diff --git a/src/deps/cast/toTestable.js b/src/deps/cast/toTestable.js
new file mode 100644
index 0000000..3a8ccac
--- /dev/null
+++ b/src/deps/cast/toTestable.js
@@ -0,0 +1,85 @@
+const stringPrimitive = require('../is/stringPrimitive')
+const isFunction = require('../is/function')
+const isFalsy = require('../is/falsy')
+const isNil = require('../is/nullOrUndefined')
+const hasIn = require('../is/hasIn')
+const toRegExp = require('../cast/toRegExp')
+const always = require('../fp/always')
+
+const testableFactory = matcher => x => matcher.test(x)
+
+/**
+ * @desc like matcher, but .isMatch
+ * @since 3.0.0
+ * @version 5.0.0 <- big change, changed to toTestable, and split `test.js`
+ * @memberOf cast
+ * @memberOf matcher
+ *
+ * @param {Matchable} matchable any matchable
+ * @return {boolean} is a match, passes the test
+ *
+ * @NOTE as else-if for easier ternary uglification
+ *
+ * @ param {any} [arg1=undefined] arg to match with
+ * @ param {any} [arg2=undefined] optional second arg to pass into tester
+ *
+ * @example
+ *
+ * matcher('kinga')('kinga')
+ * //=> true
+ * matcher('k*nga')('kinga')
+ * //=> true
+ * matcher('kinga')('nope')
+ * //=> false
+ *
+ * matcher(new RegExp(/kinga/))('kinga')
+ * //=> true
+ * matcher(new RegExp(/kinga/))('nope')
+ * //=> false
+ *
+ * matcher(x => x === 'kinga')('kinga')
+ * //=> true
+ * matcher(x => x === 'kinga')('nope')
+ * //=> false
+ *
+ * matcher({test: x => x === 'kinga'})('kinga')
+ * //=> true
+ * matcher({test: x => x === 'kinga'})('nope')
+ * //=> false
+ *
+ */
+function _toTestable(matchable) {
+ if (stringPrimitive(matchable)) {
+ return toRegExp(matchable)
+ }
+ else if (isFalsy(matchable)) {
+ return {test: always(false)}
+ }
+ else if (hasIn(matchable, 'test')) {
+ return matchable
+ }
+ else if (isFunction(matchable)) {
+ // could be arity, this keeps it still callable
+ // const matchableFn = $0 => matchable($0)
+ // matchableFn.test = matchableFn
+
+ return {test: matchable}
+ }
+ else {
+ return {test: always(false)}
+ }
+}
+
+// better for always returning the same, the following is just compat
+// function toTestable(matchable, arg) {
+// return testableFactory(_toTestable(matchable))
+// }
+
+function toTestable(matchable, arg, arg2) {
+ const testable = _toTestable(matchable)
+ if (!isNil(arg2)) return testable.test(arg, arg2)
+ if (!isNil(arg)) return testable.test(arg)
+ else return testableFactory(testable)
+}
+
+module.exports = toTestable
diff --git a/src/deps/cast/toUint31.js b/src/deps/cast/toUint31.js
new file mode 100644
index 0000000..c3d7e8a
--- /dev/null
+++ b/src/deps/cast/toUint31.js
@@ -0,0 +1,27 @@
+/**
+ * v8 has an optimization for storing 31-bit signed numbers.
+ * Values which have either 00 or 11 as the high order bits qualify.
+ * This function drops the highest order bit in a signed number, maintaining
+ * the sign bit.
+ *
+ * @since 5.0.0-beta.6
+ * @version 2.0.0 <- accidentally had as signed, fixed to uint
+ * @memberOf cast
+ *
+ * @name toUint31
+ * @alias castToSigned31BitUinteger
+ * @alias castTo31
+ * @alias castToUint31
+ * @alias toSignedUint31
+ * @alias smi
+ *
+ * @param {number} i32 32bit integer
+ * @return {number} unsigned31Integer number
+ *
+ * {@link https://github.com/facebook/immutable-js/blob/master/src/Math.js#L22 immutablejs-tounsigned31}
+ * @see {@link immutablejs-tounsigned31}
+ */
+module.exports = function toUnsigned31(i32) {
+ // eslint-disable-next-line
+ return i32 >>> 1 & 0x40000000 | i32 & 0xbfffffff;
+}
diff --git a/src/deps/cast/toUint32.js b/src/deps/cast/toUint32.js
new file mode 100644
index 0000000..b2e1e80
--- /dev/null
+++ b/src/deps/cast/toUint32.js
@@ -0,0 +1,39 @@
+/**
+ * N >>> 0 is shorthand for ToUint32
+ *
+ * @since 5.0.0-beta.6
+ * @version 2.0.0 <- accidentally had as signed, fixed to uint
+ * @memberOf cast
+ *
+ * @param {number | string} i32 32bit number
+ * @return {number} unsigned 32bit number
+ *
+ * @name toUint32
+ * @alias castToUnsigned32BitInteger
+ * @alias castToUnsigned32
+ * @alias castToUnsignedInt32
+ * @alias toUnsigned32
+ * @alias toUnsigned32Bit
+ *
+ * @see cast/toUint31
+ *
+ * {@link https://github.com/facebook/immutable-js/blob/master/src/Math.js#L22 immutable-js-siml}
+ * {@link https://github.com/facebook/immutable-js/blob/master/src/TrieUtils.js#L58 immutable-js-trie-uint32}
+ * {@link https://stackoverflow.com/questions/1908492/unsigned-integer-in-javascript stack-overflow-unsigned-integer}
+ * {@link https://tc39.github.io/ecma262/#sec-touint32 emca-touint32}
+ * @see {@link emca-tounit32}
+ * @see {@link stack-overflow-unsigned-integer}
+ * @see {@link immutable-js-trie-uint32}
+ * @see {@link immutable-js-siml}
+ *
+ * @example
+ *
+ * toUint32(-Math.pow(2,32)) //=> 0
+ * toUint32(-Math.pow(2,32)-1) //=> 4294967295
+ * toUint32(-1) //=> 4294967295
+ *
+ */
+module.exports = function toUnsigned32(i32) {
+ // eslint-disable-next-line
+ return i32 >>> 0
+}
diff --git a/src/deps/cast/unicodeToArray.js b/src/deps/cast/unicodeToArray.js
new file mode 100644
index 0000000..2d7692e
--- /dev/null
+++ b/src/deps/cast/unicodeToArray.js
@@ -0,0 +1,45 @@
+// -----
+
+/** Used to compose unicode character classes. */
+const rsAstralRange = '\\ud800-\\udfff'
+const rsComboMarksRange = '\\u0300-\\u036f'
+const reComboHalfMarksRange = '\\ufe20-\\ufe2f'
+const rsComboSymbolsRange = '\\u20d0-\\u20ff'
+const rsVarRange = '\\ufe0e\\ufe0f'
+const rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange
+
+/** Used to compose unicode capture groups. */
+const rsAstral = `[${rsAstralRange}]`
+const rsCombo = `[${rsComboRange}]`
+const rsFitz = '\\ud83c[\\udffb-\\udfff]'
+const rsModifier = `(?:${rsCombo}|${rsFitz})`
+const rsNonAstral = `[^${rsAstralRange}]`
+const rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}'
+const rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]'
+const rsZWJ = '\\u200d'
+
+/** Used to compose unicode regexes. */
+const reOptMod = `${rsModifier}?`
+const rsOptVar = `[${rsVarRange}]?`
+const rsOptJoin = `(?:${rsZWJ}(?:${[rsNonAstral, rsRegional, rsSurrPair].join('|')})${rsOptVar + reOptMod})*`
+const rsSeq = rsOptVar + reOptMod + rsOptJoin
+const rsNonAstralCombo = `${rsNonAstral}${rsCombo}?`
+const rsSymbol = `(?:${[rsNonAstralCombo, rsCombo, rsRegional, rsSurrPair, rsAstral].join('|')})`
+
+/** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */
+const reUnicode = RegExp(`${rsFitz}(?=${rsFitz})|${rsSymbol + rsSeq}`, 'g')
+
+/**
+ * Converts a Unicode `string` to an array.
+ * @since 5.0.0-beta.5
+ * @memberOf cast
+ *
+ * @param {string} string The string to convert.
+ * @return {Array} Returns the converted array.
+ *
+ * @TODO @example
+ *
+ */
+module.exports = function unicodeToArray(string) {
+ return string.match(reUnicode) || []
+}
diff --git a/src/deps/concat.js b/src/deps/concat.js
deleted file mode 100644
index b974bd4..0000000
--- a/src/deps/concat.js
+++ /dev/null
@@ -1,3 +0,0 @@
-const toarr = require('./to-arr')
-
-module.exports = (one, two) => toarr(one || []).concat(toarr(two))
diff --git a/src/deps/conditional/README.md b/src/deps/conditional/README.md
index 50a957b..f41fd65 100644
--- a/src/deps/conditional/README.md
+++ b/src/deps/conditional/README.md
@@ -2,6 +2,7 @@ things like some utils like `not` and such can go in here
maybe also have `lib` for lodash style things?
+@TODO `none`
// @NOTE: there is no need for enum, just `|`, could use `==`
// this way we could also just do ==
diff --git a/src/deps/conditional/all.js b/src/deps/conditional/all.js
index 411cad1..18a7314 100644
--- a/src/deps/conditional/all.js
+++ b/src/deps/conditional/all.js
@@ -1,10 +1,31 @@
+const curry = require('../fp/curry')
+
/**
* map all values in an array to see if all match
+ * Returns `true` if all elements of the list match the predicate, `false` if there are any that don't.
+ *
+ * @alias every
+ * @name all
* @memberOf conditional
- * @since 4.0.1
+ * @since 4.0.1
+ *
+ * @TODO `not(some)` ?
+ *
+ * @curried
* @param {Function} predicate match the value
+ * @param {Array} list to match against predicate
* @return {boolean} all match predicate
*
+ * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/every mozilla-every}
+ * {@link https://github.com/jashkenas/underscore/blob/master/underscore.js#L262 underscore-all}
+ * {@link https://github.com/ramda/ramda/blob/master/src/all.js ramda-all}
+ * @see {@link ramda-all}
+ * @see {@link underscore-all}
+ * @see {@link mozilla-every}
+ * @see fp/curry
+ *
+ * @sig (a -> Boolean) -> [a] -> Boolean
+ *
* @example
*
* const allBoolean = all(x => typeof x === 'boolean'q)
@@ -16,11 +37,11 @@
* //=> false
*
*/
-const all = predicate => arr => {
- for (let i in arr) {
- if (!predicate(arr[i])) return false
+const all = curry(2, (predicate, list) => {
+ for (let i in list) {
+ if (!predicate(list[i])) return false
}
return true
-}
+})
module.exports = all
diff --git a/src/deps/conditional/and.js b/src/deps/conditional/and.js
index 57b89df..063674d 100644
--- a/src/deps/conditional/and.js
+++ b/src/deps/conditional/and.js
@@ -1,10 +1,18 @@
+const curry = require('../fp/curry')
+
/**
- * first fn & second fn
+ * @desc first fn & second fn
* @memberOf conditional
* @since 4.0.1
+ *
* @param {Function} left first fn
* @param {Function} right second fn
- * @return {boolean} both functions return truthy
+ * @return {Function | boolean} both functions return truthy @curried
+ *
+ * @curried
+ * @name and
+ * @alias both
+ * @func
*
* @example
*
@@ -20,4 +28,5 @@
* //=> false
*
*/
-module.exports = (left, right) => x => left(x) && right(x)
+const and = (left, right) => x => left(x) && right(x)
+module.exports = curry(2, and)
diff --git a/src/deps/conditional/eq.js b/src/deps/conditional/eq.js
index 3f762fd..adda8b9 100644
--- a/src/deps/conditional/eq.js
+++ b/src/deps/conditional/eq.js
@@ -1 +1,5 @@
-module.exports = left => right => left === right
+const curry = require('../fp/curry')
+
+module.exports = curry(2, function eqeqeq(left, right) {
+ return left === right
+})
diff --git a/src/deps/conditional/includes/all.js b/src/deps/conditional/includes/all.js
index 7ad10d3..bc23554 100644
--- a/src/deps/conditional/includes/all.js
+++ b/src/deps/conditional/includes/all.js
@@ -1,44 +1,78 @@
-const isArray = require('../../is/array')
-const includes = require('./includes')
+const isStringPrimitive = require('../../is/stringPrimitive')
+const curry = require('../../fp/curry')
+const includes = require('./haystackNeedle')
/**
- * @param {string} needle
- * @param {Array} haystack
+ * @desc tripple equals, or every haystack item, is needle
+ * @since 0.1.0
+ * @version 1.0.0
+ *
+ * @param {string} needle includes(haystack[index], needle)
+ * @param {Array} haystack includes(haystack[index], needle)
* @return {boolean}
+ *
+ * @example
+ *
+ * stringIncludesAll('eh', ['e', 'h']) //=> true
+ * stringIncludesAll('eh', ['e']) //=> false
+ *
*/
-function strHasAll(needle, haystack) {
- if (needle === haystack) {
- return true
- }
+function stringIncludesAll(needle, haystack) {
+ if (needle === haystack) return true
+
for (let i = 0, len = haystack.length; i < len; i++)
if (!includes(haystack[i], needle)) return false
+
return true
}
/**
- * @see strHasAll
- * @param {Array} needles
- * @param {Array} haystack
+ * @desc every needle is in every hay
+ * @since 0.1.0
+ * @version 1.0.0
+ *
+ * @see stringIncludesAll
+ * @extends stringIncludesAll
+ *
+ * @param {Array} needles includes(haystack[index], needle)
+ * @param {Array} haystack includes(haystack[index], needle)
* @return {boolean}
+ *
+ * @example
+ *
+ * arrayIncludesAll(['eh'], 'eh')
+ *
*/
-function arrayHasAll(needles, haystack) {
+function arrayIncludesAll(needles, haystack) {
// loop needles
- for (let i = 0; i < needles.length; i++) {
- if (!strHasAll(needles[i], haystack)) return false
- }
+ for (let i = 0; i < needles.length; i++)
+ if (!stringIncludesAll(needles[i], haystack)) return false
+
return true
}
/**
- * @see arrayHasAll
- * @see strHasAll
- * @param {Array | string} needle
- * @param {Array} haystack
+ * @desc every needle is in every hay
+ * @since 4.0.0
+ * @param {Array | string} needle everything in haystack is in this
+ * @param {Array} haystack everything in this is in the needle
* @return {boolean}
+ *
+ * @see arrayIncludesAll
+ * @see stringIncludesAll
+ *
+ * @example
+ *
+ * /// 'canada' and 'can' are both in it, so true
+ * includesAll('canada', ['canada', 'can'])
+ * includesAll(['eh'], 'e') //=> true
+ * includesAll(['eh'], 'nope') //=> false
+ * includesAll('eh', ['no', 'eh']) //=> false
+ *
*/
function includesAll(needle, haystack) {
- if (isArray(needle)) return arrayHasAll(needle, haystack)
- else return strHasAll(needle, haystack)
+ if (isStringPrimitive(needle)) return stringIncludesAll(needle, haystack)
+ else return arrayIncludesAll(needle, haystack)
}
-module.exports = includesAll
+module.exports = curry(2, includesAll)
diff --git a/src/deps/conditional/includes/any.js b/src/deps/conditional/includes/any.js
index 517cb36..fd6d33a 100644
--- a/src/deps/conditional/includes/any.js
+++ b/src/deps/conditional/includes/any.js
@@ -1,52 +1,87 @@
-const isArray = require('../../is/array')
-const includes = require('./includes')
+const isStringPrimitive = require('../../is/stringPrimitive')
+const curry = require('../../fp/curry')
+const haystackNeedle = require('./haystackNeedle')
/**
- * @param {string} needle
- * @param {Array} haystack
+ * @desc needle includes haystack, haystack includes needle
+ * @version 4.0.0
+ * @memberOf includes
+ *
+ * @param {string} needle serves dualy as haystack
+ * @param {Array} haystack serves dualy as needle
* @return {boolean}
+ *
+ * @example
+ *
+ * strHas('eh', 'eh') //=> true
+ * strHas('eh', 'e') //=> true
+ * strHas('eh', 'nope') //=> false
+ *
*/
function strHasAny(needle, haystack) {
- if (needle.includes(haystack)) {
- return true
- }
- for (let i = 0, len = haystack.length; i < len; i++) {
- if (haystack[i].includes(needle)) {
- return true
- }
- }
+ if (haystackNeedle(needle, haystack)) return true
+
+ for (let i = 0, len = haystack.length; i < len; i++)
+ if (haystackNeedle(haystack[i], needle)) return true
+
return false
}
/**
- * @see strHasAny
- * @param {Array} needles
- * @param {Array} haystack
+ * @memberOf includes
+ * @version 1.0.0
+ * @since 0.1.0
+ *
+ * @param {Array} needles also serves as haystack
+ * @param {Array} haystack also serves as needle
* @return {boolean}
+ *
+ * @extends strHasAny
+ * @see includes/any#strHasAny
+ *
+ * @example
+ *
+ * arrayHasAny(['eh'], ['eh']) //=> true
+ * arrayHasAny('eh', ['e']) //=> true
+ * arrayHasAny(['eh'], 'e') //=> true
+ * arrayHasAny(['eh'], 'eh') //=> true
+ *
*/
function arrayHasAny(needles, haystack) {
- if (needles.includes(haystack)) {
- return true
- }
+ if (haystackNeedle(needles, haystack)) return true
+
// loop needles
- for (let i = 0; i < needles.length; i++) {
- if (strHasAny(needles[i], haystack)) {
- return true
- }
- }
+ for (let i = 0; i < needles.length; i++)
+ if (strHasAny(needles[i], haystack)) return true
+
return false
}
/**
+ * @desc any haystack includes any needle
+ * @since 0.1.0
+ * @version 1.0.0
+ * @memberOf includes
+ *
+ * @param {Array | string} needle also serves as haystack
+ * @param {Array} haystack also serves as needle
+ * @return {boolean}
+ *
* @see arrayHasAny
* @see strHasAny
- * @param {Array | string} needle
- * @param {Array} haystack
- * @return {boolean}
+ * @see isStringPrimitive
+ *
+ * @example
+ *
+ * includesAny('eh', 'e') //=> true
+ * includesAny('eh', 'eh') //=> true
+ * includesAny(['eh'], 'e') //=> true
+ * includesAny(['eh'], 'nope') //=> false
+ *
*/
function includesAny(needle, haystack) {
- if (isArray(needle)) return arrayHasAny(needle, haystack)
- else return strHasAny(needle, haystack)
+ if (isStringPrimitive(needle)) return strHasAny(needle, haystack)
+ else return arrayHasAny(needle, haystack)
}
-module.exports = includesAny
+module.exports = curry(2, includesAny)
diff --git a/src/deps/conditional/includes/haystackNeedle.js b/src/deps/conditional/includes/haystackNeedle.js
new file mode 100644
index 0000000..9ad5d89
--- /dev/null
+++ b/src/deps/conditional/includes/haystackNeedle.js
@@ -0,0 +1,33 @@
+const curry = require('../../fp/curry')
+
+/**
+ * @desc haystack includes needle
+ * @memberOf includes
+ * @version 1.0.0
+ * @since 4.0.0
+ *
+ * @param {Array | string} haystack haystack includes needle
+ * @param {string | *} needle needle in haystack
+ * @return {boolean} needle in haystack
+ *
+ * @name includes
+ * @alias haystackNeedle
+ * @func
+ *
+ * @TODO `~haystack.indexOf(needle)`
+ *
+ * {@link https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#Bitwise_NOT mozilla-bitwise-not}
+ * @see {@link mozilla-bitwise-not}
+ * @see conditional/includes/flipped
+ *
+ * @example
+ *
+ * includes('eh', 'e') //=> true
+ * includes('eh', 'nope') //=> false
+ * includes(['eh'], 'eh') //=> true
+ * includes(['eh'], 'nope') //=> false
+ *
+ */
+const includes = (haystack, needle) => haystack.includes(needle)
+
+module.exports = curry(2, includes)
diff --git a/src/deps/conditional/includes/includes.js b/src/deps/conditional/includes/includes.js
index e458c40..e9e6408 100644
--- a/src/deps/conditional/includes/includes.js
+++ b/src/deps/conditional/includes/includes.js
@@ -1 +1,19 @@
-module.exports = (haystack, needle) => haystack.includes(needle)
+const haystackNeedle = require('./haystackNeedle')
+const needleHaystack = require('./needleHaystack')
+const includesAll = require('./all')
+const includesAny = require('./any')
+
+/**
+ * @member includes
+ * {@link https://github.com/jashkenas/underscore/blob/master/underscore.js#L288 underscore-includes}
+ * @see {@link underscore-includes}
+ */
+module.exports = {
+ // traditional
+ includes: haystackNeedle,
+ // rest
+ haystackNeedle,
+ needleHaystack,
+ includesAll,
+ includesAny,
+}
diff --git a/src/deps/conditional/includes/index.js b/src/deps/conditional/includes/index.js
index 05b85d6..0b863d1 100644
--- a/src/deps/conditional/includes/index.js
+++ b/src/deps/conditional/includes/index.js
@@ -1 +1 @@
-module.exports = require('./includes')
+module.exports = require('./needleHaystack')
diff --git a/src/deps/conditional/includes/needleHaystack.js b/src/deps/conditional/includes/needleHaystack.js
new file mode 100644
index 0000000..18797ee
--- /dev/null
+++ b/src/deps/conditional/includes/needleHaystack.js
@@ -0,0 +1,4 @@
+const flip2 = require('../../fp/flip2')
+const haystackNeedle = require('./haystackNeedle')
+
+module.exports = flip2(haystackNeedle)
diff --git a/src/deps/conditional/index.js b/src/deps/conditional/index.js
new file mode 100644
index 0000000..f119901
--- /dev/null
+++ b/src/deps/conditional/index.js
@@ -0,0 +1,16 @@
+/* istanbul ignore next: @docblocks @exports */
+
+const all = require('./all')
+const and = require('./and')
+const some = require('./some')
+const not = require('./not')
+const or = require('./or')
+const eq = require('./eq')
+
+/**
+ * @member conditional
+ * @type {Object}
+ */
+const conditional = {all, and, some, not, or, eq}
+
+module.exports = conditional
diff --git a/src/deps/conditional/negate.js b/src/deps/conditional/negate.js
new file mode 100644
index 0000000..e365178
--- /dev/null
+++ b/src/deps/conditional/negate.js
@@ -0,0 +1,19 @@
+/**
+ * @name negate
+ * @memberOf conditional
+ * @since 5.0.0-beta.6
+ * @see conditional/not
+ * @param {Function} predicate call this
+ * @return {Function} call this to call predicate with arguments
+ *
+ * @example
+ * const T = x => true
+ * const F = negate(t)
+ * F(true) //=> false
+ * F(false) //=> true
+ */
+module.exports = function negate(predicate) {
+ return function() {
+ return !predicate.apply(this, arguments)
+ }
+}
diff --git a/src/deps/conditional/not.js b/src/deps/conditional/not.js
index be3b1cb..f609e09 100644
--- a/src/deps/conditional/not.js
+++ b/src/deps/conditional/not.js
@@ -1,9 +1,32 @@
+const curry = require('../fp/curry')
+
/**
* return a negated function
+ * A function wrapping a call to the given function in a `!` operation.
+ * It will:
+ * - return `true` when the underlying function would return a false-y value,
+ * - and `false` when it would return a truth-y one.
+ * @since 4.0.1
+ *
+ * {@link https://github.com/facebook/immutable-js/blob/master/src/CollectionImpl.js#L771 immutable-js-not}
+ * {@link https://github.com/ramda/ramda/blob/master/src/not.js ramda-not}
+ * {@link https://github.com/lodash/lodash/blob/master/negate.js lodash-negate}
+ * {@link http://documentcloud.github.io/underscore-contrib/#not-1 underscore-not}
+ * {@link https://github.com/jashkenas/underscore/blob/master/underscore.js#L916 underscore-negate}
+ * @see {@link underscore-negate}
+ * @see {@link underscore-not}
+ * @see {@link lodash-negate}
+ * @see {@link ramda-not}
+ * @see {@link immutable-js-not}
+ *
+ * @alias negate
+ * @name not
* @memberOf conditional
- * @since 4.0.1
+ * @func
+ *
* @param {Function} fn any function
- * @return {Function} !Function
+ * @param {*} x value to pass to function
+ * @return {Function} !Function(x)
*
* @example
*
@@ -17,4 +40,5 @@
* //=> false
*
*/
-module.exports = fn => x => !fn(x)
+const not = (fn, x) => !fn(x)
+module.exports = curry(2, not)
diff --git a/src/deps/conditional/or.js b/src/deps/conditional/or.js
index 3964fb4..26da37e 100644
--- a/src/deps/conditional/or.js
+++ b/src/deps/conditional/or.js
@@ -1,14 +1,24 @@
+const curry = require('../fp/curry')
+
/**
- * first fn || second fn
+ * @desc first fn || second fn, curried
* @memberOf conditional
* @since 4.0.1
+ *
* @param {Function} left first fn
* @param {Function} right second fn
- * @return {boolean} one of the functions return truthy
+ * @param {*} x value to pass into left & right, @curried
+ * @return {boolean} one of the functions return truthy @curried
+ *
+ * @name or
+ * @func
+ * @TODO either
*
* @example
*
- * const either = or(x => x === false, x => x === true)
+ * const {isTrue, isFalse} = require('chain-able')
+ *
+ * const either = or(isFalse, isTrue)
*
* either([true])
* //=> true
@@ -19,5 +29,8 @@
* either([1])
* //=> false
*
+ * // because curried
+ * or(isTrue, isFalse, true) //=> true
+ *
*/
-module.exports = (left, right) => x => left(x) || right(x)
+module.exports = curry(3, (left, right, x) => left(x) || right(x))
diff --git a/src/deps/conditional/some.js b/src/deps/conditional/some.js
index 17182a2..9abaa48 100644
--- a/src/deps/conditional/some.js
+++ b/src/deps/conditional/some.js
@@ -1,10 +1,22 @@
+const curry = require('../fp/curry')
+
/**
- * map all values in an array to see if **some** match
+ * @desc map all values in an array to see if **some** match, curried
* @memberOf conditional
- *
* @since 4.0.1
+ *
* @param {Function} predicate match the value
- * @return {boolean} all match predicate
+ * @param {Array | any} list values to match on the predicate
+ * @return {boolean} **some** match predicate
+ *
+ * @name some
+ * @alias any
+ * @func
+ *
+ * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some mozilla-some}
+ * {@link https://github.com/jashkenas/underscore/blob/master/underscore.js#L273 underscore-some}
+ * @see {@link underscore-some}
+ * @see {@link mozilla-some}
*
* @example
*
@@ -20,11 +32,9 @@
* //=> true
*
*/
-const some = test => arr => {
- for (let i in arr) {
- if (test(arr[i])) return true
+module.exports = curry(2, function some(test, list) {
+ for (let i in list) {
+ if (test(list[i])) return true
}
return false
-}
-
-module.exports = some
+})
diff --git a/src/deps/construct/date.js b/src/deps/construct/date.js
new file mode 100644
index 0000000..c692a43
--- /dev/null
+++ b/src/deps/construct/date.js
@@ -0,0 +1,4 @@
+const construct = require('../fp/construct')
+
+// @NOTE this is the worst one to construct because it has so many optional args
+module.exports = construct(0, Date)
diff --git a/src/deps/construct/index.js b/src/deps/construct/index.js
new file mode 100644
index 0000000..3d12d44
--- /dev/null
+++ b/src/deps/construct/index.js
@@ -0,0 +1,16 @@
+/* istanbul ignore next */
+
+const constructMap = require('./map')
+const constructSet = require('./set')
+const constructRegExp = require('./regexp')
+
+/**
+ * @member construct
+ * @type {Object}
+ * @TODO map to `newX` ?
+ */
+module.exports = {
+ constructMap,
+ constructSet,
+ constructRegExp,
+}
diff --git a/src/deps/construct/map.js b/src/deps/construct/map.js
new file mode 100644
index 0000000..41f7e87
--- /dev/null
+++ b/src/deps/construct/map.js
@@ -0,0 +1,3 @@
+const construct = require('../fp/construct')
+
+module.exports = construct(0, Map)
diff --git a/src/deps/construct/regexp.js b/src/deps/construct/regexp.js
new file mode 100644
index 0000000..f769948
--- /dev/null
+++ b/src/deps/construct/regexp.js
@@ -0,0 +1,3 @@
+const construct = require('../fp/construct')
+
+module.exports = construct(0, RegExp)
diff --git a/src/deps/construct/set.js b/src/deps/construct/set.js
new file mode 100644
index 0000000..8a5b83c
--- /dev/null
+++ b/src/deps/construct/set.js
@@ -0,0 +1,3 @@
+const construct = require('../fp/construct')
+
+module.exports = construct(0, Set)
diff --git a/src/deps/dopemerge/dopemerge.js b/src/deps/dopemerge/dopemerge.js
index 7c888e1..3617c18 100644
--- a/src/deps/dopemerge/dopemerge.js
+++ b/src/deps/dopemerge/dopemerge.js
@@ -10,7 +10,7 @@ const isDate = require('../is/date')
const isBoolean = require('../is/boolean')
const isString = require('../is/string')
const simpleKindOf = require('../util/simpleKindOf')
-const includes = require('../conditional/includes')
+const includes = require('../conditional/includes/haystackNeedle')
const emptyTarget = require('./emptyTarget')
/**
@@ -30,7 +30,7 @@ const emptyTarget = require('./emptyTarget')
* //=> true
*
* isMergeableObj(Object.create(null))
- * // => true
+ * //=> true
*
* isMergeableObj(new Date())
* //=> false
@@ -112,6 +112,7 @@ function defaultArrayMerge(target, source, optsArg) {
for (var i = 0; i < source.length; i++) {
var v = source[i]
+
if (isUndefined(destination[i])) {
destination[i] = cloneIfNeeded(v, optsArg)
}
@@ -125,6 +126,7 @@ function defaultArrayMerge(target, source, optsArg) {
destination.push(cloneIfNeeded(v, optsArg))
}
}
+
return destination
}
@@ -136,6 +138,7 @@ function mergeObj(target, source, optsArg) {
destination[targetKeys[k]] = cloneIfNeeded(target[targetKeys[k]], optsArg)
}
}
+
var sourceKeys = ObjectKeys(source)
for (var s = 0; s < sourceKeys.length; s++) {
var key = sourceKeys[s]
@@ -182,6 +185,9 @@ function deepmerge(target, source, optsArg) {
* @param {*} opts dopemerge options
* @return {Object | Array | any} merged
*
+ * {@link https://github.com/facebook/immutable-js/blob/master/src/Map.js#L145 immutable-js-merge}
+ * {@link https://github.com/ramda/ramda/blob/master/src/merge.js ramda-merge}
+ * {@link https://github.com/lodash/lodash/blob/master/merge.js lodash-merge}
* {@link https://github.com/KyleAMathews/deepmerge deepmerge}
* @see {@link deepmerge}
*
@@ -248,7 +254,8 @@ function dopemerge(obj1, obj2, opts) {
ignoreTypes: ['null', 'undefined'],
// debug: true,
},
- opts || {}
+ opts
+ // || {}
)
const {ignoreTypes, stringToArray, boolToArray, clone} = options
@@ -258,6 +265,7 @@ function dopemerge(obj1, obj2, opts) {
// const boolToArray = false
// const clone = true
+ // @NOTE uglifier optimizes into a wicked ternary
// check one then check the other
if (isTrue(includes(ignoreTypes, simpleKindOf(obj1)))) {
return obj2
@@ -266,7 +274,6 @@ function dopemerge(obj1, obj2, opts) {
return obj1
}
else if (isBoolean(obj1) && isBoolean(obj2)) {
- // @NOTE uglifier optimizes into a wicked ternary
return boolToArray ? [obj1, obj2] : obj2
}
else if (isString(obj1) && isString(obj2)) {
diff --git a/src/deps/dopemerge/emptyTarget.js b/src/deps/dopemerge/emptyTarget.js
index d3cb695..b74f4cf 100644
--- a/src/deps/dopemerge/emptyTarget.js
+++ b/src/deps/dopemerge/emptyTarget.js
@@ -3,7 +3,9 @@ const isArray = require('../is/array')
/**
* @desc make a new empty Array or Object for cloning
* @memberOf dopemerge
+ * @name emptyTarget
* @since 2.0.0
+ * @func
*
* @param {*} val array or object to return an empty one of
* @return {Object | Array} depending on the data type of val
@@ -15,6 +17,7 @@ const isArray = require('../is/array')
*
* emptyTarget([1])
* //=> []
+ *
*/
module.exports = function emptyTarget(val) {
return isArray(val) ? [] : {}
diff --git a/src/deps/dopemerge/map.js b/src/deps/dopemerge/map.js
index e982d63..a7267ab 100644
--- a/src/deps/dopemerge/map.js
+++ b/src/deps/dopemerge/map.js
@@ -1,10 +1,36 @@
+/* istanbul ignore next: WIP */
+
const ObjectKeys = require('../util/keys')
const isMap = require('../is/map')
const isFalse = require('../is/false')
const reduce = require('../reduce')
const dopemerge = require('./dopemerge')
-function dopemergeMap(obj1, obj2) {
+/**
+ * merge maps & sets
+ * @memberOf dopemerge
+ *
+ * @param {Map | Set} obj1 merge with 2
+ * @param {Map | Set} obj2 merge with 1
+ * @return {Map | Set} merged
+ *
+ * @TODO easy clone
+ *
+ * @example
+ *
+ * var targetMap = new Map()
+ * targetMap.set('true', false)
+ * targetMap.set('obj', {obj: []})
+ * targetMap.set('arr', [1])
+ * var srcMap = new Map()
+ * srcMap.set('true', true)
+ * srcMap.set('obj', {obj: [Symbol]})
+ * srcMap.set('arr', [2])
+ * srcMap.set('emptyArr', [])
+ * var mergedMap = dopemergeMap(targetMap, srcMap, {clone: true})
+ *
+ */
+module.exports = function dopemergeMap(obj1, obj2) {
const oneIsMap = isMap(obj1)
const twoIsMap = isMap(obj2)
@@ -45,15 +71,3 @@ function dopemergeMap(obj1, obj2) {
return dest
}
-
-// test
-var targetMap = new Map()
-targetMap.set('true', false)
-targetMap.set('obj', {obj: []})
-targetMap.set('arr', [1])
-var srcMap = new Map()
-srcMap.set('true', true)
-srcMap.set('obj', {obj: [Symbol]})
-srcMap.set('arr', [2])
-srcMap.set('emptyArr', [])
-var mergedMap = dopemergeMap(targetMap, srcMap, {clone: true})
diff --git a/src/deps/dot/README.md b/src/deps/dot/README.md
index e841496..5240c24 100644
--- a/src/deps/dot/README.md
+++ b/src/deps/dot/README.md
@@ -3,6 +3,16 @@
- https://github.com/mariocasciaro/object-path/blob/master/index.js
- https://github.com/sindresorhus/dot-prop/blob/master/index.js
- https://github.com/sindresorhus/is-obj/blob/master/index.js
+- https://github.com/facebook/fbjs/blob/master/packages/fbjs/src/misc/getByPath.js
+- http://pothibo.com/2013/7/memoizations-accessories-private-variable-in-javascript
+- https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Property_accessors
+- https://gist.github.com/keeto/273490
+- http://knockoutjs.com/documentation/custom-bindings.html
+- http://javascriptplayground.com/blog/2013/12/es5-getters-setters/
+- http://batmanjs.org/docs/accessors.html
+- http://ejohn.org/blog/javascript-getters-and-setters/
+- https://github.com/tvcutsem/harmony-reflect
+https://github.com/timjansen/minified.js/blob/master/src/minified-generated-full-src.js#L503
# segments:
```js
diff --git a/src/deps/dot/delete.js b/src/deps/dot/delete.js
index aab49cf..1378d7d 100644
--- a/src/deps/dot/delete.js
+++ b/src/deps/dot/delete.js
@@ -3,6 +3,29 @@ const lengthMinusOne = require('../util/lengthMinusOne')
const getPathSegments = require('./segments')
const isDottable = require('./dottable')
+/**
+ * @desc delete a path on an object
+ * @name dot.delete
+ * @alias dotRemove
+ * @alias removePath
+ *
+ * @memberOf dot
+ * @func
+ * @since 3.0.0
+ * @extends dot/getPathSegments
+ *
+ * @param {Object} obj the object to DELETE the nested property from.
+ * @param {Dottable | string | Array} path dot-prop-path to use
+ * @return {void}
+ *
+ *
+ * @example
+ *
+ * dot.get({a: {b: 2}}, 'a.b'); //=> 2
+ * dot.get({a: {b: 2}}, ['a', 'b']); //=> 2
+ * dot.get({c: {b: 2}}, ['a', 'b']); //=> undefined
+ *
+ */
module.exports = function dotdelete(obj, path) {
if (!isDottable(obj, path)) {
return
diff --git a/src/deps/dot/dot-prop.js b/src/deps/dot/dot-prop.js
index 8a91bf0..ecc8dbc 100644
--- a/src/deps/dot/dot-prop.js
+++ b/src/deps/dot/dot-prop.js
@@ -1,3 +1,7 @@
+// const escape = require('./escape')
+// const dottable = require('./dottable')
+// const segments = require('./segments')
+// const paths = require('. paths')
const dotHas = require('./has')
const dotGet = require('./get')
const dotDelete = require('./delete')
diff --git a/src/deps/dot/escape.js b/src/deps/dot/escape.js
index 13784ca..1cf1b22 100644
--- a/src/deps/dot/escape.js
+++ b/src/deps/dot/escape.js
@@ -1 +1,8 @@
-module.exports = x => x.replace(/[.]/gim, '')
+const replace = require('../fp/replace')
+
+/**
+ * @memberOf dot
+ * @name escapeDot
+ * @extends fp/replace
+ */
+module.exports = replace(/[.]/gim, '')
diff --git a/src/deps/dot/get.js b/src/deps/dot/get.js
index e0a9dc7..7e3d75f 100644
--- a/src/deps/dot/get.js
+++ b/src/deps/dot/get.js
@@ -5,28 +5,62 @@ const lengthMinusOne = require('../util/lengthMinusOne')
const getPathSegments = require('./segments')
const isDottable = require('./dottable')
-module.exports = function(obj, path, value) {
+/**
+ * @desc dot-prop get at path
+ * @namespace dot
+ * @memberOf dot
+ * @since 3.0.0
+ *
+ * @alias dotGet
+ * @alias get
+ *
+ * @param {Object} obj the object to retrieve the nested property from.
+ * @param {Dottable | string | Array} path dot-prop-path to use
+ * @param {*} fallback use when there is no value at specified path
+ * @return {*} value at path or fallback
+ *
+ * @func
+ * @extends dot/getPathSegments
+ *
+ * {@link https://github.com/jashkenas/underscore/blob/master/underscore.js#L150 underscore-deep-get}
+ * @see {@link underscore-deep-get}
+ *
+ * @example
+ *
+ * dot.get({a: {b: 2}}, 'a.b') //=> 2
+ * dot.get({a: {b: 2}}, ['a', 'b']) //=> 2
+ * dot.get({c: {b: 2}}, ['a', 'b']) //=> undefined
+ *
+ */
+module.exports = function(obj, path, fallback) {
+ // if (pathArray.length === 1 && hasOwnProperty(dot, path[0]))
+ // return dot[path[0]]
+ // else if (isString(path) && path.includes('.') === false && hasOwnProperty(dot, path))
+ // return dot[path]
+
if (!isDottable(obj, path)) {
- return isUndefined(value) ? obj : value
+ return isUndefined(fallback) ? obj : fallback
}
const pathArr = getPathSegments(path)
for (let i = 0; i < pathArr.length; i++) {
if (!isEnumerable(obj, pathArr[i])) {
- return value
+ return fallback
}
obj = obj[pathArr[i]]
if (isNullOrUndefined(obj)) {
- // `obj` is either `undefined` or `null` so we want to stop the loop, and
- // if this is not the last bit of the path, and
- // if it did't return `undefined`
- // it would return `null` if `obj` is `null`
- // but we want `get({foo: null}, 'foo.bar')` to equal `undefined`, or the supplied value, not `null`
+ /*
+ * `obj` is either `undefined` or `null` so we want to stop the loop, and
+ * if this is not the last bit of the path, and
+ * if it did't return `undefined`
+ * it would return `null` if `obj` is `null`
+ * but we want `get({foo: null}, 'foo.bar')` to equal `undefined`, or the supplied fallback, not `null`
+ */
if (i !== lengthMinusOne(pathArr)) {
- return value
+ return fallback
}
break
diff --git a/src/deps/dot/has.js b/src/deps/dot/has.js
index 0f3b2b1..8f29bd4 100644
--- a/src/deps/dot/has.js
+++ b/src/deps/dot/has.js
@@ -2,6 +2,27 @@ const isObj = require('../is/obj')
const getPathSegments = require('./segments')
const isDottable = require('./dottable')
+/**
+ * @name dot.has
+ * @memberOf dot
+ * @func
+ * @since 3.0.0
+ * @extends dot/getPathSegments
+ *
+ * @param {Object} obj the object to retrieve the nested property from.
+ * @param {Dottable | string | Array} path dot-prop-path to use
+ * @return {boolean} has at path
+ *
+ * {@link https://github.com/jashkenas/underscore/blob/master/underscore.js#L1369 underscore-has}
+ * @see {@link underscore-has}
+ *
+ * @example
+ *
+ * dot.has({a: {b: 2}}, 'a.b'); //=> true
+ * dot.has({a: {b: 2}}, ['a', 'b']); //=> true
+ * dot.has({c: {b: 2}}, ['a', 'b']); //=> undefined
+ *
+ */
module.exports = function dotHas(obj, path) {
if (!isDottable(obj, path)) {
return false
diff --git a/src/deps/dot/paths.js b/src/deps/dot/paths.js
index cd4874e..466f024 100644
--- a/src/deps/dot/paths.js
+++ b/src/deps/dot/paths.js
@@ -4,8 +4,6 @@ const traverse = require('../traverse')
const cache = require('../cache')
const ENV_DEBUG = require('../env/debug')
-let run = 0
-
/* prettier-ignore */
/**
* @desc gathers dot.prop from any value, with a prefixed/base key
@@ -16,6 +14,7 @@ let run = 0
* @param {boolean | undefined} [longest] optionally filter to keep only longest/deepest paths
* @return {Array} paths[]
*
+ * @see deps/traverse
* @TODO should build a trie if doing this
* @NOTE had `onlyLongest` & `asString` but can just .join(',') to match
*
@@ -29,11 +28,11 @@ let run = 0
*
*/
module.exports = function(key, value, longest) {
- // if (cache.has(value)) return cache.get(value)
+ if (cache.has(value)) return cache.get(value)
let paths = []
- /* istanbul-ignore next: debug */
+ /* istanbul ignore next: debug */
if (ENV_DEBUG) {
console.log({value})
}
@@ -47,20 +46,21 @@ module.exports = function(key, value, longest) {
// const currentPath = this.paths
const currentPath = this.path
- /* istanbul-ignore next: debug */
+ /* istanbul ignore next: debug */
if (ENV_DEBUG) {
- console.log('paths', run++, this.path)
+ // run++,
+ console.log('paths', this.path)
}
+ // @NOTE we always have paths now
// ignore
- if (!currentPath || !currentPath.length) return
+ // if (!currentPath) return
+ if (!currentPath.length) return
+ // (currentPath.join ? currentPath.join('.') : currentPath)
// dot-prop the array of paths
// if we have a key, prefix it
- paths.push(
- (key ? key + '.' : '') +
- (currentPath.join ? currentPath.join('.') : currentPath)
- )
+ paths.push((key ? key + '.' : '') + currentPath.join('.'))
})
if (isTrue(longest)) {
@@ -71,7 +71,7 @@ module.exports = function(key, value, longest) {
))
}
- // cache.set(value, paths)
+ cache.set(value, paths)
return paths
}
diff --git a/src/deps/dot/segments.js b/src/deps/dot/segments.js
index 3ccffe5..9fd5416 100644
--- a/src/deps/dot/segments.js
+++ b/src/deps/dot/segments.js
@@ -3,6 +3,27 @@ const isUndefined = require('../is/undefined')
const lengthMinusOne = require('../util/lengthMinusOne')
let cache
+
+/**
+ * @name dotPropSegments
+ * @alias castPath
+ *
+ * @TODO `isKey(value, object) ? [value] : stringToPath(value)`
+ * // isKey/hasIn
+ *
+ * @since 4.0.0
+ * @memberOf dot
+ *
+ * @param {string | Array} path dot-prop-path
+ * @return {Array} array path
+ *
+ * @example
+ *
+ * dotPropSegments('eh.oh') //=> ['eh', 'oh']
+ * dotPropSegments(['eh', 'oh']) //=> ['eh', 'oh']
+ * dotPropSegments('ehoh') //=> ['ehoh']
+ *
+ */
module.exports = path => {
if (!cache) cache = new Map()
if (cache.has(path)) return cache.get(path)
@@ -16,8 +37,8 @@ module.exports = path => {
/**
* @example 1
- * '\.eh' -1 === '\\' (true)
- * +1 !== undefined (true, eh)
+ * '\.eh' -1 === '\\' //=> true
+ * +1 !== undefined //=> true, eh
*
* @example 2
* '.eh' -1 === '\\' (false, undefined)
diff --git a/src/deps/dot/set.js b/src/deps/dot/set.js
index 9fddc33..16094bf 100644
--- a/src/deps/dot/set.js
+++ b/src/deps/dot/set.js
@@ -17,6 +17,7 @@ module.exports = function dotset(obj, path, value) {
obj[p] = {}
}
+ // isLast
if (i === lengthMinusOne(pathArr)) {
obj[p] = value
}
diff --git a/src/deps/encase/encase.js b/src/deps/encase/encase.js
index 5551d0a..39d06b2 100644
--- a/src/deps/encase/encase.js
+++ b/src/deps/encase/encase.js
@@ -1,11 +1,22 @@
const tryCatch = require('./tryCatch')
/**
+ * @desc wrap in tryCatch, or a tryCatch-like api
+ * @version 5.0.0 wrapped tryCatch & withSpecification in curry
* @version 4.0.1 added custom encaser
* @since 4.0.0
- * @param {Function} call function to _encase_
- * @param {Function | undefined} [encaser=tryCatch] function to encase _with_
- * @return {Function} -> FunctionObject{onInvalid, onValid, rethrow, call}
+ * @member encase
+ * @alias attempt
+ * @symb 🛡
+ *
+ * @param {Function} call function to _encase_
+ * @param {Function | undefined} [encaser=tryCatch] function to encase _with_
+ * @return {Function} -> FunctionObject{onInvalid, onValid, rethrow, call}
+ *
+ * {@link https://github.com/fluture-js/Fluture#encase fluture-encase}
+ * {@link https://github.com/lodash/lodash/blob/master/attempt.js lodash-attempt}
+ * @see {@link lodash-attempt}
+ * @see {@link fluture-encase}
*
* @example
*
@@ -33,6 +44,7 @@ const tryCatch = require('./tryCatch')
module.exports = (call, encaser) => {
const encased = encaser ? encaser(call) : tryCatch(call)
+ // @TODO rethink this scoped approach
// left, right, rethrow
let onInvalid
let onValid
diff --git a/src/deps/encase/tryCatch.js b/src/deps/encase/tryCatch.js
index 0789521..79e0094 100644
--- a/src/deps/encase/tryCatch.js
+++ b/src/deps/encase/tryCatch.js
@@ -1,12 +1,26 @@
+const curry = require('../fp/curry')
+
/**
- * @see https://github.com/fluture-js/Fluture#encase
- * @since 4.0.0 <- moved out into a dep
+ * @name tryCatch
+ * @curried 3
+ * @memberOf encase
+ *
+ * @version 4.0.0 <- moved out into a dep
* @since 1.0.0
*
- * @param {Function} call
+ * @param {Function} call function that may throw
+ * @param {Function} [onValid] call when valid
+ * @param {Function} [onInvalid] call when invalid
* @return {boolean | any} validation/encased function call result
+ *
+ * @TODO `call.apply(null, arguments)` > a, b, c
+ *
+ * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/try...catch mozilla-trycatch}
+ * {@link https://github.com/fluture-js/Fluture#encase fluture-encase}
+ * @see {@link fluture-encase}
+ * @see {@link mozilla-trycatch}
*/
-module.exports = call => (onValid, onInvalid, rethrow) => (a, b, c) => {
+module.exports = curry(3, (call, onValid, onInvalid) => (a, b, c) => {
let result
try {
result = call(a, b, c)
@@ -18,4 +32,4 @@ module.exports = call => (onValid, onInvalid, rethrow) => (a, b, c) => {
if (onInvalid) return onInvalid(error)
else return error
}
-}
+})
diff --git a/src/deps/encase/withSpecification.js b/src/deps/encase/withSpecification.js
index 7c83722..fd8605d 100644
--- a/src/deps/encase/withSpecification.js
+++ b/src/deps/encase/withSpecification.js
@@ -1,5 +1,30 @@
-module.exports = specification => call => (onInvalid, onValid) => (a, b, c) => {
+const curry = require('../fp/curry')
+
+/**
+ * @desc a special encased wrapper with no try catch but same api
+ * @name withSpecification
+ * @func
+ * @memberOf encase
+ * @since 4.0.0
+ *
+ * @param {Function} specification match
+ * @param {Function} call cb to determine valid or invalid
+ * @param {Function} onInvalid cb when invalid
+ * @param {Function} onInvalid cb when valid
+ * @return {Function} a lot of functions...
+ *
+ * @see fp/curry
+ *
+ * @example
+ * const onInvalid = console.error
+ * const onValid = console.debug
+ * const onCall = console.log
+ * const encased = withSpecification(x => true)(onCall)(onValid, onInvalid)
+ *
+ * encased(1, 2, 3) //=> onCall (did not throw)
+ */
+module.exports = curry(4, (specification, call, onInvalid, onValid) => (a, b, c) => {
const result = call(a, b, c)
if (specification(result)) return onInvalid(result)
else return onValid(result)
-}
+})
diff --git a/src/deps/env/compat.js b/src/deps/env/compat.js
new file mode 100644
index 0000000..1ef61b7
--- /dev/null
+++ b/src/deps/env/compat.js
@@ -0,0 +1,8 @@
+/**
+ * @desc for exporting COMPATIBLE versions with poly or poly
+ * @memberOf env
+ * @since 5.0.0-beta.1
+ * @category Build
+ * @type {boolean}
+ */
+module.exports = process.env.COMPAT === 'polyfill'
diff --git a/src/deps/env/debug.js b/src/deps/env/debug.js
index 035eb48..da3aac8 100644
--- a/src/deps/env/debug.js
+++ b/src/deps/env/debug.js
@@ -1 +1,8 @@
+/**
+ * @desc for exporting `debugger` versions, for easy debugging & verbose logs
+ * @memberOf env
+ * @since 4.0.0
+ * @category Build
+ * @type {boolean}
+ */
module.exports = process.env.NODE_ENV === 'debug' // || process.env.DEBUG = true
diff --git a/src/deps/env/debuggable.js b/src/deps/env/debuggable.js
new file mode 100644
index 0000000..2cefac4
--- /dev/null
+++ b/src/deps/env/debuggable.js
@@ -0,0 +1,273 @@
+
+// ---
+
+// with a huge refactor to this,
+// with tons of safety
+// configuration like debugging on condition in certain places
+// stacktrace & sourcemap forcing on certain builds
+// this would provide a lovely debugging tool
+
+// ---
+const reStack = /(?:\n {4}at .*)+/;
+const errStack = err => {
+ const stack = err instanceof Error ? err.stack : err;
+
+ if (!stack) {
+ return '';
+ }
+
+ const match = stack.match(reStack);
+
+ if (!match) {
+ return '';
+ }
+
+ return match[0].slice(1);
+};
+
+// ---
+// https://github.com/ValYouW/njsTrace WRAPS ALL FN1?
+// https://github.com/scottnonnenberg/notate/blob/master/src/notate.js#L137
+// https://github.com/Breeze/breeze.js.labs/blob/master/breeze.metadata-helper.js
+// https://github.com/v8/v8/wiki/Stack-Trace-API
+// https://github.com/sindresorhus/callsites
+const stacker = () => {
+ const _ = Error.prepareStackTrace;
+ Error.prepareStackTrace = (_, stack) => stack;
+ const stack = new Error().stack.slice(1);
+ Error.prepareStackTrace = _;
+ return stack;
+};
+
+// ---
+var stringify = x => {
+ try {
+ const str = JSON.stringify(x, null, 2)
+ return str
+ }
+ catch (e) {
+ var str = {}
+ str.type = Object.prototype.toString.call(x)
+ for (var prop in x) {
+ str[prop] = stringify(x[prop])
+ }
+ return stringify(x)
+ }
+}
+
+var pretty = x => stringify(x).replace(/["\\[\]\,\']/g, '')
+
+// ---
+
+var weakCache = new WeakMap()
+var record = new WeakSet()
+var list = new Set()
+var cache = new Map()
+
+function debuggableStorage(x) {
+ if (weakCache.has(x)) weakCache.get(x).count += 1
+ else weakCache.set(x, x)
+
+ if (cache.has(x)) cache.get(x).count += 1
+ else cache.set(x, x)
+
+ list.add(x)
+ record.add(x)
+ return debuggable
+}
+
+// ---
+
+function metadata() {
+ const time = Date.now()
+ const count = 0
+ return {time, count}
+}
+
+// ---
+
+function stackAt(index = 1) {
+ const stacks = stacker()
+ const stack = stacks[index]
+ const meta = {}
+
+ // huge
+ meta.thisArg = stack.getThis()
+ meta.fn = stack.getFunction()
+
+ // helpful
+ meta.methodName = stack.getMethodName()
+ meta.typeName = stack.getTypeName()
+ meta.functionName = stack.getFunctionName()
+
+ // file
+ meta.fileName = stack.getFileName()
+ meta.lineNumber = stack.getLineNumber()
+ meta.columnNumber = stack.getColumnNumber()
+ meta.origin = stack.getEvalOrigin()
+
+ // bools
+ const stackIs = {
+ topLevel: stack.isToplevel(),
+ constructor: stack.isConstructor(),
+ native: stack.isNative(),
+ }
+
+ const {
+ topLevel,
+ constructor,
+ native,
+ } = stackIs
+ const {
+ methodName,
+ functionName,
+ thisArg,
+ fn,
+ fileName,
+ lineNumber,
+ columnNumber,
+ origin,
+ } = meta
+
+ let called = {functionName, methodName, fileName, lineNumber}
+
+ if (topLevel || constructor || native) {
+ called.is = stackIs
+ }
+
+ if (origin != fileName) {
+ called.origin = origin
+ }
+
+ if (called.thisArg === global) called.thisArg = 'global'
+
+ return called
+}
+
+// could clone the data too
+function debuggable() {
+ const stack = stackAt(2)
+ const meta = metadata()
+ const result = Object.assign({}, stack, {}, meta)
+ result.args = arguments
+ result.str = arguments.length !== 0 ? stringify(arguments) : '0 args'
+
+ debuggableStorage(result)
+
+ return result
+}
+debuggable.list = list
+debuggable.record = record
+debuggable.cache = cache
+debuggable.metadata = metadata
+debuggable.stackAt = stackAt
+
+// ---
+
+// where, pluck, evolve
+debuggable.values = function(cb) {
+ const values = Array.from(debuggable.list.values())
+
+ // for entries
+ // let index = 0
+ // const keys = Object.keys(where)
+ // .reduce(function(reduced, value) {
+ // reduced[index++] = next
+ // return reduced
+ // }, {})
+
+ if (cb) return cb(values)
+ else return values
+}
+
+debuggable.where = function(where) {
+ return debuggable.values().filter(where)
+}
+
+var queryable = [
+ 'functionName',
+ 'methodName',
+ 'fileName',
+ 'lineNumber',
+ 'count',
+ 'args',
+ 'str',
+ 'time'
+ ]
+
+// ---
+
+// filter, unique keys, index of the values with the uniq keys
+// debuggable.keys()
+
+
+// --- example ---
+
+// function gogo() {
+// debuggable(arguments)
+// }
+
+// class Go {}
+// Go.prototype.gogo = gogo
+// Go.prototype.zoomzoon = function() {
+// debuggable(arguments)
+// }
+
+// // gogo()
+// new Go().gogo()
+// new Go().gogo(1)
+// new Go().gogo(1)
+// new Go().zoomzoom('heyya')
+
+// -----
+
+// functionName: 'gogo',
+// methodName: 'gogo',
+// fileName: '_play.js',
+// lineNumber: 189,
+// count: 0,
+// args: { '0': [Object] },
+// str: '{\n "0": {\n "0": 1\n }\n}' } => { functionName: 'gogo',
+
+// const values = debuggable.values()
+// const R = require('ramda')
+// const propped = R.props(['functionName', 'methodName'], values)
+// const result = R.where(R.contains('zoomzoom'), propped)
+
+// console.log({result, propped})
+
+// debuggable.cache.forEach(eh => console.log('list', eh))
+// console.log(cache)
+
+// @example ramda filtering
+
+// const vals = Array.from(debuggable.values())
+// const propped = vals.map(val => R.props(['functionName', 'methodName'], val))
+
+// const funcLens = R.lensProp('functionName')
+// const funcWhere = R.where(funcLens, R.contains('zoomzoom'))
+// const funcSatisfies = R.where({
+// functionName: R.equals('zoomzoom'),
+// })
+
+// const evolved = vals.map(val => {
+
+// const lensed = R.view(funcLens, val)
+// const satisfies = funcSatisfies(val)
+
+// // console.log({lensed, satisfies, val})
+
+// if (satisfies) return R.evolve({functionName: R.identity}, val)
+// else return false
+// })
+// .filter(Boolean)
+
+// // .map(v => v[0] && v[1] ? R.fromPairs(v): v)
+// const result = R.where(R.contains('zoomzoom'), propped)
+
+// // console.log('eh', propped)
+
+// // console.log({result, propped, vals})
+// console.log(evolved)
+
+module.exports = debuggable
\ No newline at end of file
diff --git a/src/deps/env/dev.js b/src/deps/env/dev.js
index 0196f89..bd44f9e 100644
--- a/src/deps/env/dev.js
+++ b/src/deps/env/dev.js
@@ -1,2 +1,10 @@
-/* istanbul ignore next: wip build */
+/* istanbul ignore next: @build */
+
+/**
+ * @desc for exporting SMALLER builds
+ * @memberOf env
+ * @since 3.0.0
+ * @category Build
+ * @type {boolean}
+ */
module.exports = process.env.NODE_ENV !== 'production'
diff --git a/src/deps/env/index.js b/src/deps/env/index.js
new file mode 100644
index 0000000..4da2776
--- /dev/null
+++ b/src/deps/env/index.js
@@ -0,0 +1,7 @@
+/**
+ * @private
+ * @since 3.0.0
+ * @symb ⛰
+ * @category Build
+ * @member env
+ */
diff --git a/src/deps/env/preferPerf.js b/src/deps/env/preferPerf.js
new file mode 100644
index 0000000..4daba44
--- /dev/null
+++ b/src/deps/env/preferPerf.js
@@ -0,0 +1,10 @@
+/**
+ * @desc for exporting faster versions, can be larger size-e
+ * @memberOf env
+ * @since 5.0.0-beta.6
+ * @name preferPerf
+ * @alias PREFER_PERF
+ * @category Build
+ * @type {boolean}
+ */
+module.exports = process.env.PERF === 1
diff --git a/src/deps/env/preferSize.js b/src/deps/env/preferSize.js
new file mode 100644
index 0000000..d31a0e3
--- /dev/null
+++ b/src/deps/env/preferSize.js
@@ -0,0 +1,9 @@
+/**
+ * @desc for exporting smaller versions
+ * @memberOf env
+ * @since 5.0.0-beta.6
+ * @name preferSize
+ * @category Build
+ * @type {boolean}
+ */
+module.exports = process.env.SIZE === 1
diff --git a/src/deps/env/strict.js b/src/deps/env/strict.js
new file mode 100644
index 0000000..20ef72e
--- /dev/null
+++ b/src/deps/env/strict.js
@@ -0,0 +1,9 @@
+/**
+ * @desc for exporting verisons that throw errors, following stricter practice
+ * @memberOf env
+ * @since 5.0.0-beta.6
+ * @name strict
+ * @category Build
+ * @type {boolean}
+ */
+module.exports = process.env.STRICT === 1
diff --git a/src/deps/flipped/README.md b/src/deps/flipped/README.md
new file mode 100644
index 0000000..c4d9b94
--- /dev/null
+++ b/src/deps/flipped/README.md
@@ -0,0 +1,2 @@
+might rename this to `preset` since it is altered functions suited for use cases
+or `recipes` but hard to spell
diff --git a/src/deps/flipped/bindMethod.js b/src/deps/flipped/bindMethod.js
new file mode 100644
index 0000000..80b82c5
--- /dev/null
+++ b/src/deps/flipped/bindMethod.js
@@ -0,0 +1,37 @@
+const bind = require('../fp/bind')
+const flip2 = require('../fp/flip2')
+const curry = require('../fp/curry')
+const dotSet = require('../dot/set')
+const dotGet = require('../dot/get')
+const dotHas = require('../dot/has')
+const dotDelete = require('../dot/delete')
+
+const set = curry(2, flip2(dotSet))
+const get = curry(2, flip2(dotGet))
+const has = curry(2, flip2(dotHas))
+const del = curry(2, flip2(dotDelete))
+
+const thisBind = flip2(bind)
+
+/**
+ * @name bindMethod
+ * @since 5.0.0-beta.6
+ * @memberOf flipped
+ *
+ * @param {Object} thisArg context
+ * @param {Primitive} method method name
+ * @return {Function}
+ *
+ * @see fp/bind
+ * @see fp/flip2
+ * @see fp/curry
+ * @see dot/get
+ *
+ * @example
+ * const eh = {oh() {console.log(this)}}
+ * eh.oh = bindMethod(eh, 'oh')
+ */
+module.exports = (thisArg, method) => {
+ const fn = get(thisArg, method)
+ return thisBind(thisArg, fn)
+}
diff --git a/src/deps/flipped/defaultToNoop.js b/src/deps/flipped/defaultToNoop.js
new file mode 100644
index 0000000..e811794
--- /dev/null
+++ b/src/deps/flipped/defaultToNoop.js
@@ -0,0 +1,5 @@
+const defaultTo = require('../cast/defaultTo')
+const noop = require('../util/noop')
+
+// @since 5.0.0-beta.6
+module.exports = defaultTo(noop)
diff --git a/src/deps/flipped/hasOwnPropertyFlipped.js b/src/deps/flipped/hasOwnPropertyFlipped.js
new file mode 100644
index 0000000..842adf5
--- /dev/null
+++ b/src/deps/flipped/hasOwnPropertyFlipped.js
@@ -0,0 +1,4 @@
+const hasOwnProperty = require('../util/hasOwnProperty')
+const flip2 = require('../fp/flip2')
+
+module.exports = flip2(hasOwnProperty)
diff --git a/src/deps/flipped/index.js b/src/deps/flipped/index.js
new file mode 100644
index 0000000..10014c5
--- /dev/null
+++ b/src/deps/flipped/index.js
@@ -0,0 +1,4 @@
+/**
+ * @member flipped
+ * @symb 🙃
+ */
diff --git a/src/deps/flipped/invokeFlipped.js b/src/deps/flipped/invokeFlipped.js
new file mode 100644
index 0000000..3108a83
--- /dev/null
+++ b/src/deps/flipped/invokeFlipped.js
@@ -0,0 +1,4 @@
+const invoke = require('../fp/invoke')
+const flip2 = require('../fp/flip2')
+
+module.exports = flip2(invoke)
diff --git a/src/deps/flipped/isOfInstance.js b/src/deps/flipped/isOfInstance.js
new file mode 100644
index 0000000..2802b90
--- /dev/null
+++ b/src/deps/flipped/isOfInstance.js
@@ -0,0 +1,4 @@
+const instanceOf = require('../is/instanceOf')
+const flip2 = require('../fp/flip2')
+
+module.exports = flip2(instanceOf)
diff --git a/src/deps/flipped/sliceFlipped.js b/src/deps/flipped/sliceFlipped.js
new file mode 100644
index 0000000..6bc7933
--- /dev/null
+++ b/src/deps/flipped/sliceFlipped.js
@@ -0,0 +1,7 @@
+const slice = require('../fp/slice')
+const flip2 = require('../fp/flip2')
+const flip = require('../fp/flip')
+
+// list, fromIndex, toIndex
+// fromIndex, toIndex, list
+module.exports = flip2(flip(slice))
diff --git a/src/deps/fp/README.md b/src/deps/fp/README.md
new file mode 100644
index 0000000..29fd822
--- /dev/null
+++ b/src/deps/fp/README.md
@@ -0,0 +1,4 @@
+could do a wicked curry with types so auto fits in slot of type :3
+can also do like `onType`, or `onSignature` to allow EASY overloading!!!
+
+https://github.com/ramda/ramda-fantasy/blob/master/src/Either.js
diff --git a/src/deps/fp/always.js b/src/deps/fp/always.js
new file mode 100644
index 0000000..95e229e
--- /dev/null
+++ b/src/deps/fp/always.js
@@ -0,0 +1,47 @@
+/**
+ * Returns a function that always returns the given value. Note that for
+ * non-primitives the value returned is a reference to the original value.
+ *
+ * This function is known as `const`, `constant`, or `K` (for K combinator) in
+ * other languages and libraries.
+ *
+ * @icon ☝
+ * @alias always
+ * @alias constant
+ * @alias const
+ *
+ * @tests fp/always
+ *
+ * @func
+ * @memberOf fp
+ * @since v5.0.0
+ * @category Function
+ * @sig a -> (* -> a)
+ *
+ * @param {*} value The value to wrap in a function
+ * @return {Function} A Function :: * -> val.
+ *
+ * {@link https://github.com/jashkenas/underscore/blob/master/underscore.js#L1399 underscore-src-constant}
+ * {@link http://underscorejs.org/#constant underscore-constant}
+ * {@link https://github.com/lodash/lodash/issues/1010 lodash-constant}
+ * {@link https://github.com/ramda/ramda/issues/1038 ramda-constant-docs-issue}
+ * {@link https://github.com/ramda/ramda/blob/master/src/always.js ramda-always}
+ * @see {@link ramda-constant-docs-issue}
+ * @see {@link ramda-always}
+ * @see {@link lodash-constant}
+ * @see {@link underscore-constant}
+ *
+ * @types fp
+ * @tests fp/always
+ *
+ * @example
+ *
+ * var t = always('Tee')
+ * t() //=> 'Tee'
+ *
+ */
+module.exports = function constant(value) {
+ return function() {
+ return value
+ }
+}
diff --git a/src/deps/fp/arity.js b/src/deps/fp/arity.js
new file mode 100644
index 0000000..684bce2
--- /dev/null
+++ b/src/deps/fp/arity.js
@@ -0,0 +1,56 @@
+/* eslint complexity: "OFF" */
+/* eslint consistent-return: "OFF" */
+/* eslint max-len: "OFF" */
+/* eslint no-unused-vars: "OFF" */
+
+/* istanbul ignore next: metadata, one is covered, all are covered */
+/* prettier-ignore */
+/**
+ * @desc just for `.length` of a function, to know how many args
+ * @memberOf fp
+ *
+ * @since 5.0.0
+ * @param {number} n number of arguments
+ * @param {Function} fn function to wrap
+ * @return {Function} function with params
+ *
+ * @tests fp/arity
+ *
+ * {@link https://github.com/blakeembrey/nary nary}
+ * {@link https://www.npmjs.com/package/util-arity util-arity}
+ * {@link https://docs.microsoft.com/en-us/scripting/javascript/reference/length-property-function-javascript microsoft-func-length}
+ * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/arity mozilla-func-arity}
+ * @see {@link mozilla-func-arity}
+ * @see {@link microsoft-func-length}
+ * @see {@link util-arity}
+ * @see {@link nary}
+ *
+ * @NOTE keeping this means uglify `keep_func_args: false`
+ *
+ * @example
+ *
+ * const wan = one => console.log(one)
+ * arity(1, wan)
+ * => function(one => wan(one))
+ *
+ * const five = ($1, $2, $3, $4, $5) => console.log.apply(console, arguments)
+ * arity(5, five).length
+ * //=> 5
+ *
+ */
+module.exports = function _arity(n, fn) {
+ // if (n === 0 || n > 5)
+ if (n === 1) return function($0) { return fn.apply(this, arguments) }
+ else if (n === 2) return function($0, $1) { return fn.apply(this, arguments) }
+ else if (n === 3) return function($0, $1, $2) { return fn.apply(this, arguments) }
+ else if (n === 4) return function($0, $1, $2, $3) { return fn.apply(this, arguments) }
+ else if (n === 5) return function($0, $1, $2, $3, $4) { return fn.apply(this, arguments) }
+ else return function() { return fn.apply(this, arguments) }
+
+ // @NOTE ignoring
+ // else if (n === 6) return function(a0, a1, a2, a3, a4, a5) { return fn.apply(this, arguments) }
+ // else if (n === 7) return function(a0, a1, a2, a3, a4, a5, a6) { return fn.apply(this, arguments) }
+ // else if (n === 8) return function(a0, a1, a2, a3, a4, a5, a6, a7) { return fn.apply(this, arguments) }
+ // else if (n === 9) return function(a0, a1, a2, a3, a4, a5, a6, a7, a8) { return fn.apply(this, arguments) }
+ // else if (n === 10) return function(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) { return fn.apply(this, arguments) }
+}
diff --git a/src/deps/fp/bind.js b/src/deps/fp/bind.js
new file mode 100644
index 0000000..2ccaa18
--- /dev/null
+++ b/src/deps/fp/bind.js
@@ -0,0 +1,45 @@
+const arity = require('./arity')
+const curry = require('./curry')
+
+/**
+ * Creates a function that is bound to a context.
+ * @since 5.0.0-beta.5
+ * @memberOf fp
+ *
+ * @param {Function} fn The function to bind to context
+ * @param {Object} thisArg The context to bind `fn` to
+ * @return {Function} A function that will execute in the context of `thisArg`.
+ *
+ * @tests fp/bind
+ *
+ * @func
+ * @fork v0.6.0
+ * @category Function
+ * @category Object
+ * @sig (* -> *) -> {*} -> (* -> *)
+ * @symb bind(f, o)(a, b) = f.call(o, a, b)
+ *
+ * {@link https://github.com/jashkenas/underscore/blob/master/underscore.js#L765 underscore-bind}
+ * {@link https://github.com/lodash/lodash/blob/master/bindKey.js lodash-bind-key}
+ * {@link https://github.com/ramda/ramda/blob/master/src/partial.js ramda-partial}
+ * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind mozilla-Function.bind}
+ * @see {@link mozilla-Function.bind}
+ * @see {@link ramda-partial}
+ * @see {@link lodash-bind-key}
+ * @see {@link underscore-bind}
+ *
+ * @NOTE `bind` does not provide the additional argument-binding capabilities of
+ * [Function.prototype.bind](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind).
+ *
+ * @example
+ *
+ * var log = bind(console.log, console);
+ * R.pipe(R.assoc('a', 2), R.tap(log), R.assoc('a', 3))({a: 1}); //=> {a: 3}
+ * // logs {a: 2}
+ *
+ */
+module.exports = curry(2, function bind(fn, thisArg) {
+ return arity(fn.length, function() {
+ return fn.apply(thisArg, arguments)
+ })
+})
diff --git a/src/deps/fp/construct.js b/src/deps/fp/construct.js
new file mode 100644
index 0000000..d3f6cd2
--- /dev/null
+++ b/src/deps/fp/construct.js
@@ -0,0 +1,98 @@
+/* eslint max-len: "OFF" */
+/* eslint consistent-return: "OFF" */
+
+const isNumberPrimitive = require('../is/numberPrimitive')
+const curry = require('./curry')
+// const nAry = require('./arity')
+
+/**
+ * Wraps a constructor function inside a curried function that can be called
+ * with the same arguments and returns the same type. The arity of the function
+ * returned is specified to allow using variadic constructor functions.
+ *
+ * @memberOf fp
+ * @symb 👷
+ * @since 5.0.0-beta.4
+ *
+ * @param {number} n The arity of the constructor function. (aka, number of args)
+ * @param {Function} Klass The constructor function to wrap. (class to do `new Klass` on)
+ * @return {Function} A wrapped, curried constructor function.
+ *
+ * @func
+ * @fork v0.4.0
+ * @category Function
+ * @sig Number -> (* -> {*}) -> (* -> {*})
+ *
+ * @extends R.construct
+ * @extends R.constructN
+ * @variation with a single *notNumber* arg, it acts as construct, rather than constructN
+ *
+ * {@link https://stackoverflow.com/questions/9267157/why-is-it-impossible-to-change-constructor-function-from-prototype stack-overflow-constructor}
+ * {@link https://github.com/ramda/ramda/blob/master/src/constructN.js ramda-construct}
+ * @see {@link ramda-construct}
+ * @see {@link stack-overflow-constructor}
+ * @see isNumberPrimitive
+ *
+ * @example
+ *
+ * // Variadic Constructor function
+ * function Salad() {
+ * this.ingredients = arguments;
+ * }
+ *
+ * Salad.prototype.recipe = function() {
+ * var instructions = R.map(ingredient => 'Add a dollop of ' + ingredient, this.ingredients);
+ * return R.join('\n', instructions);
+ * };
+ *
+ * var ThreeLayerSalad = R.constructN(3, Salad);
+ *
+ * // Notice we no longer need the 'new' keyword, and the constructor is curried for 3 arguments.
+ * var salad = ThreeLayerSalad('Mayonnaise')('Potato Chips')('Ketchup');
+ *
+ * console.log(salad.recipe());
+ * // Add a dollop of Mayonnaise
+ * // Add a dollop of Potato Chips
+ * // Add a dollop of Ketchup
+ *
+ */
+function constructN(n, Klass) {
+ if (!isNumberPrimitive(n)) {
+ return constructN(n.length, n)
+ }
+ else if (n === 0) {
+ /**
+ * @HACK @FIXME @TODO shows incorrect arity,
+ * but if we want not-specific constructs...
+ */
+ return (...args) => {
+ if (args.length !== 0) {
+ return constructN(args.length, Klass).apply(this, args)
+ }
+ else {
+ return new Klass()
+ }
+ }
+ }
+ else {
+ /*, $5, $6, $7, $8, $9 */
+ // curry(nAry(n,
+ return curry(n, function($0, $1, $2, $3, $4) {
+ const len = arguments.length
+ if (len === 1 || len > 5) return new Klass($0, $1, $2)
+ else if (len === 2) return new Klass($0, $1)
+ else if (len === 3) return new Klass($0, $1, $2)
+ else if (len === 4) return new Klass($0, $1, $2, $3)
+ else if (len === 5) return new Klass($0, $1, $2, $3, $4)
+ // else if (len=== 6) return new Klass($0, $1, $2, $3, $4, $5)
+ // else if (len=== 7) return new Klass($0, $1, $2, $3, $4, $5, $6)
+ // else if (len=== 8) return new Klass($0, $1, $2, $3, $4, $5, $6, $7)
+ // else if (len=== 9) return new Klass($0, $1, $2, $3, $4, $5, $6, $7, $8)
+ // else if (len === 10) return new Klass($0, $1, $2, $3, $4, $5, $6, $7, $8, $9)
+ })
+ // ))
+ }
+}
+
+// module.exports = curry(2, constructN)
+module.exports = constructN
diff --git a/src/deps/fp/constructInit.js b/src/deps/fp/constructInit.js
new file mode 100644
index 0000000..68924b2
--- /dev/null
+++ b/src/deps/fp/constructInit.js
@@ -0,0 +1,9 @@
+/* istanbul ignore: @TODO */
+
+const construct = require('./construct')
+
+// adds .init function that is constructN
+module.exports = function addInit(Klass, n = 1) {
+ Klass.init = construct(n, Klass)
+ // return Klass
+}
diff --git a/src/deps/fp/curry.js b/src/deps/fp/curry.js
new file mode 100644
index 0000000..9d77e22
--- /dev/null
+++ b/src/deps/fp/curry.js
@@ -0,0 +1,150 @@
+const isPlaceholder = require('./isPlaceholder')
+const arity = require('./arity')
+
+/**
+ * Returns a curried equivalent of the provided function, with the specified
+ * arity. The curried function has two unusual capabilities. First, its
+ * arguments needn't be provided one at a time. If `g` is `R.curryN(3, f)`, the
+ * following are equivalent:
+ *
+ * - `g(1)(2)(3)`
+ * - `g(1)(2, 3)`
+ * - `g(1, 2)(3)`
+ * - `g(1, 2, 3)`
+ *
+ * Secondly, the special placeholder value [`R.__`](#__) may be used to specify
+ * "gaps", allowing partial application of any combination of arguments,
+ * regardless of their positions. If `g` is as above and `_` is [`R.__`](#__),
+ * the following are equivalent:
+ *
+ * - `g(1, 2, 3)`
+ * - `g(_, 2, 3)(1)`
+ * - `g(_, _, 3)(1)(2)`
+ * - `g(_, _, 3)(1, 2)`
+ * - `g(_, 2)(1)(3)`
+ * - `g(_, 2)(1, 3)`
+ * - `g(_, 2)(_, 3)(1)`
+ *
+ * @alias curryN
+ * @alias partial
+ * @since 5.0.0-beta.1
+ *
+ * @param {number} length The arity of the curried function.
+ * @param {Array} received An array of arguments received thus far.
+ * @param {Function} fn The function to curry.
+ * @return {Function} A new, curried function.
+ *
+ * @func
+ * @memberOf fp
+ * @ramda v0.5.0
+ * @category Function
+ * @sig Number -> (* -> a) -> (* -> a)
+ *
+ * {@link https://github.com/andrewplummer/Sugar/blob/master/lib/function.js#L382 sugar-partial}
+ * {@link http://documentcloud.github.io/underscore-contrib/#curry underscore-contrib-curry}
+ * {@link https://github.com/lodash/lodash/blob/master/.internal/composeArgs.js lodash-compose-args}
+ * {@link https://github.com/jashkenas/underscore/blob/master/underscore.js#L773 underscore-partial}
+ * {@link https://github.com/ramda/ramda/blob/master/src/uncurryN.js ramda-uncurry}
+ * {@link https://github.com/ramda/ramda/blob/master/src/curryN.js ramda-curry}
+ * {@link https://github.com/lodash/lodash/blob/master/curry.js lodash-curry}
+ * @see {@link ramda-curry}
+ * @see {@link lodash-curry}
+ * @see {@link ramda-uncurry}
+ * @see {@link underscore-partial}
+ * @see {@link sugar-partial}
+ *
+ * @types fp/curry
+ * @tests fp/curry
+ *
+ * @example
+ *
+ * var sumArgs = (...args) => R.sum(args);
+ *
+ * var curriedAddFourNumbers = R.curryN(4, sumArgs);
+ * var f = curriedAddFourNumbers(1, 2);
+ * var g = f(3);
+ * g(4); //=> 10
+ *
+ */
+function _curryN(length, received, fn) {
+ return function() {
+ const combined = []
+ let argsIdx = 0
+ let left = length
+ let combinedIdx = 0
+
+ while (combinedIdx < received.length || argsIdx < arguments.length) {
+ let result
+
+ if (
+ combinedIdx < received.length &&
+ (!isPlaceholder(received[combinedIdx]) || argsIdx >= arguments.length)
+ ) {
+ result = received[combinedIdx]
+ }
+ else {
+ result = arguments[argsIdx++]
+ // argsIdx += 1
+ }
+ combined[combinedIdx++] = result
+ if (!isPlaceholder(result)) {
+ left -= 1
+ }
+ // combinedIdx += 1
+ }
+
+ return left <= 0
+ ? fn.apply(this, combined)
+ : arity(left, _curryN(length, combined, fn))
+ }
+}
+
+/**
+ * Returns a curried equivalent of the provided function, with the specified
+ * arity. The curried function has two unusual capabilities. First, its
+ * arguments needn't be provided one at a time. If `g` is `R.curryN(3, f)`, the
+ * following are equivalent:
+ *
+ * - `g(1)(2)(3)`
+ * - `g(1)(2, 3)`
+ * - `g(1, 2)(3)`
+ * - `g(1, 2, 3)`
+ *
+ * Secondly, the special placeholder value [`R.__`](#__) may be used to specify
+ * "gaps", allowing partial application of any combination of arguments,
+ * regardless of their positions. If `g` is as above and `_` is [`R.__`](#__),
+ * the following are equivalent:
+ *
+ * - `g(1, 2, 3)`
+ * - `g(_, 2, 3)(1)`
+ * - `g(_, _, 3)(1)(2)`
+ * - `g(_, _, 3)(1, 2)`
+ * - `g(_, 2)(1)(3)`
+ * - `g(_, 2)(1, 3)`
+ * - `g(_, 2)(_, 3)(1)`
+ *
+ * @func
+ * @memberOf fp
+ * @since v0.5.0
+ * @category Function
+ * @sig Number -> (* -> a) -> (* -> a)
+ *
+ * @param {number} length The arity for the returned function.
+ * @param {Function} fn The function to curry.
+ * @return {Function} A new, curried function.
+ *
+ * @see ramda
+ *
+ * @example
+ *
+ * var sumArgs = (...args) => R.sum(args);
+ *
+ * var curriedAddFourNumbers = R.curryN(4, sumArgs);
+ * var f = curriedAddFourNumbers(1, 2);
+ * var g = f(3);
+ * g(4); //=> 10
+ *
+ */
+module.exports = function curryN(length, fn) {
+ return arity(length, _curryN(length, [], fn))
+}
diff --git a/src/deps/fp/equals.js b/src/deps/fp/equals.js
new file mode 100644
index 0000000..4da1fad
--- /dev/null
+++ b/src/deps/fp/equals.js
@@ -0,0 +1,12 @@
+const eq = require('../traversers/eq')
+const curry = require('./curry')
+
+/**
+ * @name equals
+ * @curried 2
+ * @memberOf fp
+ * @since 5.0.0-beta.6
+ * @see traversers/eq
+ * @type {Function}
+ */
+module.exports = curry(2, eq)
diff --git a/src/deps/fp/evolve.js b/src/deps/fp/evolve.js
new file mode 100644
index 0000000..574e257
--- /dev/null
+++ b/src/deps/fp/evolve.js
@@ -0,0 +1,68 @@
+const isFunction = require('../is/function')
+const isObjNotNull = require('../is/objNotNull')
+const curry = require('./curry')
+
+/**
+ * Creates a new object by recursively evolving a shallow copy of `object`,
+ * according to the `transformation` functions. All non-primitive properties
+ * are copied by reference.
+ *
+ * A `transformation` function will not be invoked if its corresponding key
+ * does not exist in the evolved object.
+ *
+ * @icon 🦎
+ * @alias evolve
+ * @alias transform
+ * @alias transformWith
+ * @since 5.0.0-beta.6
+ * @curried 2
+ * @memberOf fp
+ *
+ * @param {Object} transformations The object specifying transformation functions to apply
+ * to the object.
+ * @param {Object} object The object to be transformed.
+ * @return {Object} The transformed object.
+ *
+ * @tests fp/evolve
+ *
+ * @func
+ * @fork v0.9.0
+ * @category Object
+ * @sig {k: (v -> v)} -> {k: v} -> {k: v}
+ *
+ * {@link https://github.com/bahmutov/change-by-example change-by-example}
+ * {@link https://github.com/lodash/lodash/blob/master/transform.js lodash-transform}
+ * {@link https://github.com/ramda/ramda/blob/v0.24.1/src/evolve.js ramda-evolve}
+ * @see {@link lodash-transform}
+ * @see {@link ramda-evolve}
+ * @see {@link change-by-example}
+ *
+ * @example
+ *
+ * var tomato = {firstName: ' Tomato ', data: {elapsed: 100, remaining: 1400}, id:123}
+ * var transformations = {
+ * firstName: R.trim,
+ * lastName: R.trim, // Will not get invoked.
+ * data: {elapsed: R.add(1), remaining: R.add(-1)}
+ * }
+ * evolve(transformations, tomato)
+ * //=> {firstName: 'Tomato', data: {elapsed: 101, remaining: 1399}, id:123}
+ *
+ */
+module.exports = curry(2, function evolve(transformations, object) {
+ const result = {}
+ let transformation
+ let key
+
+ // eslint-disable-next-line
+ for (key in object) {
+ transformation = transformations[key]
+ result[key] = isFunction(transformation)
+ ? transformation(object[key])
+ : isObjNotNull(transformation)
+ ? evolve(transformation, object[key])
+ : object[key]
+ }
+
+ return result
+})
diff --git a/src/deps/fp/find.js b/src/deps/fp/find.js
new file mode 100644
index 0000000..9fda647
--- /dev/null
+++ b/src/deps/fp/find.js
@@ -0,0 +1,26 @@
+const traverse = require('../traverse')
+const defaultTo = require('../cast/defaultTo')
+const isMatchWith = require('../is/matchWith')
+
+// moved to deps 5.0.0-beta.6
+// https://github.com/fluents/chain-able/issues/32
+// module.exports = function find(path, arg, fallback) {
+// const data = defaultTo(x => this.entries(true), arg)
+// let val = null
+// // console.debug(`key: ${key} `)
+// const cb = (key, x, traverser) => {
+// if (isMatchWith(path, key) || traverser.path.includes(key)) {
+// val = x
+// traverser.stop()
+// // console.error({x})
+// }
+// // console.debug(`path: ${traverser.path.join('.')} prop: ${traverser.key}`)
+// // console.dir({x, path: traverser.path, key: traverser.key})
+// }
+//
+// traverse(data).forEach(function(x) {
+// cb(x, this)
+// })
+//
+// return val
+// }
diff --git a/src/deps/fp/first.js b/src/deps/fp/first.js
new file mode 100644
index 0000000..10a6930
--- /dev/null
+++ b/src/deps/fp/first.js
@@ -0,0 +1,44 @@
+const isIndexable = require('../is/indexable')
+const firstIndex = require('./firstIndex')
+
+/**
+ * Returns the first element of the given list or string. In some libraries
+ * this function is named `first`.
+ *
+ * @memberOf fp
+ * @since v5.0.0
+ *
+ * @extends deps/fp/firstIndex
+ * @param {*} x Array or Object find the last key of
+ * @return {*} value at last index
+ *
+ * @name first
+ * @alias head
+ *
+ * @tests fp/first
+ *
+ * @func
+ * @category List
+ * @sig [a] -> a | Undefined
+ * @sig String -> String
+ *
+ * {@link https://github.com/ramda/ramda/blob/master/src/head.js ramda-head}
+ * {@link https://github.com/lodash/lodash/blob/master/head.js lodash-head}
+ * {@link https://github.com/jashkenas/underscore/blob/master/underscore.js#L494 underscore-first}
+ * @see {@link underscore-head}
+ * @see {@link lodash-head}
+ * @see {@link ramda-head}
+ * @see R.init, R.head, R.tail
+ *
+ * @TODO could just pipe nth
+ *
+ * @example
+ *
+ * first(['fi', 'fo', 'fum']); //=> 'fi'
+ * first([]); //=> undefined
+ *
+ * first('abc'); //=> 'a'
+ * first(''); //=> ''
+ *
+ */
+module.exports = x => (isIndexable(x) ? x[firstIndex(x)] : undefined)
diff --git a/src/deps/fp/firstIndex.js b/src/deps/fp/firstIndex.js
new file mode 100644
index 0000000..fd82312
--- /dev/null
+++ b/src/deps/fp/firstIndex.js
@@ -0,0 +1,37 @@
+const ObjectKeys = require('../util/keys')
+const isArray = require('../is/array')
+const isString = require('../is/string')
+const isObj = require('../is/array')
+
+/**
+ * @desc get first index in a list
+ * @since 5.0.0-beta.2
+ * @version 5.0.0-beta.7 <- fixed silly position[0] giving wrong index in arr
+ * @memberOf fp
+ *
+ * @param {Array | Object | string | *} x item to find the first index of
+ * @return {*} first index, usually number/string
+ *
+ * @NOTE works for strings too eh
+ * @extends deps/util/keysObjOrArray
+ * @see deps/fp/first
+ *
+ * @example
+ *
+ * firstIndex([0, 'one']) //=> 0
+ * firstIndex({one: 1, two: 2}) //=> 'one'
+ *
+ */
+function firstIndex(x) {
+ // any string or array starts @ 0
+ if (isString(x) || isArray(x)) return 0
+
+ // otherwise, object is good, if no keys, use 0, not sure how best to-do
+ // probably better if this always returned a number, firstKey, firstIndex...
+ else if (isObj(x)) return ObjectKeys(x)[0] || '0'
+
+ // any other value, 0
+ else return 0
+}
+
+module.exports = firstIndex
diff --git a/src/deps/fp/flip.js b/src/deps/fp/flip.js
new file mode 100644
index 0000000..39efa5b
--- /dev/null
+++ b/src/deps/fp/flip.js
@@ -0,0 +1,46 @@
+const argumentor = require('../cast/argumentor')
+
+/**
+ * @desc flip the fn args:
+ * Creates a function that invokes `func` with arguments reversed.
+ *
+ * @memberOf fp
+ * @symb 🙃
+ * @since 5.0.0-beta.4
+ *
+ * @param {Function} fn The function to invoke with its first two parameters reversed.
+ * @return {*} The result of invoking `fn` with its first two parameters' order reversed.
+ *
+ * @func
+ * @ramda v0.1.0
+ * @category Function
+ * @sig ((a, b, c, ...) -> z) -> (b -> a -> c -> ... -> z)
+ *
+ * @TODO could also just call with fn.apply([b, a]), and have flipN
+ *
+ * {@link https://github.com/lodash/lodash/blob/4.2.1-npm-packages/lodash.flip/index.js lodash-flip}
+ * {@link https://github.com/ramda/ramda/blob/master/src/flip.js ramda-flip}
+ * @see {@link ramda-flip}
+ * @see {@link lodash-flip}
+ * @see fp/reverse
+ *
+ * @types fp
+ * @tests fp/flip
+ *
+ * @example
+ *
+ * var mergeThree = (a, b, c) => [].concat(a, b, c)
+ * mergeThree(1, 2, 3); //=> [1, 2, 3]
+ * flip(mergeThree)(1, 2, 3); //=> [3, 2, 1]
+ *
+ * const flipped = flip((...args) => args)
+ * flipped('a', 'b', 'c', 'd')
+ * //=> ['d', 'c', 'b', 'a']
+ *
+ */
+module.exports = function flip(fn) {
+ // could wrap in arity
+ return function() {
+ return fn.apply(this, argumentor.apply(null, arguments).reverse())
+ }
+}
diff --git a/src/deps/fp/flip2.js b/src/deps/fp/flip2.js
new file mode 100644
index 0000000..b38b699
--- /dev/null
+++ b/src/deps/fp/flip2.js
@@ -0,0 +1,42 @@
+const argumentor = require('../cast/argumentor')
+const curry = require('./curry')
+
+/**
+ * Returns a new function much like the supplied one, except that the first two
+ * arguments' order is reversed.
+ *
+ * @memberOf fp
+ * @symb 🙃🙃
+ * @since 5.0.0-beta.4
+ *
+ * @param {Function} fn The function to invoke with its first two parameters reversed.
+ * @return {*} The result of invoking `fn` with its first two parameters' order reversed.
+ *
+ * @extends fp/flip
+ * @variation just flip, but flips arg 1-2 instead of reversing all arguments
+ * @see fp/flip
+ * @TODO flipN
+ *
+ * @types fp
+ * @tests fp/flip2
+ *
+ * @example
+ *
+ * var mergeThree = (a, b, c) => [].concat(a, b, c)
+ * mergeThree(1, 2, 3); //=> [1, 2, 3]
+ * flip(mergeThree)(1, 2, 3); //=> [2, 1, 3]
+ *
+ * const flipped = flip((...args) => args)
+ * flipped('a', 'b', 'c', 'd')
+ * //=> ['b', 'a', 'c', 'd']
+ *
+ */
+module.exports = function flip2(fn) {
+ return curry(2, function(a, b) {
+ const args = argumentor.apply(null, arguments)
+ // .slice(n).reverse().splice()
+ args[0] = b
+ args[1] = a
+ return fn.apply(this, args)
+ })
+}
diff --git a/src/deps/fp/fp.js b/src/deps/fp/fp.js
new file mode 100644
index 0000000..3711ef3
--- /dev/null
+++ b/src/deps/fp/fp.js
@@ -0,0 +1,81 @@
+/* istanbul ignore next: @docblocks @exports */
+
+const always = require('./always')
+const arity = require('./arity')
+const curry = require('./curry')
+const evolve = require('./evolve')
+const equals = require('./equals')
+const first = require('./first')
+const last = require('./last')
+const path = require('./path')
+const pipe = require('./pipe')
+const pipeTwo = require('./pipeTwo')
+const prop = require('./prop')
+const construct = require('./construct')
+const firstIndex = require('./firstIndex')
+const lastIndex = require('./lastIndex')
+const hasInMatching = require('./hasInMatching')
+const includesCount = require('./includesCount')
+const remove = require('./remove')
+const replace = require('./replace')
+const reverse = require('./reverse')
+const invoke = require('./invoke')
+const invoker = require('./invoker')
+const flip = require('./flip')
+const flip2 = require('./flip2')
+const bind = require('./bind')
+const times = require('./times')
+const nth = require('./nth')
+const nthArg = require('./nthArg')
+const invertObj = require('./invertObjKeyVal')
+const preferExistingMethod = require('./preferExistingMethod')
+const slice = require('./slice')
+const where = require('./where')
+const when = require('./when')
+const identity = require('./identity')
+// const wrap = require('./wrap')
+// const replaceWrap = require('./replaceWrap')
+
+/**
+ * @member fp
+ * @symb 🐏
+ * @tests fp/*
+ * @types fp
+ * @type {Object}
+ */
+module.exports = {
+ always,
+ arity,
+ bind,
+ construct,
+ hasInMatching,
+ equals,
+ includesCount,
+ invoke,
+ invoker,
+ curry,
+ first,
+ firstIndex,
+ flip,
+ flip2,
+ last,
+ lastIndex,
+ path,
+ pipe,
+ pipeTwo,
+ prop,
+ replace,
+ remove,
+ reverse,
+ times,
+ nth,
+ nthArg,
+ preferExistingMethod,
+ invertObj,
+ slice,
+ evolve,
+ where,
+ when,
+ identity,
+ 'return': identity,
+}
diff --git a/src/deps/fp/hasInMatching.js b/src/deps/fp/hasInMatching.js
new file mode 100644
index 0000000..d8b4d49
--- /dev/null
+++ b/src/deps/fp/hasInMatching.js
@@ -0,0 +1,34 @@
+const curry = require('../fp/curry')
+const hasIn = require('../is/in')
+
+/**
+ * @desc isIn + hasIn ...and also allows a predicate/matcher/specification
+ * @memberOf is
+ * @memberOf fp
+ * @since 5.0.0-beta.4
+ *
+ * @param {Object} predicate predicate match the property against this
+ * @param {Object} obj object to check
+ * @param {any} prop property to check in object
+ * @return {boolean} obj[prop] hasIn & satisfies
+ *
+ * @TODO surely would be better with focusing on a prop, then applying predicate, lense? :s
+ * @TODO is it better in fp/ or is/ ? needs some definitions
+ *
+ * @see https://github.com/ramda/ramda/blob/master/src/propOr.js
+ * @extends hasIn
+ * @extends isNull
+ * @extends isIn
+ *
+ * @example
+ *
+ * hasIn({}, 'eh') //=> false
+ * hasIn(null, 'eh') //=> false
+ * hasIn({eh: true}, 'eh') //=> true
+ *
+ */
+function hasInMatching(predicate, obj, prop) {
+ return hasIn(obj, prop) && predicate(obj[prop])
+}
+
+module.exports = curry(3, hasInMatching)
diff --git a/src/deps/fp/identity.js b/src/deps/fp/identity.js
new file mode 100644
index 0000000..fa1395d
--- /dev/null
+++ b/src/deps/fp/identity.js
@@ -0,0 +1,45 @@
+/**
+ * Returns whatever was passed in, thus named return
+ *
+ * @memberOf fp
+ * @since 3.0.0
+ * @version 5.0.0-beta.7 <- renamed identity for standards
+ * @version 5.0.0-beta.6 <- moved out into a function
+ * @version 2.0.0 <- was named `flipReturn`
+ *
+ * @name identity
+ * @alias return
+ * @alias inputOutput
+ * @alias sameInSameOut
+ * @alias io
+ *
+ * @param {*} value The value to return
+ * @return {*} always `value`
+ *
+ * @tests fp/identity
+ *
+ * @NOTE lodash has fn in `tests` that does the same named identity, maybe in /fp too
+ *
+ * {@link https://github.com/jashkenas/underscore/blob/master/underscore.js#L1395 underscore-identity}
+ * {@link https://github.com/medikoo/es5-ext/blob/master/function/identity.js es5-ext-identity}
+ * {@link https://github.com/ramda/ramda/blob/master/src/identity.js ramda-identity}
+ * @see {@link underscore-identity}
+ * @see {@link ramda-identity}
+ * @see {@link es5-ext-identity}
+ *
+ * @func
+ * @category Function
+ * @sig a -> (* -> a)
+ *
+ * @types fp
+ * @tests fp/return
+ *
+ * @example
+ *
+ * var t = identity(1)
+ * t //=> 1
+ *
+ */
+module.exports = function identity(value) {
+ return value
+}
diff --git a/src/deps/fp/includesCount.js b/src/deps/fp/includesCount.js
new file mode 100644
index 0000000..083d8cb
--- /dev/null
+++ b/src/deps/fp/includesCount.js
@@ -0,0 +1,65 @@
+const EMPTY_ARRAY = require('../native/EMPTY_ARRAY')
+const isArray = require('../is/array')
+const isString = require('../is/stringPrimitive')
+const toRegExp = require('../cast/toRegExp')
+const toFunction = require('../cast/toFunction')
+const pipe = require('../fp/pipe')
+const curry = require('../fp/curry')
+const invoke = require('../fp/invoke')
+const lengthMinusOne = require('../util/lengthMinusOne')
+const split = require('../string/split')
+
+// @TODO could have `method` for curring with .flip .invoke
+// const filter = invoke('_', 'filter')
+
+/**
+ * @desc getIncludesCount, how many times a needle occurrs in a haystack
+ *
+ * @since 5.0.0-beta.4
+ * @alias occurrs
+ * @alias getIncludesCount
+ *
+ * @curried 2
+ *
+ * @param {string | Array} haystack haystack to look in
+ * @param {string | Matchable} needle needle to find
+ * @return {number} occurrs/includes times/count
+ *
+ * {@link https://github.com/ramda/ramda/blob/master/src/countBy.js ramda-count-by}
+ * {@link https://github.com/jashkenas/underscore/blob/master/underscore.js#L459 underscore-count-by}
+ * {@link https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf#Finding_all_the_occurrences_of_an_element mozilla-array-occurrences}
+ * {@link https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/String/indexOf#Using_indexOf()_to_count_occurrences_of_a_letter_in_a_string mozilla-occurrences}
+ * @see {@link mozilla-occurrences}
+ * @see {@link mozilla-array-occurrences}
+ * @see {@link underscore-count-by}
+ * @see {@link ramda-count-by}
+ *
+ * @example
+ *
+ * getIncludesCount('1 00 1', '1') //=> 2
+ * getIncludesCount([1, 1, 0, 0], 1) //=> 2
+ * getIncludesCount([0], 1) //=> 0
+ * getIncludesCount('', 1) //=> 0
+ * getIncludesCount(null, 1) //=> 0
+ *
+ */
+function getIncludesCount(haystack, needle) {
+ if (isString(haystack)) {
+ // return haystack.split(needle)
+ return split(haystack, needle)
+ }
+ else if (isArray(haystack)) {
+ // @TODO this disables ternary ability
+ // const matcher = toRegExp(needle).test
+ // return haystack.filter(toRegExp(needle))
+ return haystack.filter(toFunction(toRegExp(needle)))
+ }
+ // may not be needed...
+ else {
+ return EMPTY_ARRAY
+ }
+}
+
+// curry for 2 args, pipe result through to .length - 1
+const getIncludesThenLength = pipe(getIncludesCount, lengthMinusOne)
+module.exports = curry(2, getIncludesThenLength)
diff --git a/src/deps/fp/index.js b/src/deps/fp/index.js
new file mode 100644
index 0000000..d135135
--- /dev/null
+++ b/src/deps/fp/index.js
@@ -0,0 +1,3 @@
+/* istanbul ignore next: @docblocks @exports */
+
+module.exports = require('./fp.js')
diff --git a/src/deps/fp/invertObjKeyVal.js b/src/deps/fp/invertObjKeyVal.js
new file mode 100644
index 0000000..319eed0
--- /dev/null
+++ b/src/deps/fp/invertObjKeyVal.js
@@ -0,0 +1,72 @@
+const keys = require('../util/keysObjOrArray')
+const length = require('../util/length')
+const curry = require('./curry')
+
+/**
+ * - Returns a new object with the keys of the given object as values, and the
+ * values of the given object, which are coerced to strings, as keys. Note
+ * that the last key found is preferred when handling the same value.
+ * - Creates an object composed of the inverted keys and values of `object`.
+ * If `object` contains duplicate values, subsequent values overwrite
+ * property assignments of previous values.
+ *
+ * @memberOf fp
+ * @since 5.0.0
+ * @fork v0.9.0
+ *
+ * @param {Object} obj The object or array to invert
+ * @return {Object} out A new object
+ *
+ * @func
+ * @category Object
+ * @sig {s: x} -> {x: s}
+ *
+ * {@link https://github.com/jashkenas/underscore/blob/master/underscore.js#L1048 underscore-invert}
+ * {@link https://github.com/kesla/node-invert-object invert-obj-npm}
+ * {@link https://github.com/lodash/lodash/blob/master/invert.js lodash-invert}
+ * {@link https://github.com/ramda/ramda/blob/master/src/invert.js ramda-invert}
+ * {@link https://github.com/ramda/ramda/blob/master/test/invertObj.js ramda-invertobj}
+ * @see {@link ramda-invertobj}
+ * @see {@link ramda-invert}
+ * @see {@link lodash-invert}
+ * @see {@link invert-obj-npm}
+ * @see {@link underscore-invert}
+ *
+ * @example
+ *
+ * const obj = { 'a': 1, 'b': 2, 'c': 1 }
+ *
+ * invert(obj)
+ * //=> { '1': 'c', '2': 'b' }
+ *
+ * @example
+ *
+ * var raceResults = {
+ * first: 'alice',
+ * second: 'jake'
+ * }
+ * invertObj(raceResults)
+ * //=> { 'alice': 'first', 'jake':'second' }
+ *
+ * // Alternatively:
+ * var raceResults = ['alice', 'jake']
+ * invertObj(raceResults)
+ * //=> { 'alice': '0', 'jake':'1' }
+ *
+ */
+module.exports = curry(1, function invertObj(obj) {
+ const props = keys(obj)
+ const out = {}
+ let index = 0
+
+ while (index < length(props)) {
+ const key = props[index]
+
+ // value = key
+ out[obj[key]] = key
+
+ index++
+ }
+
+ return out
+})
diff --git a/src/deps/fp/invoke.js b/src/deps/fp/invoke.js
new file mode 100644
index 0000000..87b5054
--- /dev/null
+++ b/src/deps/fp/invoke.js
@@ -0,0 +1,80 @@
+/* eslint consistent-return: "OFF" */
+
+const curry = require('../fp/curry')
+const hasIn = require('../is/hasIn')
+const isFunction = require('../is/function')
+
+/**
+ * Creates a function that invokes the method at `path` of a given object.
+ * Any additional arguments are provided to the invoked method.
+ *
+ * @name invoke
+ * @alias method
+ * @alias callMethod
+ * @curried 3
+ *
+ * @NOTE basically this is `invoker` but not curried
+ *
+ * @since 5.0.0-beta.4
+ * @lodash 3.7.0
+ * @category Util
+ *
+ * @param {Array|string} path The path of the method to invoke.
+ * @param {Array} [args] The arguments to invoke the method with.
+ * @returns {Function} Returns the new invoker function.
+ *
+ * @see https://github.com/emberjs/ember.js/blob/master/packages/ember-utils/lib/invoke.js
+ * @see https://github.com/wycats/handlebars.js/blob/master/lib/handlebars/runtime.js#L38
+ * @see https://github.com/lodash/lodash/blob/master/method.js
+ *
+ * @example
+ *
+ * const objects = [
+ * { 'a': { 'b': () => 2 } },
+ * { 'a': { 'b': () => 1 } }
+ * ]
+ *
+ * map(objects, method('a.b'))
+ * //=> [2, 1]
+ *
+ * map(objects, method(['a', 'b']))
+ * //=> [2, 1]
+ *
+ */
+
+/**
+ * @desc call a method when it exists
+ * @since 5.0.0-beta.4
+ * @memberOf fp
+ * @symb 📞
+ *
+ * @param {*} x object
+ * @param {*} key property with method
+ * @param {*} args arguments
+ * @return {*}
+ *
+ * @TODO add `path` calling, fallback to noop
+ * @see is/hasIn
+ *
+ * {@link https://github.com/jashkenas/underscore/blob/master/underscore.js#L294 underscore-invoke}
+ * {@link https://github.com/lodash/lodash/blob/master/invoke.js lodash-invoke}
+ * @see {@link lodash-invoke}
+ * @see {@link underscore-invoke}
+ *
+ * @example
+ *
+ * var obj = {eh: console.log}
+ * invoke(obj, 'eh', 'eh!')
+ * //=> console.log('eh!')
+ *
+ * var getTag = invoke(Object.prototype.toString, 'call')
+ * getTag([])
+ * //=> '[object Array]'
+ *
+ */
+function invoke(x, key, args) {
+ if (hasIn(x, key) && isFunction(x[key])) return x[key](args)
+ // else return void 0
+}
+
+module.exports = curry(3, invoke)
diff --git a/src/deps/fp/invoker.js b/src/deps/fp/invoker.js
new file mode 100644
index 0000000..ba683ef
--- /dev/null
+++ b/src/deps/fp/invoker.js
@@ -0,0 +1,78 @@
+const argumentor = require('../cast/argumentor')
+const slice = require('../native/arraySlice')
+const isNill = require('../is/nullOrUndefined')
+const isFunction = require('../is/function')
+const hasIn = require('../is/hasIn')
+const curry = require('./curry')
+
+/**
+ * @desc simple desc:
+ * - pass in numberOfArgs & methodName
+ * - when the function is called, with 1 more arg than the number of args you gave
+ * it uses that as
+ * // arguments 0-numberOfArgs...
+ * `leftover = arguments.slice(0, numberOfArgs)`
+ * `target[numberOfArgs][methodName](leftover)`
+ * longer desc:
+ * - Turns a named method with a specified arity into a function that can be
+ * called directly supplied with arguments and a target object.
+ * - The returned function is curried and accepts `arity + 1` parameters where
+ * the final parameter is the target object.
+ *
+ * @since 5.0.0-beta.6
+ * @NOTE has safety and returns `undefined` when there is no method for the function
+ * @TODO add the `safety` to debugRecord
+ *
+ * @func
+ * @name invoker
+ * @memberOf fp
+ * @ramda v0.1.0
+ * @category Function
+ * @sig Number -> String -> (a -> b -> ... -> n -> Object -> *)
+ *
+ * @param {Number} arity Number of arguments the returned function should take
+ * before the target object.
+ * @param {String} method Name of the method to call.
+ * @return {Function} A new curried function.
+ *
+ * {@link https://github.com/jashkenas/underscore/blob/master/underscore.js#L294 underscore-invoke}
+ * {@link https://github.com/ramda/ramda/blob/master/src/invoker.js ramda-invoker}
+ * @see {@link underscore-invoker}
+ * @see {@link ramda-invoker}
+ * @see fp/construct
+ *
+ * @symb invoker(0, 'method')(o) = o['method']()
+ * @symb invoker(1, 'method')(a, o) = o['method'](a)
+ * @symb invoker(2, 'method')(a, b, o) = o['method'](a, b)
+ *
+ * @example
+ *
+ * const sliceFrom = invoker(1, 'slice');
+ * sliceFrom(6, 'abcdefghijklm'); //=> 'ghijklm'
+ *
+ * const sliceFrom6 = invoker(2, 'slice')(6);
+ * sliceFrom6(8, 'abcdefghijklm'); //=> 'gh'
+ *
+ */
+module.exports = curry(2, function invoker(arity, method) {
+ return curry(arity + 1, function() {
+ const args = argumentor.apply(null, arguments)
+ const target = args[arity]
+
+ // !isNill(target) && isFunction(target[method])
+ // if (hasIn(target, method)) {
+ if (hasIn(target, method) && isFunction(target[method])) {
+ return target[method]
+ .apply(
+ target
+ .apply(target, args
+ .slice(0, arity))
+ )
+ }
+ else {
+ return undefined
+ }
+
+ // throw new TypeError(toString(target) + ' does not have a method named "' + method + '"')
+ })
+})
diff --git a/src/deps/fp/isPlaceholder.js b/src/deps/fp/isPlaceholder.js
new file mode 100644
index 0000000..33d32e6
--- /dev/null
+++ b/src/deps/fp/isPlaceholder.js
@@ -0,0 +1,3 @@
+module.exports = function _isPlaceholder(x) {
+ return x === '_'
+}
diff --git a/src/deps/fp/last.js b/src/deps/fp/last.js
new file mode 100644
index 0000000..6de1349
--- /dev/null
+++ b/src/deps/fp/last.js
@@ -0,0 +1,39 @@
+const isIndexable = require('../is/indexable')
+const lastIndex = require('./lastIndex')
+
+/**
+ * Returns the last element of the given list or string.
+ *
+ * @func
+ * @memberOf fp
+ * @since 5.0.0-beta.2
+ *
+ * @param {*} x list to get last index of
+ * @return {*}
+ *
+ * @tests fp/last
+ *
+ * @ramda v0.1.4
+ * @category List
+ * @sig [a] -> a | Undefined
+ * @sig String -> String
+ *
+ * @see R.init, R.head, R.tail
+ * @extends deps/fp/lastIndex
+ *
+ * {@link https://github.com/jashkenas/underscore/blob/master/underscore.js#L507 underscore-last}
+ * @see {@link underscore-last}
+ *
+ * @types fp
+ * @tests fp/*
+ *
+ * @example
+ *
+ * last(['fi', 'fo', 'fum']); //=> 'fum'
+ * last([]); //=> undefined
+ *
+ * last('abc'); //=> 'c'
+ * last(''); //=> ''
+ *
+ */
+module.exports = x => (isIndexable(x) ? x[lastIndex(x)] : undefined)
diff --git a/src/deps/fp/lastIndex.js b/src/deps/fp/lastIndex.js
new file mode 100644
index 0000000..11dbb0b
--- /dev/null
+++ b/src/deps/fp/lastIndex.js
@@ -0,0 +1,52 @@
+const ObjectKeys = require('../util/keys')
+const lengthMinusOne = require('../util/lengthMinusOne')
+const isArray = require('../is/array')
+const isObj = require('../is/objNotNull')
+const isString = require('../is/stringPrimitive')
+
+/**
+ * @desc get last index in a list
+ * @since 5.0.0-beta.2
+ * @memberOf fp
+ *
+ * @name lastIndex
+ * @alias findLastIndex
+ *
+ * @param {Array | Object | string | *} x item to find the last index of
+ * @return {number|string|*} last index, usually number/string
+ *
+ * @tests fp/last
+ *
+ * @TODO could have support for map...
+ * @NOTE works for strings too eh
+ * @extends deps/util/keysObjOrArray
+ *
+ * {@link https://github.com/jashkenas/underscore/blob/master/underscore.js#L667 underscore-last-index}
+ * {@link https://github.com/lodash/lodash/tree/npm-packages/lodash.findlastindex lodash-find-last-index}
+ * {@link https://github.com/ramda/ramda/tree/v0.24.1/src/findLastIndex.js ramda-find-last-index}
+ * @see {@link ramda-find-last-index}
+ * @see {@link lodash-find-last-index}
+ * @see {@link underscore-last-index}
+ * @see deps/fp/last
+ *
+ * @example
+ *
+ * lastIndex([0, 'one']) //=> 1
+ * lastIndex({one: 1, two: 2}) //=> 'two'
+ *
+ */
+function lastIndex(x) {
+ if (isString(x) || isArray(x)) return lengthMinusOne(x)
+ else if (isObj(x)) return ObjectKeys(x).pop()
+ else return -1
+
+ // @TODO if (isString(x)) return x.lastIndexOf()
+ // else if (isObj(x)) return toNumber(lengthMinusOne(keys(x)))
+ // else if (isObj(x)) return lastIndex(ObjectKeys(x))
+ // const xKeys = isArray(x) ? x : keys(x)
+ // return xKeys[lengthMinusOne(xKeys)]
+ // const last = xKeys[xKeys.length - 1]
+ // return last
+}
+
+module.exports = lastIndex
diff --git a/src/deps/fp/nth.js b/src/deps/fp/nth.js
new file mode 100644
index 0000000..bcada01
--- /dev/null
+++ b/src/deps/fp/nth.js
@@ -0,0 +1,78 @@
+const curry = require('../fp/curry')
+const isString = require('../is/string')
+
+/**
+ * Gets the element at index `n` of `array`. If `n` is negative, the nth
+ * element from the end is returned.
+ *
+ * @memberOf fp
+ * @since 5.0.0-beta.1
+ *
+ * @param {Array|Object|String} array The array|obj|string to query.
+ * @param {number} [n=0] The index of the element to return.
+ * @returns {*} Returns the nth element of `array`.
+ *
+ * @tests fp/arity
+ *
+ * @fork 4.11.0
+ * @category Array
+ *
+ * @name nth
+ * @alias at
+ * @alias atIndex
+ * @alias atPosition
+ *
+ * {@link http://documentcloud.github.io/underscore-contrib/#nth underscore-contrib-nth}
+ * {@link https://github.com/lodash/lodash/blob/master/.internal/baseAt.js lodash-base-at}
+ * {@link https://github.com/lodash/lodash/blob/master/at.js lodash-at}
+ * {@link https://github.com/ramda/ramda/blob/v0.24.1/src/nth.js ramda-nth}
+ *
+ * @see {@link ramda-nth}
+ * @see {@link lodash-base-at}
+ * @see {@link lodash-at}
+ * @see {@link underscore-contrib-nth}
+ *
+ * @example
+ *
+ * const array = ['a', 'b', 'c', 'd']
+ *
+ * nth(array, 1)
+ * //=> 'b'
+ *
+ * nth(array, -2)
+ * //=> 'c'
+ *
+ */
+function nth(list, offset) {
+ // isNill(array) return
+
+ // @TODO from 0
+ const index = offset < 0 ? list.length + offset : offset
+ // return list[index]
+ return isString(list) ? list.charAt(index) : list[index]
+}
+
+module.exports = curry(2, nth)
+
+/**
+ * @ignore
+ * The base implementation of `at` without support for individual paths.
+ *
+ * @private
+ * @param {Array|Object} object The object to iterate over.
+ * @param {string[]} paths The property paths to pick.
+ * @returns {Array} Returns the picked elements.
+ */
+// const isIndex = require('./isValidIndex')
+// const isNill = require('../is/nill')
+// function baseAt(object, paths) {
+// let index = -1
+// const length = paths.length
+// const result = new Array(length)
+// const skip = object == null
+//
+// while (++index < length) {
+// result[index] = skip ? undefined : get(object, paths[index])
+// }
+// return result
+// }
diff --git a/src/deps/fp/nthArg.js b/src/deps/fp/nthArg.js
new file mode 100644
index 0000000..12bdb4b
--- /dev/null
+++ b/src/deps/fp/nthArg.js
@@ -0,0 +1,40 @@
+const argumentor = require('../cast/argumentsToArray')
+const curryN = require('./curry')
+const nth = require('./nth')
+
+/**
+ * @desc Returns a function which returns its nth argument.
+ * @memberOf fp
+ * @since 5.0.0-beta.6
+ *
+ * @param {Number} n arg to get
+ * @return {Function}
+ * @see deps/argumentor
+ *
+ * @curried 1
+ * @tests fp/nthArg
+ *
+ * @func
+ * @fork v0.9.0
+ * @category Function
+ * @sig Number -> *... -> *
+ *
+ * @symb nthArg(-1)(a, b, c) = c
+ * @symb nthArg(0)(a, b, c) = a
+ * @symb nthArg(1)(a, b, c) = b
+ *
+ * @example
+ *
+ * nthArg(1)('a', 'b', 'c') //=> 'b'
+ * nthArg(-1)('a', 'b', 'c') //=> 'c'
+ *
+ */
+const nthArg = function(n) {
+ const arity = n < 0 ? 1 : n + 1
+ return curryN(arity, function() {
+ // return nth(n, argumentor.apply(null, arguments))
+ return nth(argumentor.apply(null, arguments), n)
+ })
+}
+
+module.exports = nthArg
diff --git a/src/deps/fp/path.js b/src/deps/fp/path.js
new file mode 100644
index 0000000..8b918bd
--- /dev/null
+++ b/src/deps/fp/path.js
@@ -0,0 +1,39 @@
+const isNil = require('../is/nullOrUndefined')
+const curry = require('./curry')
+
+/**
+ * @desc retrieve the value at a given path.
+ * @since v5.0.0
+ * @memberOf fp
+ * @curried 2
+ *
+ * @param {Array} path The path to use.
+ * @param {Object} obj The object to retrieve the nested property from.
+ * @return {*} The data at `path`.
+ *
+ * @func
+ * @category Object
+ * @typedefn Idx = String | Int
+ * @sig [Idx] -> {a} -> a | Undefined
+ *
+ * {@link https://github.com/ramda/ramda/blob/master/src/path.js ramda-path}
+ * @see {@link ramda-path}
+ * @see fp/prop
+ *
+ * @example
+ *
+ * path(['a', 'b'], {a: {b: 2}}); //=> 2
+ * path(['a', 'b'], {c: {b: 2}}); //=> undefined
+ *
+ */
+module.exports = curry(2, function path(paths, obj) {
+ let value = obj
+ let index = 0
+
+ while (index < paths.length) {
+ if (isNil(value)) return
+ value = value[paths[index++]]
+ }
+
+ return value
+})
diff --git a/src/deps/fp/pipe.js b/src/deps/fp/pipe.js
new file mode 100644
index 0000000..8d3fd68
--- /dev/null
+++ b/src/deps/fp/pipe.js
@@ -0,0 +1,56 @@
+const isArray = require('../is/array')
+const argumentor = require('../cast/argumentor')
+const pipeTwo = require('./pipeTwo')
+
+/**
+ * Performs left-to-right function composition. The leftmost function may have
+ * any arity; the remaining functions must be unary.
+ * In some libraries this function is named `sequence`.
+ *
+ * @icon |
+ * @func
+ * @memberOf fp
+ * @since v5.0.0
+ * @category Function
+ * @sig (((a, b, ..., n) -> o), (o -> p), ..., (x -> y), (y -> z)) -> ((a, b, ..., n) -> z)
+ * @symb pipe(f, g, h)(a, b) = h(g(f(a, b)))
+ * @extends fp/pipeTwo
+ *
+ * @param {Function} first function first
+ * @param {...Function} rest function next
+ * @return {Function}
+ *
+ * @see https://github.com/reactjs/redux/blob/master/src/compose.js
+ * @see https://github.com/ramda/ramda/blob/master/src/compose.js
+ * @see https://github.com/ramda/ramda/blob/master/src/pipe.js
+ * @see https://github.com/ramda/ramda/blob/master/test/pipe.js
+ *
+ * @types fp
+ * @tests fp/pipe
+ *
+ * @example
+ *
+ * var f = R.pipe(Math.pow, R.negate, R.inc);
+ * f(3, 4); // -(3^4) + 1
+ *
+ * @example
+ *
+ * var x = v => v + 'x'
+ * var y = v => v + 'y'
+ * var z = v => v + 'z'
+ *
+ * const xyz = pipe(x, y, z)
+ * /// starts with w, adds x, then y, then z
+ * const wxyz = xyz('w')
+ * //=> 'wxyz'
+ *
+ */
+module.exports = function pipe(first) {
+ // @TODO: could move into pipeArray
+ // could start from first, second? etc?
+ // (isArray(first) ? first : argumentor.apply(null, arguments))
+ let args = argumentor.apply(null, arguments).slice(1).reduce(pipeTwo)
+ // .reduce((previous, next) => pipeTwo(previous, next))
+
+ return pipeTwo(first, args)
+}
diff --git a/src/deps/fp/pipeTwo.js b/src/deps/fp/pipeTwo.js
new file mode 100644
index 0000000..1e050bd
--- /dev/null
+++ b/src/deps/fp/pipeTwo.js
@@ -0,0 +1,32 @@
+/**
+ * Performs left-to-right function composition. ONLY CAN PIPE 2 ARGUMENTS
+ *
+ * @NOTE The result of pipe is not automatically curried.
+ * @NOTE This is a variation, is the internal version with only 2 functions, for now
+ *
+ * @func
+ * @memberOf fp
+ * @since v5.0.0
+ * @category Function
+ *
+ * @param {...Function} f function first
+ * @param {...Function} g function next
+ * @return {Function}
+ *
+ * @see https://github.com/ramda/ramda/blob/master/src/pipe.js
+ * @see https://github.com/ramda/ramda/blob/master/test/pipe.js
+ *
+ * @types fp
+ * @tests fp/pipe
+ *
+ * @example
+ *
+ * var f = R.pipe(Math.pow, R.negate);
+ * f(3, 4); // -(3^4) + 1
+ *
+ */
+module.exports = function _pipe(f, g) {
+ return function() {
+ return g.call(this, f.apply(this, arguments))
+ }
+}
diff --git a/src/deps/fp/preferExistingMethod.js b/src/deps/fp/preferExistingMethod.js
new file mode 100644
index 0000000..b15e434
--- /dev/null
+++ b/src/deps/fp/preferExistingMethod.js
@@ -0,0 +1,54 @@
+const isArray = require('../is/array')
+const isFunction = require('../is/function')
+const argumentor = require('../cast/argumentor')
+
+/**
+ * This checks whether a function has a [methodname] function. If it isn't an
+ * array it will execute that function otherwise it will default to the internal
+ * implementation.
+ *
+ * @memberOf fp
+ * @since 5.0.0-beta.5
+ *
+ * @name preferExistingMethod
+ * @alias useMethodIfExists
+ * @alias _checkForMethod
+ *
+ * @param {Function} fn internal implemtation
+ * @param {String} methodname property to check for a custom implementation
+ * @return {Object} Whatever the return value of the method is.
+ *
+ * {@link https://github.com/ramda/ramda/blob/master/src/internal/_checkForMethod.js ramda-check-for-method}
+ * @see {@link ramda-check-for-method}
+ *
+ * @TODO arity
+ *
+ * @example
+ *
+ * const fallback = (list, index) => Array.prototype.slice.call(list, index)
+ * const slice = useMethodIfExists('slice', fallback)
+ *
+ * const list = ['zero', 'one']
+ * const sliced = (list, 0)
+ * /// uses list.slice(0)
+ * //=> 0
+ *
+ */
+module.exports = function preferExistingMethod(methodname, fn) {
+ return function() {
+ const length = arguments.length
+ if (length === 0) {
+ return fn()
+ }
+ else {
+ const obj = arguments[length - 1]
+ return (isArray(obj) || !isFunction(obj[methodname]))
+ ? fn.apply(this, arguments)
+ : obj[methodname]
+ .apply(
+ obj,
+ argumentor.apply(null, arguments).slice(length - 1)
+ )
+ }
+ }
+}
diff --git a/src/deps/fp/prop.js b/src/deps/fp/prop.js
new file mode 100644
index 0000000..b138849
--- /dev/null
+++ b/src/deps/fp/prop.js
@@ -0,0 +1,35 @@
+/* eslint no-confusing-arrow: "OFF" */
+const isNil = require('../is/nullOrUndefined')
+const curry = require('./curry')
+
+/**
+ * Returns a function that when supplied an object returns the indicated
+ * property of that object, if it exists.
+ *
+ * @version 3.0.0 <- checks isNill
+ * @since v5.0.0
+ * @memberOf fp
+ *
+ * @param {String} key The property name
+ * @param {Object} obj The object to query
+ * @return {*} The value at `obj[key]`.
+ *
+ * {@link https://github.com/ramda/ramda/blob/master/src/prop.js ramda-prop}
+ * @see {@link ramda-prop}
+ *
+ * @TODO could toKey here
+ *
+ * @func
+ * @category Object
+ * @sig s -> {s: a} -> a | Undefined
+ *
+ * @types fp
+ * @tests fp/prop
+ *
+ * @example
+ *
+ * prop('x', {x: 100}); //=> 100
+ * prop('x', {}); //=> undefined
+ *
+ */
+module.exports = curry(2, (key, obj) => isNil(obj) ? undefined : obj[key])
diff --git a/src/deps/fp/propSatisfies.js b/src/deps/fp/propSatisfies.js
new file mode 100644
index 0000000..f894a68
--- /dev/null
+++ b/src/deps/fp/propSatisfies.js
@@ -0,0 +1,9 @@
+const curry = require('../fp/curry')
+const hasIn = require('../is/hasIn')
+
+// 5.0.0-beta.7
+module.exports = curry(3, function _propSatisfies(propertyPath, fnIs, obj) {
+ return hasIn(obj, propertyPath)
+ ? fnIs(obj[propertyPath])
+ : false
+})
diff --git a/src/deps/fp/remove.js b/src/deps/fp/remove.js
new file mode 100644
index 0000000..bd25be0
--- /dev/null
+++ b/src/deps/fp/remove.js
@@ -0,0 +1,21 @@
+const isObjNotNull = require('../is/objNotNull')
+const isArray = require('../is/array')
+const curry = require('./curry')
+
+/**
+ * @desc removes from object or array using `.splice` or `delete`
+ * @name remove
+ * @since 5.0.0-beta.5
+ * @memberOf fp
+ * @curried 2
+ *
+ * @param {Object | Array | *} obj object
+ * @param {Primitive | *} key index/property/key to delete from obj
+ * @return {void} only deletes
+ *
+ * @TODO remove with index, or with value
+ */
+module.exports = curry(2, function removeFromArrayOrObj(obj, key) {
+ if (isArray(obj)) obj.splice(key, 1)
+ else if (isObjNotNull(obj)) delete obj[key]
+})
diff --git a/src/deps/fp/repeat.js b/src/deps/fp/repeat.js
new file mode 100644
index 0000000..fce6d14
--- /dev/null
+++ b/src/deps/fp/repeat.js
@@ -0,0 +1,38 @@
+const curry = require('./curry')
+const always = require('./always')
+const times = require('./times')
+
+/**
+ * Returns a fixed list of size `n` containing a specified identical value.
+ * @since 5.0.0-beta.7
+ * @memberOf fp
+ *
+ * @param {*} value The value to repeat.
+ * @param {Number} n The desired size of the output list.
+ * @return {Array} A new array containing `n` `value`s.
+ *
+ * @TODO what about string.repeat?!
+ *
+ * @func
+ * @fork v0.1.1
+ * @category List
+ * @sig a -> n -> [a]
+ *
+ * @see fp/times
+ *
+ * @symb repeat(a, 0) = []
+ * @symb repeat(a, 1) = [a]
+ * @symb repeat(a, 2) = [a, a]
+ *
+ * @example
+ *
+ * repeat('hi', 5); //=> ['hi', 'hi', 'hi', 'hi', 'hi']
+ *
+ * var obj = {};
+ * var repeatedObjs = repeat(obj, 5); //=> [{}, {}, {}, {}, {}]
+ * repeatedObjs[0] === repeatedObjs[1]; //=> true
+ *
+ */
+module.exports = curry(2, function repeat(value, n) {
+ return times(n, always(value))
+})
diff --git a/src/deps/fp/replace.js b/src/deps/fp/replace.js
new file mode 100644
index 0000000..9cc0ef8
--- /dev/null
+++ b/src/deps/fp/replace.js
@@ -0,0 +1,36 @@
+const curry = require('./curry')
+
+/**
+ * Replace a substring or regex match in a string with a replacement.
+ *
+ * @func
+ * @memberOf fp
+ * @since v5.0.0
+ * @category String
+ * @sig RegExp|String -> String -> String -> String
+ *
+ * @param {RegExp|String} pattern A regular expression or a substring to match.
+ * @param {String} replacement The string to replace the matches with.
+ * @param {String} str The String to do the search and replacement in.
+ * @return {String} The result.
+ *
+ * @types fp
+ * @tests fp/replace
+ *
+ * {@link https://github.com/ramda/ramda/blob/master/src/replace.js ramda-replace}
+ * {@link https://github.com/lodash/lodash/blob/master/replace.js lodash-replace}
+ * @see {@link ramda-replace}
+ * @see {@link lodash-replace}
+ *
+ * @example
+ *
+ * replace('foo', 'bar', 'foo foo foo'); //=> 'bar foo foo'
+ * replace(/foo/, 'bar', 'foo foo foo'); //=> 'bar foo foo'
+ *
+ * // Use the "g" (global) flag to replace all occurrences:
+ * replace(/foo/g, 'bar', 'foo foo foo'); //=> 'bar bar bar'
+ *
+ */
+module.exports = curry(3, function replace(pattern, replacement, str) {
+ return str.replace(pattern, replacement)
+})
diff --git a/src/deps/fp/replaceWith.js b/src/deps/fp/replaceWith.js
new file mode 100644
index 0000000..f194436
--- /dev/null
+++ b/src/deps/fp/replaceWith.js
@@ -0,0 +1,40 @@
+const keys = require('../util/keysObjOrArray')
+const curry = require('./curry')
+const pipe = require('./pipe')
+const replace = require('./replace')
+
+/**
+ * @desc replace an array of patterns, or an object with {pattern: replacement}
+ * @since v5.0.0
+ * @memberOf fp
+ * @category String
+ *
+ * @param {RegExp|String} pattern A regular expression or a substring to match.
+ * @param {String} replacement The string to replace the matches with.
+ * @param {String} str The String to do the search and replacement in.
+ * @return {String} The result.
+ *
+ * @curried
+ * @func
+ * @name replaceWith
+ *
+ * @TODO could use `toTester`/`toMatcher` on keys
+ * @TODO might also be using a map
+ * @TODO need to finish the mapping ones,
+ * @TODO need to externalize some functionality as needed point where
+ * @TODO need to tighten up the .method stuff, fully test
+ *
+ * @example
+ *
+ * const stripEh = replaceWith({'eh': ''})
+ * stripEh('ehs') //=> 's'
+ *
+ */
+const replaceWith = (map, str, castToMatcher = false) => {
+ const replacements = keys(map)
+ .map(key => replace(key, map[key]))
+
+ return pipe.apply(null, replacements)(str)
+}
+
+module.exports = curry(2, replaceWith)
diff --git a/src/deps/fp/reverse.js b/src/deps/fp/reverse.js
new file mode 100644
index 0000000..ebb0c26
--- /dev/null
+++ b/src/deps/fp/reverse.js
@@ -0,0 +1,43 @@
+const slice = require('../native/arraySlice')
+const isString = require('../is/string')
+
+/**
+ * Returns a new list or string with the elements or characters in reverse
+ * order.
+ *
+ * @symb ⬅️
+ * @memberOf fp
+ * @since 5.0.0-beta.5
+ *
+ * @param {Array|String} x (list) string or array to reverse
+ * @return {Array|String}
+ *
+ * @func
+ * @ramda v0.1.0
+ * @category List
+ * @sig [a] -> [a]
+ * @sig String -> String
+ *
+ * {@link https://stackoverflow.com/a/26610963/2855712 stack-overflow-10-ways-to-reverse-string}
+ * {@link https://github.com/ramda/ramda/blob/master/src/reverse.js ramda-reverse}
+ * @see {@link ramda-reverse}
+ * @see {@link stack-overflow-10-ways-to-reverse-string}
+ *
+ * @example
+ *
+ * reverse([1, 2, 3]); //=> [3, 2, 1]
+ * reverse([1, 2]); //=> [2, 1]
+ * reverse([1]); //=> [1]
+ * reverse([]); //=> []
+ *
+ * reverse('abc'); //=> 'cba'
+ * reverse('ab'); //=> 'ba'
+ * reverse('a'); //=> 'a'
+ * reverse(''); //=> ''
+ *
+ */
+module.exports = function reverse(x) {
+ return isString(x)
+ ? x.split('').reverse().join('')
+ : slice.call(x, 0).reverse()
+}
diff --git a/src/deps/fp/slice.js b/src/deps/fp/slice.js
new file mode 100644
index 0000000..f60a3a4
--- /dev/null
+++ b/src/deps/fp/slice.js
@@ -0,0 +1,68 @@
+const isArray = require('../is/array')
+const isUndefined = require('../is/undefined')
+const isString = require('../is/string')
+const from = require('../util/from')
+const arraySlice = require('../native/arraySlice')
+const curry = require('../fp/curry')
+const preferExistingMethod = require('../fp/preferExistingMethod')
+
+const stringSlice = String.prototype.slice
+
+/**
+ * Returns the elements of the given list or string (or object with a `slice`
+ * method) from `fromIndex` (inclusive) to `toIndex` (exclusive).
+ * Dispatches to the `slice` method of the third argument, if present.
+ * @memberOf array
+ * @memberOf string
+ * @memberOf fp
+ * @since 5.0.0-beta.6
+ *
+ * @param {*} list array | string to slice on
+ * @param {Number} fromIndex The start index (inclusive).
+ * @param {Number} toIndex The end index (exclusive).
+ * @return {*}
+ *
+ * @tests fp/slice
+ * @curried 3
+ * @see fp/preferExistingMethod
+ *
+ * @func
+ * @fork v0.1.4
+ * @category List
+ * @sig Number -> Number -> [a] -> [a]
+ * @sig Number -> Number -> String -> String
+ *
+ * {@link https://github.com/lodash/lodash/blob/master/slice.js lodash-slice}
+ * {@link https://github.com/lodash/lodash/blob/master/.internal/castSlice.js lodash-cast-slice}
+ * {@link https://github.com/lodash/lodash/commit/e5e8f35c066c71a04ba584f65acc017d032c0174 lodash-commit-remove-base-slice}
+ * {@link https://github.com/jashkenas/underscore/blob/master/underscore.js#L1650 underscore-slice}
+ * {@link https://github.com/ramda/ramda/blob/master/src/slice.js}
+ * @see {@link ramda-slice}
+ * @see {@link underscore-slice}
+ * @see {@link lodash-commit-remove-base-slice}
+ * @see {@link lodash-cast-slice}
+ * @see {@link lodash-slice}
+ *
+ * @example
+ *
+ * slice(1, 3, ['a', 'b', 'c', 'd']); //=> ['b', 'c']
+ * slice(1, Infinity, ['a', 'b', 'c', 'd']); //=> ['b', 'c', 'd']
+ * slice(0, -1, ['a', 'b', 'c', 'd']); //=> ['a', 'b', 'c']
+ * slice(-3, -1, ['a', 'b', 'c', 'd']); //=> ['b', 'c']
+ * slice(0, 3, 'ramda'); //=> 'ram'
+ *
+ */
+function slice(list, fromIndex, toIndex) {
+ const to = isUndefined(toIndex) ? list.length : toIndex
+ if (isString(list)) return stringSlice.call(list, fromIndex, to)
+
+ // let array = isArray(list) ? list : from(list)
+ let array = list
+ return arraySlice.call(array, fromIndex, to)
+}
+
+// @TODO put in flipped
+//
+
+module.exports = curry(3, preferExistingMethod('slice', slice))
+// module.exports = curry(3, slice)
diff --git a/src/deps/fp/times.js b/src/deps/fp/times.js
new file mode 100644
index 0000000..b3d5395
--- /dev/null
+++ b/src/deps/fp/times.js
@@ -0,0 +1,53 @@
+const curry = require('../fp/curry')
+const toLength = require('../cast/toLength')
+
+/**
+ * - Run a function **n** times.
+ * - Calls an input function `n` times, returning an array containing the results
+ * of those function calls.
+ * - `fn` is passed one argument: The current value of `n`, which begins at `0`
+ * and is gradually incremented to `n - 1`.
+ * - Invokes the iteratee `n` times, returning an array of the results of
+ * each invocation. The iteratee is invoked with one argumentindex).
+ *
+ * @since 5.0.0-beta.1
+ * @memberOf fp
+ * @curried 2
+ *
+ * @NOTE lodash & underscore have `(number, fn)`, ramda has `(fn, number)`
+ *
+ * @param {number} n The number of times to invoke `iteratee`.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @return {Array} Returns the array of results.
+ *
+ * @name times
+ * @fork 0.1.0
+ * @category Util
+ * @category List
+ * @sig (Number -> a) -> Number -> [a]
+ *
+ * {@link https://github.com/lodash/lodash/blob/master/times.js lodash-times}
+ * {@link https://github.com/jashkenas/underscore/blob/master/underscore.js#L1436 underscore-times}
+ * {@link https://github.com/ramda/ramda/blob/master/src/times.js ramda-times}
+ * @see {@link ramda-times}
+ * @see {@link underscore-times}
+ * @see {@link lodash-times}
+ * @see cast/toLength
+ *
+ * @example
+ *
+ * times(3, String)
+ * //=> ['0', '1', '2']
+ *
+ * times(4, () => 0)
+ * //=> [0, 0, 0, 0]
+ *
+ */
+function times(n, iteratee) {
+ n = toLength(n)
+ const result = new Array(Math.max(0, n))
+ for (let i = 0; i < n; i++) result[i] = iteratee(i)
+ return result
+}
+
+module.exports = curry(2, times)
diff --git a/src/deps/fp/when.js b/src/deps/fp/when.js
new file mode 100644
index 0000000..6e53dbb
--- /dev/null
+++ b/src/deps/fp/when.js
@@ -0,0 +1,55 @@
+const isString = require('../is/stringPrimitive')
+const isFunction = require('../is/function')
+const propSatisfies = require('../fp/propSatisfies')
+
+const getIsFunction = propSatisfies('get', isFunction)
+
+/**
+ * @desc when the condition is true,
+ * trueBrancher is called,
+ * else, falseBrancher is called
+ *
+ * @memberOf Chainable
+ * @version 5.0.0 <- moved to fp from class
+ * @version 4.0.0 <- added string-as-has(condition)
+ * @since 2.0.0
+ *
+ * @param {boolean | string} condition when string, checks this.get
+ * @param {Function} [trueBrancher=Function] called when true
+ * @param {Function} [falseBrancher=Function] called when false
+ * @return {Chainable} @chainable
+ *
+ * @tests fp/when
+ *
+ * @example
+ *
+ *
+ * const prod = process.env.NODE_ENV === 'production'
+ * chains.when(prod, c => c.set('prod', true), c => c.set('prod', false))
+ *
+ *
+ */
+module.exports = function when(condition, trueBrancher, falseBrancher) {
+ // truthy condition - could be string
+ if (condition) {
+ // ensure we have functions
+ if (isFunction(trueBrancher)) {
+ // if we have a .get function, and we use a string, use that
+ if (isString(condition) && getIsFunction(this)) {
+ if (this.get(condition)) {
+ trueBrancher(this)
+ }
+ }
+ else {
+ trueBrancher(this)
+ }
+ }
+ }
+ else if (isFunction(falseBrancher)) {
+ // ensure function, on else
+ falseBrancher(this)
+ }
+
+ // chainable
+ return this
+};
diff --git a/src/deps/fp/where.js b/src/deps/fp/where.js
new file mode 100644
index 0000000..f20392c
--- /dev/null
+++ b/src/deps/fp/where.js
@@ -0,0 +1,101 @@
+// const forOwn = require('../loop/each/forOwn')
+const hasOwnProperty = require('../util/hasOwnProperty')
+const hasIn = require('../is/hasIn')
+const isObj = require('../is/obj')
+const isObjPure = require('../is/objPure')
+const isFunction = require('../is/function')
+const isArray = require('../is/array')
+const curry = require('./curry')
+
+/**
+ * Takes a spec object and a test object returns true if the test satisfies
+ * the spec. Each of the spec's own properties must be a predicate function.
+ * Each predicate is applied to the value of the corresponding property of the
+ * test object. `where` returns true if all the predicates return true, false
+ * otherwise.
+ *
+ * `where` is well suited to declaratively expressing constraints for other
+ * functions such as [`filter`](#filter) and [`find`](#find).
+ *
+ * @since 5.0.0-beta.6
+ * @version 5.0.0-beta.9 <- added safety https://github.com/fluents/chain-able/issues/61
+ * @memberOf fp
+ * @curried 2
+ *
+ * @param {Object} spec specification
+ * @param {Object} testObj object to test specification on
+ * @return {Boolean}
+ *
+ * @tests fp/where
+ *
+ * {@link https://github.com/jashkenas/underscore/blob/master/underscore.js#L323 underscore-where}
+ * {@link https://github.com/lodash/lodash/blob/master/.internal/baseConformsTo.js lodash-conformsto}
+ * {@link https://github.com/ramda/ramda/blob/v0.24.1/src/where.js ramda-where}
+ * @see {@link underscore-where}
+ * @see {@link ramda-where}
+ * @see {@link lodash-conformsto}
+ *
+ * @func
+ * @fork v0.1.1
+ * @category Object
+ * @sig {String: (* -> Boolean)} -> {String: *} -> Boolean
+ *
+ * @example
+ *
+ * // pred :: Object -> Boolean
+ * var pred = where({
+ * a: equals('foo'),
+ * b: not(equals('bar')),
+ * x: gt('_', 10),
+ * y: lt('_', 20)
+ * })
+ *
+ * pred({a: 'foo', b: 'xxx', x: 11, y: 19}) //=> true
+ * pred({a: 'xxx', b: 'xxx', x: 11, y: 19}) //=> false
+ * pred({a: 'foo', b: 'bar', x: 11, y: 19}) //=> false
+ * pred({a: 'foo', b: 'xxx', x: 10, y: 19}) //=> false
+ * pred({a: 'foo', b: 'xxx', x: 11, y: 20}) //=> false
+ *
+ */
+module.exports = curry(2, function where(spec, testObj) {
+ // forOwn(spec, (test, prop) => hasOwnProperty(testObj, prop) && !spec[prop](testObj[prop]) })
+
+ /**
+ * cannot really test an object vs a non object, unless spec is a function
+ */
+ if (!isObj(testObj)) {
+ if (isFunction(spec)) return spec(testObj)
+ else return false
+ }
+
+ /* prettier-ignore */
+ for (let prop in spec) {
+ /**
+ * @NOTE we are allowing checks on inherited TESTOBJ,
+ * but not on inherited SPEC
+ *
+ * !hasIn(testObj, prop)
+ */
+ if (!hasOwnProperty(spec, prop)) {
+ // continue
+ }
+ /**
+ * when we have a nested object, recursively check
+ */
+ else if (isObjPure(spec[prop]) || isArray(spec[prop])) {
+ if (!where(spec[prop], testObj[prop])) {
+ return false
+ }
+ }
+ /**
+ * if the test object does not have the same property
+ * or our value in the testObje does not satisfy the specification
+ */
+ else if (!spec[prop](testObj[prop])) {
+ return false
+ }
+ }
+
+ // good to go!
+ return true
+})
diff --git a/src/deps/fp/wrap.js b/src/deps/fp/wrap.js
new file mode 100644
index 0000000..8fbf3a4
--- /dev/null
+++ b/src/deps/fp/wrap.js
@@ -0,0 +1,351 @@
+/** @ignore 🚧 wip */
+
+// const toFunction = require('../cast/toFunction')
+// const forInUnguarded = require('../loop/each/forInUnguarded')
+//
+// function __ehs(args) {
+// this.__eh = 1
+// }
+// function _ehs(args) {
+// __ehs.call(this)
+// this._eh = args
+// }
+//
+// const Ehs = toFunction(_ehs)
+// function ehs(args) {
+// return new _ehs(args)
+// }
+//
+// console.log(new Ehs(0))
+//
+// const copy = x => forInUnguarded(x, (value, key) => x[key] = value)
+//
+// // https://h3manth.com/new/blog/2014/thisarg-in-javascript/
+// // const fpChain = (...chains) => {
+// // function functionContext() {
+// // this.store = new Map()
+// // return this
+// // }
+// // function eh() {
+// // functionContext.call(this, this)
+// // console.log(this)
+// // }
+//
+// // function inherit(Parent, Child) {
+// // const ParentPrototype = Object.getPrototypeOf(Parent)
+// // Object.setPrototypeOf(Child, ParentPrototype)
+// // Chained.prototype = Object.create(ParentPrototype);
+// // Chained.prototype.constructor = Chained
+// // }
+// function _classCallCheck(instance, Constructor) {
+// if (!(instance instanceof Constructor)) {
+// throw new TypeError('Cannot call a class as a function')
+// }
+// }
+//
+// function _possibleConstructorReturn(self, _super) {
+// if (!self) {
+// throw new ReferenceError(
+// 'this hasn\'t been initialised - super() hasn\'t been called'
+// )
+// }
+//
+// const call = _super.call(self)
+// return call && (typeof call === 'object' || typeof call === 'function')
+// ? call
+// : self
+// }
+//
+// function _inherits(subClass, superClass) {
+// if (typeof superClass !== 'function' && superClass !== null) {
+// throw new TypeError(
+// 'Super expression must either be null or a function, not ' +
+// typeof superClass
+// )
+// }
+// subClass.prototype = Object.create(superClass && superClass.prototype, {
+// constructor: {
+// value: subClass,
+// enumerable: false,
+// writable: true,
+// configurable: true,
+// },
+// })
+// if (superClass)
+// Object.setPrototypeOf
+// ? Object.setPrototypeOf(subClass, superClass)
+// : subClass.__proto__ = superClass
+//
+// return function callForConstructor(self) {
+// const call = superClass.call(self)
+// return call && (typeof call === 'object' || typeof call === 'function')
+// ? call
+// : self
+// }
+// }
+//
+// function eh() {
+// console.log('what')
+// this.eh = true
+// // @NOTE this is an example of constructor returning & not using `this`
+// var _this = copy(this)
+// _this._ = 0
+// return _this
+// }
+//
+// const _super = eh
+// const call = _inherits(Chained, _super)
+// function Chained() {
+// // _classCallCheck(this, Chained)
+// // var _this = _super.call(this) || this
+// var _this = call(this, _super)
+//
+// // _super.call(this)
+// _this.ca = true
+// console.log('chained')
+// return _this
+// }
+
+// var Chained = (function(_super) {
+// const call = _inherits(Chained, _super)
+// function Chained() {
+// // _classCallCheck(this, Chained)
+// // var _this = _super.call(this) || this
+// var _this = call(this, _super)
+//
+// // _super.call(this)
+// _this.ca = true
+// console.log('chained')
+// return _this
+// }
+//
+// return Chained
+// // return buble(Chained, _super)
+// })
+// Chained = Chained(eh)
+
+// console.log(new Chained())
+// console.log(protos(Chained), protos(new Chained()))
+// console.log({Chained})
+// console.log(new Chained())
+
+// fpChain([])
+
+// const curry = require('./curry')
+//
+// /**
+// * Returns the first function passed as an argument to the second,
+// * allowing you to adjust arguments, run code before and after, and
+// * conditionally execute the original function.
+// *
+// * @memberOf fp
+// * @since 5.0.0-beta.5
+// *
+// * @param {Function} fn function to wrap
+// * @param {Function} wrap function that wraps `fn`
+// *
+// * @symb 🍬
+// * @name wrap
+// *
+// * {@link http://underscorejs.org/#wrap underscore-wrap}
+// * {@link https://github.com/jashkenas/underscore/blob/master/underscore.js#L909 underscore-src-wrap}
+// * @see {@link underscore-wrap}
+// * @see {@link underscore-src-wrap}
+// *
+// * @example
+// *
+// * var hello = function(name) { return "hello: " + name; };
+// * hello = wrap(hello, function(func) {
+// * return "before, " + func("moe") + ", after";
+// * })
+// *
+// * hello()
+// * //=> 'before, hello: moe, after'
+// *
+// */
+// function wrap(fn, wrapper) {
+// // this just passes `fn` into wrap...
+// // maybe, instead, add `pre` & `post`
+// // was `partial(wrapper, fn)`
+// return curry(3, wrapper, fn)
+// }
+//
+// const argumentor = require('../cast/argumentor')
+// const isFunction = require('../is/function')
+//
+// // @TODO maybe returning `false` will disable the function?
+// // or returning `noop` ?
+// // or anything but `nill` ?
+// function pre(target, subscriber) {
+// return curry(target.length, function() {
+// const args = argumentor.apply(null, arguments)
+//
+// // call subscriber
+// const returned = subscriber.apply(this, args)
+//
+// if (returned === false) return null
+// else if (isFunction(returned)) return returned
+// else return target.apply(this, args)
+// })
+// }
+// function post(target, subscriber) {
+// const args = argumentor.apply(null, arguments)
+// const returned = target.apply(this, args)
+//
+// // also original args??
+// subscriber.apply(null, returned)
+// }
+//
+// // http://ramdajs.com/docs/#memoizeWith
+//
+// // AND THEN, COULD JUST USE `NTH` ON RETURNED
+//
+// // HOW CAN THE SUBSCRIBERS GET THE RESULTS?
+// // LIKE IF WE WANT TO SEE THE RETURNED VALUE?
+// //
+// // return result from last?
+// // @example
+// //
+// // const pre = console.log
+// // const post = console.error
+// // const multiply = (n, factor) => n * factor
+// // notifyEach(pre, multiply, post)
+// function notifyEach(subscribers) {
+// return function() {
+// const args = arguments
+// const results = []
+// subscribers.forEach(subscriber => {
+// results.push(subscriber.apply(null, arguments))
+// })
+// }
+// }
+//
+// // USE ARRAY OF OBJECTS, TO AN OBJECT WITH INDEXES AS A PROPERTY
+// function indexBy() {}
+//
+//
+// // Return a random integer between min and max (inclusive).
+// const random = function(min, max) {
+// if (isNill(max)) {
+// max = min
+// min = 0
+// }
+// return min + Math.floor(Math.random() * (max - min + 1))
+// }
+//
+// // @NOTE USES LODASH.ORDERBY
+// function orderByKeys(obj, orderFirst) {
+// const orderedObj = {}
+// orderFirst = orderFirst.reverse()
+// const keys = Object.keys(obj)
+// _sortBy(keys, key => orderFirst.indexOf(key))
+// .reverse()
+// .forEach(key => {
+// orderedObj[key] = obj[key]
+// })
+// return orderedObj
+// }
+//
+//
+// /**
+// * @example
+// *
+// * remapBy(prop('id'), [{'id': 'eh'}])
+// *
+// * @example
+// * in: [
+// * {id: 'eh', val: 'canada'},
+// * {id: 'moose', val: 'igloo'}
+// * ]
+// *
+// * out: {
+// * 'eh': {id: 'eh', val: 'canada'},
+// * 'moose': {id: 'moose', val: 'igloo'}
+// * }
+// */
+// // or INDEXBY
+// function remapBy(transformer, vals) {
+// const remapped = {}
+//
+// // @TODO: should reload if there is no remap by id vals...
+// if (!isObj(vals)) return remapped
+//
+// var asObj = values(vals)
+//
+// // if (isArray(vals)) {
+// // // if it does not have the prop, add it as the index
+// // // if it has it, and it is an array, join it
+// // vals = values.map((data, i) => {
+// // if (!data[prop]) data[prop] = i
+// // if (isArray(data[prop])) data[prop] = data[prop].join(',')
+// // return data
+// // })
+// //
+// // return arrToObj(values, {
+// // keyFn: ({i}) => values[i][prop],
+// // valFn: ({i, val}) => val,
+// // })
+// // }
+//
+// // remap to add item id as object property
+// const props = keys(asObj)
+// for (let i = 0, len = props.length; i < len; i++) {
+// const key = props[i]
+// const val = asObj[key]
+//
+// remapped[val.id] = val
+// }
+// // console.debug('remapById', {values, asObj})
+//
+// return remapped
+// }
+//
+//
+// function omit(obj, keys) {
+// const target = {}
+// for (let i in obj) {
+// if (keys.indexOf(i) >= 0 || !hasOwnProperty(obj, i)) continue
+// target[i] = obj[i]
+// }
+// return target
+// }
+//
+//
+// // http://werxltd.com/wp/2010/05/13/javascript-implementation-of-javas-string-hashcode-method/
+// // module.exports = function fliphash(str) {
+// // // || typeof str !== 'string'
+// // // if (str === undefined || str === null) {
+// // // console.log('you passed not real value to fliphash')
+// // // return str
+// // // }
+// // if (isNill(str)) return 'nill'
+// // let len = str.length
+// // if (len === 0) return 0
+// //
+// // let hash = 0
+// //
+// // for (let i = 0; i < len; i++) {
+// // const char = str.charCodeAt(i)
+// // hash = ((hash << 5) - hash) + char
+// // hash = hash & hash // Convert to 32bit integer
+// // }
+// // return hash
+// // }
+// //
+// // const test = require('ava')
+// // const fliphash = require('../')
+// //
+// // test('hashes a number', t => {
+// // t.plan(1)
+// // const txt = 'ehohehoh... wayoh wayoh wayoh-wayoh!'
+// // t.true(typeof fliphash(txt) === 'number')
+// // })
+// //
+// // test('hashes are the same', t => {
+// // t.plan(1)
+// // const txt = 'hullabaloo000&&&!!!eh'
+// // t.is(fliphash(txt), fliphash(txt))
+// // })
+//
+//
+// module.exports = curry(2, wrap)
diff --git a/src/deps/is/JSON.js b/src/deps/is/JSON.js
new file mode 100644
index 0000000..ff5d9bd
--- /dev/null
+++ b/src/deps/is/JSON.js
@@ -0,0 +1,87 @@
+const getIncludesCount = require('../fp/includesCount')
+const isEven = require('../math/even')
+const isArray = require('./array')
+const isNumber = require('./numberPrimitive')
+const isString = require('./stringPrimitive')
+const isTrue = require('./true')
+
+// http://documentcloud.github.io/underscore-contrib/#isjson
+// https://github.com/chriso/validator.js/blob/master/src/lib/isJSON.js
+// https://bitsrc.io/amit/json/global/json-validator/code
+//
+// const onlyLettersAndSpaces = /^([\sa-z]+)*$/gim
+// const regexp = /[\"|\{|\[|\}|]+/
+// const chars = ['[', '"', '{', ']', '}']
+// const nums = [91, 34]
+// const map = {
+// '"': 34,
+// '{': 123,
+// '}': 125,
+// ']': 93,
+// '[': 91,
+// }
+
+
+// @TODO everything like this (with numbers)
+// eslint-disable-next-line no-useless-escape
+const JSONAlphaOmega = x =>
+ x === 93 || x === 91 || x === 125 || x === 123 || x === 34
+
+
+function hasWith(x, fn, symbol) {
+ if (isArray(symbol)) return symbol.map(s => hasWith(x, fn, s)).every(isTrue)
+ else return fn(getIncludesCount(x.split(''), symbol))
+}
+
+const isValidJSONLine = subString => {
+ const trimmed = subString.trim()
+ const start = trimmed.charCodeAt(0)
+ const end = trimmed.charCodeAt(trimmed.length - 1)
+ return JSONAlphaOmega(start) && JSONAlphaOmega(end)
+}
+
+/* prettier-ignore */
+/**
+ * @desc isJSON, without tryCatch
+ * @param {*} x value to check
+ * @return {boolean} x isJSON
+ *
+ * @example
+ * isJSON('{}')
+ * //=> true
+ *
+ * isJSON('')
+ * //=> false
+ *
+ * isJSON('[]')
+ * //=> true
+ */
+function isJSON(x) {
+ return isString(x) && x.split(',').every(isValidJSONLine)
+}
+
+function isJSONSafe(x) {
+ return isJSON(x) && hasWith(x, isEven, ['[', ']', '{', '}', '"'])
+}
+
+// https://github.com/mootools/mootools-core/blob/master/Source/Utilities/JSON.js
+
+const reValidJSON = /^[\],:{}\s]*$/
+const reProps = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g
+const reVals = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g
+const reColons = /(?:^|:|,)(?:\s*\[)+/g
+
+// const replacements = [
+// replace(reProps, '@'),
+// replace(reVals, ']'),
+// replace(reColons, ':'),
+// ]
+// const replaceAll = pipe(replacements)
+
+function isValidJSON(string) {
+ reValidJSON.test(
+ string.replace(reProps, '@').replace(reVals, ']').replace(reColons, '')
+ )
+}
+
+module.exports = isJSON
diff --git a/src/deps/is/NaN.js b/src/deps/is/NaN.js
new file mode 100644
index 0000000..e945905
--- /dev/null
+++ b/src/deps/is/NaN.js
@@ -0,0 +1,38 @@
+const isNumber = require('./number')
+
+/**
+ * Checks if `value` is `NaN`
+ * @category Lang
+ * @memberOf is
+ * @since 5.0.0-beta.5
+ *
+ * @param {*} x The value to check.
+ * @return {boolean} x isNaN
+ *
+ * @name isNaN
+ * @alias isNotNumber
+ * @alias isNotEhNumber
+ *
+ * {@link https://tc39.github.io/ecma262/#sec-isnan-number emca-isnan}
+ * {@link https://github.com/lodash/lodash/tree/npm-packages/lodash.isnan lodash-isnan}
+ * {@link https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/isNaN mozilla-isnan}
+ * {@link https://github.com/jashkenas/underscore/blob/master/underscore.js#L1347 underscore-is-nan}
+ * @see {@link emca-isnan}
+ * @see {@link mozilla-isnan}
+ * @see {@link underscore-is-nan}
+ * @see {@link lodash-isnan}
+ * @see is/number
+ * @see is/real
+ *
+ * @example
+ *
+ * isNaN(Number(null)) //=> true
+ * isNaN(NaN) //=> true
+ *
+ * isNaN(0) //=> false
+ * isNaN(Number(100)) //=> false
+ *
+ */
+module.exports = function isNaN(x) {
+ return isNumber(x) && Number.isNaN(x)
+}
diff --git a/src/deps/is/README.md b/src/deps/is/README.md
index 7b617e4..488a822 100644
--- a/src/deps/is/README.md
+++ b/src/deps/is/README.md
@@ -1,5 +1,32 @@
+https://tc39.github.io/ecma262/#sec-well-known-intrinsic-objects
+https://github.com/lodash/lodash/blob/master/.internal/isPrototype.js
+https://tc39.github.io/ecma262/#sec-property-descriptor-specification-type
+https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isSafeInteger
+
+---
+
https://github.com/infernojs/inferno/blob/master/packages/inferno-shared/src/index.ts
https://www.npmjs.com/package/kind-of
-https://github.com/lodash/lodash/blob/master/isString.js
+
https://github.com/lodash/lodash/blob/master/.internal/baseGetTag.js
https://github.com/lodash/lodash/blob/master/.internal/getTag.js
+https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures
+https://github.com/canjs/can-util/tree/master/js
+
+https://github.com/bitovi/guide-automation
+https://github.com/bitovi/checklist
+https://github.com/bitovi/u
+https://github.com/bitovi/steal-tools-builder
+https://github.com/addyosmani/es6-tools
+
+https://github.com/madrobby/zepto
+http://code.jquery.com/jquery-3.2.1.js
+https://github.com/sstephenson/prototype
+
+https://tc39.github.io/ecma262/#sec-object.isfrozen
+
+- I've been improving so much code, reading every library that's any good
+- next to every single one of them has some "isX" util
+- @example `isFunction`, `isNull`, `isError`,
+- they get really hot, and they are really small, so they get inlined blazing fast and it's dope
+- **...** but if you have say 3 libraries, and each one has their own `isFunction` or `isNull`, that defeats the purpose! need a build function & compat checker to replace & merge as needed for best perf in apps not just libs
diff --git a/src/deps/is/_all.js b/src/deps/is/_all.js
new file mode 100644
index 0000000..7c8bf34
--- /dev/null
+++ b/src/deps/is/_all.js
@@ -0,0 +1,189 @@
+const toS = require('./toS')
+const isTagEq = require('./tagEq')
+const isType = require('./type')
+const isArguments = require('./arguments')
+const isArray = require('./array')
+const isArrayOf = require('./arrayOf')
+const isArrayLike = require('./arrayLike')
+const isArrayTyped = require('./arrayTyped')
+const isArrayBuffer = require('./arrayBuffer')
+const isAsync = require('./async')
+const isAsyncish = require('./asyncish')
+const isBoolean = require('./boolean')
+const isBooleanPrimitive = require('./booleanPrimitive')
+const isBooleanLike = require('./booleanLike')
+const isBrowser = require('./browser')
+const isCircular = require('./circular')
+const isCollection = require('./collection')
+const isClass = require('./class')
+const isDate = require('./date')
+const isDataView = require('./dataView')
+const isDot = require('./dot')
+const isError = require('./error')
+const isExtensible = require('./extensible')
+const isEnumerable = require('./enumerable')
+const isElement = require('./element')
+const isEmpty = require('./empty')
+const isFunction = require('./function')
+const isFalse = require('./false')
+const isFalsy = require('./falsy')
+const isFlattenable = require('./flattenable')
+const isFinite = require('./finite')
+const isGenerator = require('./generator')
+const hasIn = require('./hasIn')
+const isIterator = require('./iterator')
+const isIn = require('./in')
+const isInfinity = require('./infinity')
+const isNegativeInfinity = require('./negativeInfinity')
+const isIndexable = require('./indexable')
+const isInstanceOf = require('./instanceOf')
+const isInteger = require('./integer')
+const isJSON = require('./JSON')
+const isMatcher = require('./matcher')
+const isMap = require('./map')
+const isMapish = require('./mapish')
+const isMatch = require('./match')
+const isMatchWith = require('./matchWith')
+const isNill = require('./nullOrUndefined')
+const isNull = require('./null')
+const isNumber = require('./number')
+const isNumberPrimitive = require('./numberPrimitive')
+const isNumberish = require('./numberish')
+const isNumberishWithDecimals = require('./numberishWithDecimals')
+const isNaN = require('./NaN')
+const isNative = require('./native')
+const isNodeJS = require('./nodejs')
+// const isEmptyArray = require('./emptyArray')
+const isObj = require('./obj')
+const isObjPure = require('./objPure')
+const isObjWithKeys = require('./objWithKeys')
+const isObjNotNull = require('./objNotNull')
+const isObjPlain = require('./objPlain')
+const isObjTag = require('./objTag')
+const isObjTypeof = require('./objTypeof')
+const ownPropertyIs = require('./ownPropertyIs')
+const isPrimitive = require('./primitive')
+const isPrototypeOf = require('./prototypeOf')
+const isPromise = require('./promise')
+const isRegExp = require('./regexp')
+const isReal = require('./real')
+const isStringOrNumber = require('./stringOrNumber')
+const isString = require('./string')
+const isSet = require('./set')
+const isSymbol = require('./symbol')
+const isTrue = require('./true')
+const isUndefined = require('./undefined')
+const isUndefinedLike = require('./undefinedLike')
+const isUnsignedInteger = require('./unsignedInteger')
+const isURL = require('./url')
+const isValidArrayIndex = require('./validArrayIndex')
+const isValidIndex = require('./validIndex')
+const isValidPropertyKey = require('./validPropertyKey')
+const isWeakMap = require('./weakMap')
+const isWeakSet = require('./weakSet')
+const isWebWorker = require('./webWorker')
+const isWeakMapUsable = require('./weakMapUsable')
+const isZeroish = require('./zeroish')
+const hasDecimals = require('./hasDecimals')
+
+const getTag = toS
+
+/**
+ * @alias allIzzez
+ * @memberOf is
+ * @since 5.0.0-beta.6
+ * @see is/_core
+ * @type {Object}
+ */
+module.exports = {
+ getTag,
+ toS,
+ // actual isses
+ isArguments,
+ isArrayOf,
+ isArrayLike,
+ isAsyncish,
+ isArray,
+ isArrayTyped,
+ isArrayBuffer,
+ isAsync,
+ isBoolean,
+ isBooleanPrimitive,
+ isBooleanLike,
+ isBrowser,
+ isCircular,
+ isCollection,
+ isClass,
+ isDate,
+ isDataView,
+ isDot,
+ isError,
+ isEnumerable,
+ isElement,
+ isEmpty,
+ isExtensible,
+ isFunction,
+ isFalse,
+ isFalsy,
+ isFlattenable,
+ isFinite,
+ isGenerator,
+ // not named is
+ hasIn,
+ ownPropertyIs,
+ // back to it
+ isIterator,
+ isIn,
+ isInfinity,
+ isNegativeInfinity,
+ isIndexable,
+ isInstanceOf,
+ isInteger,
+ isJSON,
+ isMatcher,
+ isMap,
+ isMapish,
+ isMatch,
+ isMatchWith,
+ isNill,
+ isNull,
+ isNumber,
+ isNumberPrimitive,
+ isNumberish,
+ isNumberishWithDecimals,
+ isNaN,
+ isNative,
+ isNodeJS,
+ isObj,
+ isObjTag,
+ isObjTypeof,
+ isObjPure,
+ isObjWithKeys,
+ isObjNotNull,
+ isObjPlain,
+ isPrimitive,
+ isPromise,
+ isPrototypeOf,
+ isRegExp,
+ isReal,
+ isStringOrNumber,
+ isString,
+ isSet,
+ isSymbol,
+ isTrue,
+ isType,
+ isTagEq,
+ isUndefined,
+ isUndefinedLike,
+ isUnsignedInteger,
+ isURL,
+ isValidArrayIndex,
+ isValidIndex,
+ isValidPropertyKey,
+ isWeakMap,
+ isWeakMapUsable,
+ isWeakSet,
+ isWebWorker,
+ isZeroish,
+ hasDecimals,
+}
diff --git a/src/deps/is/_core.js b/src/deps/is/_core.js
new file mode 100644
index 0000000..252693b
--- /dev/null
+++ b/src/deps/is/_core.js
@@ -0,0 +1,60 @@
+const toS = require('./toS')
+const isBoolean = require('./boolean')
+const isRegExp = require('./regexp')
+const isError = require('./error')
+const isNumber = require('./number')
+const isString = require('./string')
+const isDate = require('./date')
+const isObj = require('./obj')
+const isObjPure = require('./objPure')
+const isObjWithKeys = require('./objWithKeys')
+const isObjNotNull = require('./objNotNull')
+const isReal = require('./real')
+const isMap = require('./map')
+const isSet = require('./set')
+const isSymbol = require('./symbol')
+const isFunction = require('./function')
+const isPrototypeOf = require('./prototypeOf')
+const isArray = require('./array')
+const isIterator = require('./iterator')
+const isUndefined = require('./undefined')
+const isNull = require('./null')
+const isMatcher = require('./matcher')
+const isNill = require('./nullOrUndefined')
+const isTrue = require('./true')
+
+/**
+ * @member is
+ * @alias coreIzzez
+ * @types is
+ * @tests is/*
+ *
+ * @see https://github.com/lodash/lodash/issues/3237
+ * @type {Object}
+ */
+module.exports = {
+ isObjWithKeys,
+ isObj,
+ isObjPure,
+ isObjNotNull,
+ isFunction,
+ isReal,
+ toS,
+ isDate,
+ isRegExp,
+ isError,
+ isBoolean,
+ isNumber,
+ isString,
+ isMap,
+ isSet,
+ isSymbol,
+ isPrototypeOf,
+ isArray,
+ isIterator,
+ isUndefined,
+ isNull,
+ isNill,
+ isTrue,
+ isMatcher,
+}
diff --git a/src/deps/is/arguments.js b/src/deps/is/arguments.js
new file mode 100644
index 0000000..7705d6b
--- /dev/null
+++ b/src/deps/is/arguments.js
@@ -0,0 +1,60 @@
+const hasOwnProperty = require('../util/hasOwnProperty')
+const isEnumerable = require('./enumerable')
+const toS = require('./toS')
+
+/**
+ * @desc check if toString on object is Arguments
+ * @since 4.0.0
+ * @memberOf is
+ *
+ * @param {Object | *} x value to check if isArguments
+ * @return {boolean} isArguments
+ *
+ * @see is/toS
+ * @name isArguments
+ * @func
+ *
+ * {@link https://tc39.github.io/ecma262/#prod-ArgumentList emca-isarguments}
+ * {@link https://github.com/medikoo/es5-ext/blob/master/function/is-arguments.js es5-ext-is-arguments}
+ * {@link https://github.com/jashkenas/underscore/blob/master/underscore.js#L1325 underscore-is-arguments}
+ * {@link https://github.com/substack/node-deep-equal/blob/master/lib/is_arguments.js node-deep-equals-is-arguments}
+ * {@link https://github.com/lodash/lodash/blob/master/isArguments.js lodash-is-arguments}
+ * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments mozilla-func-arguments}
+ * @see {@link emca-isarguments}
+ * @see {@link mozilla-func-arguments}
+ * @see {@link node-deep-equals-is-arguments}
+ * @see {@link lodash-is-arguments}
+ * @see {@link underscore-is-arguments}
+ * @see {@link es5-ext-is-arguments}
+ *
+ * @example
+ *
+ * isArguments({}) //=> false
+ *
+ * (function() {
+ * isArguments(arguments)
+ * //=> true
+ * })()
+ *
+ */
+const isArguments = x => toS(x) === '[object Arguments]'
+
+module.exports = isArguments
+
+// function unsupported(object) {
+// return (
+// (object &&
+// typeof object === 'object' &&
+// typeof object.length === 'number' &&
+// hasOwnProperty(object, 'callee') &&
+// !isEnumerable.call(object, 'callee')) ||
+// false
+// )
+// }
+//
+// const supportsArgumentsClass =
+// (function() {
+// return toS(arguments)
+// })() === '[object Arguments]'
+//
+// module.exports = supportsArgumentsClass ? supported : unsupported
diff --git a/src/deps/is/array.js b/src/deps/is/array.js
index 71d84e1..292d82e 100644
--- a/src/deps/is/array.js
+++ b/src/deps/is/array.js
@@ -1,8 +1,31 @@
/**
- * @func isArray
- * @see https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray
- * @type {Function}
+ * @name isArray
+ * @memberOf is
* @since 3.0.0
+ *
+ * {@link https://tc39.github.io/ecma262/#sec-isarray emca-isarray}
+ * {@link https://github.com/gcanti/tcomb/blob/master/lib/isArray.js tcomb-isarray}
+ * {@link https://nodejs.org/api/util.html#util_util_isarray_object node-util-isarray}
+ * {@link https://github.com/infernojs/inferno/blob/master/packages/inferno-shared/src/index.ts#L16 inferno-is-array}
+ * {@link https://github.com/jashkenas/underscore/blob/master/underscore.js#L1308 underscore-is-array}
+ * {@link https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray mozilla-isarray}
+ * {@link https://github.com/facebook/immutable-js/blob/master/src/utils/isArrayLike.js immutables-is-array-like}
+ *
+ * @param {Array | *} arg
+ * @return {boolean} isArray(arg)
+ *
+ * @func
+ * @type {Function}
+ *
+ * @see is/arrayLike
+ * @see {@link emca-isarray}
+ * @see {@link mozilla-isarray}
+ * @see {@link underscore-is-array}
+ * @see {@link tcomb-isarray}
+ * @see {@link immutables-is-array-like}
+ * @see {@link inferno-is-array}
+ * @see {@link node-util-isarray}
+ *
*/
module.exports = Array.isArray
diff --git a/src/deps/is/arrayBuffer.js b/src/deps/is/arrayBuffer.js
new file mode 100644
index 0000000..89e174e
--- /dev/null
+++ b/src/deps/is/arrayBuffer.js
@@ -0,0 +1,9 @@
+const tagEq = require('./tagEq')
+
+/**
+ * @name isArrayBuffer
+ * @type {Function}
+ * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer mozilla-array-buffer}
+ * @see {@link mozilla-array-buffer}
+ */
+module.exports = tagEq('[object ArrayBuffer]')
diff --git a/src/deps/is/arrayLike.js b/src/deps/is/arrayLike.js
new file mode 100644
index 0000000..bab4c24
--- /dev/null
+++ b/src/deps/is/arrayLike.js
@@ -0,0 +1,87 @@
+const lengthMinusOne = require('../util/lengthMinusOne')
+const hasOwnProperty = require('../util/hasOwnProperty')
+const length = require('../util/length')
+const isArray = require('./array')
+const isString = require('./string')
+const isPureObj = require('./objPure')
+const isReal = require('./real')
+// const isElement = require('./element')
+
+/**
+ * @desc Tests whether or not an object is similar to an array.
+ * @name isArrayLike
+ * @memberOf is
+ * @since 5.0.0-beta.5
+ * @alias isArrayIsh
+ *
+ * @param {Array | Object | *} arg object to test
+ * @return {boolean} `true` if `x` has a numeric length property and extreme indices defined; `false` otherwise.
+ *
+ * @func
+ * @type {Function}
+ *
+ * {@link https://github.com/ramda/ramda/blob/master/src/internal/_isArrayLike.js ramda-is-array-like}
+ * {@link https://github.com/jashkenas/underscore/blob/master/underscore.js#L165 underscore-is-array-like}
+ * {@link https://github.com/lodash/lodash/blob/master/isArrayLike.js lodash-is-array-like}
+ * {@link https://github.com/mobxjs/mobx/blob/master/src/utils/utils.ts#L210 mobx-is-array-like}
+ * {@link https://github.com/facebook/immutable-js/blob/master/src/utils/isArrayLike.js immutables-is-array-like}
+ * @see {@link immutables-is-array-like}
+ * @see {@link mobx-is-array-like}
+ * @see {@link lodash-is-array-like}
+ * @see {@link underscore-is-array-like}
+ * @see {@link ramda-is-array-like}
+ *
+ * @category Type
+ * @category List
+ * @sig * -> Boolean
+ *
+ * @example
+ *
+ * isArrayLike([]); //=> true
+ * isArrayLike(true); //=> false
+ * isArrayLike({}); //=> false
+ * isArrayLike({length: 10}); //=> false
+ * isArrayLike({0: 'zero', 9: 'nine', length: 10}); //=> true
+ *
+ */
+module.exports = function isArrayLike(x) {
+ if (!isReal(x)) {
+ return false
+ }
+ else if (isArray(x)) {
+ return true
+ }
+ else if (!isPureObj(x)) {
+ return false
+ }
+ else if (isString(x)) {
+ return false
+ }
+ // ignoring because it's pretty big
+ // else if (isElement(x)) {
+ // return !!x.length
+ // }
+ else if (length(x) === 0) {
+ return true
+ }
+ // has [0] & [1]
+ else if (length(x) > 0) {
+ return hasOwnProperty(x, 0) && hasOwnProperty(x, lengthMinusOne(x))
+ }
+ else {
+ return false
+ }
+}
+
+// from underscore
+// Helper for collection methods to determine whether a collection
+// should be iterated as an array or as an object.
+// Related: http://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength
+// Avoids a very nasty iOS 8 JIT bug on ARM-64. #2094
+// var MAX_ARRAY_INDEX = Math.pow(2, 53) - 1
+// var getLength = shallowProperty('length')
+// var isArrayLike = function(collection) {
+// var length = getLength(collection)
+// return isNumber(length) && length >= 0 && length <= MAX_ARRAY_INDEX
+// }
+//
diff --git a/src/deps/is/arrayOf.js b/src/deps/is/arrayOf.js
new file mode 100644
index 0000000..d0cef51
--- /dev/null
+++ b/src/deps/is/arrayOf.js
@@ -0,0 +1,25 @@
+const and = require('../conditional/and')
+const all = require('../conditional/all')
+const isArray = require('./array')
+
+/**
+ * @desc every item in an array matches predicate
+ * @since 4.0.0 was in validatorBuilder
+ * @version 5.0.0
+ *
+ * @memberOf is
+ * @param {Function} predicate test to pass on every item in an array
+ * @return {boolean} all match predicate
+ *
+ * @example
+ *
+ * isArrayOf(isTrue)([true, true]) //=> true
+ * isArrayOf(isEmpty)(['']) //=> true
+ *
+ * isArrayOf(isBoolean)([true, false, 1, 2, 0]) //=> false
+ * isArrayOf(isString)(['string', Number]) //=> false
+ *
+ */
+module.exports = function isArrayOf(predicate) {
+ return and(isArray, all(predicate))
+}
diff --git a/src/deps/is/arrayTyped.js b/src/deps/is/arrayTyped.js
new file mode 100644
index 0000000..d478b87
--- /dev/null
+++ b/src/deps/is/arrayTyped.js
@@ -0,0 +1,25 @@
+const matchTypedTag = require('../regexp/matchTypedTag')
+const toS = require('./toS')
+const isObjNotNull = require('./objNotNull')
+
+/**
+ * Checks if `value` is classified as a typed array.
+ * @since 5.0.0-beta.6
+ *
+ * @param {*} x The value to check.
+ * @return {boolean} Returns `true` if `value` is a typed array, else `false`.
+ *
+ * @name isArrayTyped
+ * @alias isTypedArray
+ *
+ * @fork 3.0.0
+ * @category Lang
+ *
+ * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays mozilla-typed-arrays}
+ * @see {@link mozilla-typed-arrays}
+ *
+ * @example isTypedArray(new Uint8Array) //=> true
+ * @example isTypedArray([]) //=> false
+ *
+ */
+module.exports = x => isObjNotNull(x) && matchTypedTag.test(toS(x))
diff --git a/src/deps/is/async.js b/src/deps/is/async.js
index aba138e..7e6de06 100644
--- a/src/deps/is/async.js
+++ b/src/deps/is/async.js
@@ -9,6 +9,8 @@ const toS = require('./toS')
*
* @memberOf is
* @func isAsync
+ * @see is/toS
+ * @see is/promise
*
* @example
*
diff --git a/src/deps/is/asyncish.js b/src/deps/is/asyncish.js
index 79acdfe..48895ed 100644
--- a/src/deps/is/asyncish.js
+++ b/src/deps/is/asyncish.js
@@ -1,29 +1,30 @@
+const or = require('../conditional/or')
const isAsync = require('./async')
const isPromise = require('./promise')
/**
* @desc async function or promise
- * @category Lang
+ * @since 4.0.0-beta.2
+ * @memberOf is
*
* @param {*} x value
* @return {boolean} x isAsyncish
- * @since 4.0.0-beta.2
*
- * @memberOf is
- * @func isAsyncish
+ * @category Lang
+ * @func
+ * @name isAsyncish
+ * @alias isAsyncLike
* @extends isAsyncish
* @extends isPromise
* @variation isAsyncish OR isPromise
*
* @example
*
- * isAsyncish(async function() {})
- * //=> true
- * isAsyncish(new Promise(r => r()))
- * //=> true
+ * isAsyncish(async function() {}) //=> true
+ * isAsyncish(new Promise(r => r())) //=> true
+ *
+ * isAsyncish({}) //=> false
+ * isAsyncish(function() {}) //=> false
*
- * isAsyncish({})
- * //=> false
- * isAsyncish(function() {})
*/
-module.exports = x => isAsync(x) || isPromise(x)
+module.exports = or(isAsync, isPromise)
diff --git a/src/deps/is/boolean.js b/src/deps/is/boolean.js
index a4ac0da..33f6d94 100644
--- a/src/deps/is/boolean.js
+++ b/src/deps/is/boolean.js
@@ -1,22 +1,33 @@
const toS = require('./toS')
-const isTrue = require('./true')
-const isFalse = require('./false')
+const isBooleanPrimitive = require('./booleanPrimitive')
/**
- * @desc Checks if `value` is classified as a boolean primitive or object.
- * @category Lang
+ * @desc Checks if `value` is classified as a boolean primitive OR object.
* @since 3.0.0
+ * @version 1.0.0 <- supported primitive & object
+ * @version 2.0.0 <- split out primitive
+ * @category Lang
+ * @memberOf is
*
* @param {*} x value
* @return {boolean} isBoolean
*
* @extends isTrue
* @extends isFalse
- * @see is/toS
- * @memberOf is
- * @func isBoolean
+ * @extends isBooleanPrimitive
+ *
+ * @func
+ * @name isBoolean
*
- * @NOTE could also have typeof x === 'boolean' || (/true|false/).test(x)
+ * {@link https://github.com/infernojs/inferno/blob/master/packages/inferno-shared/src/index.ts#L23 inferno-isboolean}
+ * {@link https://github.com/gcanti/tcomb/blob/master/lib/isBoolean.js tcomb-isboolean}
+ * {@link https://nodejs.org/api/util.html#util_util_isboolean_object node-util-isboolean}
+ * {@link https://github.com/jashkenas/underscore/blob/master/underscore.js#L1352 underscore-is-boolean}
+ * @see {@link inferno-isboolean}
+ * @see {@link tcomb-isboolean}
+ * @see {@link underscore-is-boolean}
+ * @see {@link node-util-isboolean}
+ * @see is/toS
*
* @example
*
@@ -31,5 +42,5 @@ const isFalse = require('./false')
*
*/
module.exports = function isBoolean(x) {
- return isTrue(x) || isFalse(x) || toS(x) === '[object Boolean]'
+ return isBooleanPrimitive(x) || toS(x) === '[object Boolean]'
}
diff --git a/src/deps/is/booleanLike.js b/src/deps/is/booleanLike.js
new file mode 100644
index 0000000..f937312
--- /dev/null
+++ b/src/deps/is/booleanLike.js
@@ -0,0 +1,5 @@
+const matchBooleanIsh = require('../regexp/matchBooleanIsh')
+const isBoolean = require('./boolean')
+
+const isBooleanLike = x => isBoolean(x) || matchBooleanIsh(x)
+module.exports = isBooleanLike
diff --git a/src/deps/is/booleanPrimitive.js b/src/deps/is/booleanPrimitive.js
new file mode 100644
index 0000000..7db158a
--- /dev/null
+++ b/src/deps/is/booleanPrimitive.js
@@ -0,0 +1,35 @@
+const isTrue = require('./true')
+const isFalse = require('./false')
+
+/**
+ * @desc Checks if `value` is classified as a boolean primitive NOT object.
+ * @category Lang
+ * @since 5.0.0-beta.4
+ *
+ * @param {*} x value
+ * @return {boolean} isBooleanPrimitive
+ *
+ * @extends isTrue
+ * @extends isFalse
+ * @see is/toS
+ * @memberOf is
+ * @func isBooleanPrimitive
+ *
+ * @NOTE could also have typeof x === 'boolean' || (/true|false/).test(x)
+ *
+ * @example
+ *
+ * isBooleanPrimitive(false)
+ * //=> true
+ * isBooleanPrimitive(new Boolean(1))
+ * //=> false
+ *
+ * isBooleanPrimitive(1)
+ * //=> false
+ * isBooleanPrimitive('')
+ * //=> false
+ *
+ */
+module.exports = function isBooleanPrimitive(x) {
+ return isTrue(x) || isFalse(x)
+}
diff --git a/src/deps/is/browser.js b/src/deps/is/browser.js
new file mode 100644
index 0000000..a83c5db
--- /dev/null
+++ b/src/deps/is/browser.js
@@ -0,0 +1,16 @@
+const isUndefinedLike = require('./undefinedLike')
+
+/* istanbul ignore next: jest mess up */
+/**
+ * @desc check typeof window
+ * @since 5.0.0-beta.1
+ * @memberOf is
+ * @return {boolean} is in browser, or has global window
+ * @name isBrowser
+ * @func
+ * @extends isUndefinedLike
+ * @see utils/localGlobal
+ * @example isBrowser() //=> true | false
+ */
+module.exports = () =>
+ !isUndefinedLike(typeof window) && !isUndefinedLike(window.window)
diff --git a/src/deps/is/buffer.js b/src/deps/is/buffer.js
new file mode 100644
index 0000000..6dd9a1f
--- /dev/null
+++ b/src/deps/is/buffer.js
@@ -0,0 +1,38 @@
+const length = require('../util/length')
+const isObj = require('./obj')
+const isFunction = require('./function')
+const isNumber = require('./number')
+
+/**
+ * @desc isBuffer, global Buffer
+ * @since 5.0.0-beta.1
+ *
+ * @memberOf is
+ * @param {Buffer | *} x value to check if Buffer
+ * @return {boolean} x is Buffer
+ *
+ * If you need to support Safari 5-7 (8-10 yr-old browser),
+ *
+ * @see https://nodejs.org/api/util.html#util_util_isbuffer_object
+ * @see https://github.com/feross/is-buffer
+ *
+ * @example
+ *
+ * isBuffer({}) //=> false
+ * isBuffer(new Buffer('eh')) //=> true
+ *
+ */
+module.exports = function isBuffer(x) {
+ if (!x || isObj(x) || length(x)) return false
+ else if (!isFunction(x.copy) || isFunction(x.slice)) return false
+ else if (length(x) > 0 && isNumber(x[0])) return false
+ else return true
+}
+
+// another way to write it
+// module.exports = function isBuffer(val) {
+// var c = val.constructor
+// return c &&
+// typeof c.isBuffer === 'function' &&
+// c.isBuffer(val)
+// }
diff --git a/src/deps/is/circular.js b/src/deps/is/circular.js
new file mode 100644
index 0000000..9b66c02
--- /dev/null
+++ b/src/deps/is/circular.js
@@ -0,0 +1,69 @@
+const isObj = require('./obj')
+
+/**
+ * safari, ff, chrome/opera
+ * @type {Array}
+ */
+const errorKeywords = ['circular', 'cyclic']
+
+/**
+ * @desc check if a value is circular
+ *
+ * @memberOf is
+ * @since 5.0.0-beta.4
+ * @symb 🔘
+ *
+ * @param {Object | *} obj object to check if is circular
+ * @return {boolean} isCircular / hasCircular
+ *
+ * @TODO find the circular property...
+ * @NOTE is slow try catch json
+ * @NOTE if (isFunction(obj)) { throw new Error('cannot determine if function is circular')}
+ *
+ * @example
+ *
+ * const a = {};
+ * a.b = a;
+ * isCircular(a) //=> true
+ *
+ * const a = {};
+ * a.b = {
+ * c: a
+ * }
+ * isCircular(a) //=> true
+ *
+ * const a = {};
+ * a.b = {
+ * c: 4
+ * }
+ * isCircular(a) //=> false
+ *
+ * const a = [];
+ * a.push(a);
+ * isCircular(a) //=> true
+ *
+ * isCircular({}) //=> false
+ * isCircular('hi') //=> false
+ * isCircular(undefined) //=> false
+ *
+ */
+module.exports = function isCircular(obj) {
+ if (!isObj(obj)) return false
+
+ try {
+ JSON.stringify(obj)
+ }
+ catch (err) {
+ let index = errorKeywords.length
+ while (index--) {
+ if (err.message.includes(errorKeywords[index])) {
+ return true
+ }
+ }
+
+ // @NOTE should not do this
+ throw err
+ }
+
+ return false
+}
diff --git a/src/deps/is/class.js b/src/deps/is/class.js
index fa65a31..cfecdc4 100644
--- a/src/deps/is/class.js
+++ b/src/deps/is/class.js
@@ -1,2 +1,2 @@
/* istanbul ignore next: build - things are compiled so isClass is not used */
-module.exports = o => o && (/^\s*class\s/).test(o.toString())
+module.exports = x => x && (/^\s*class\s/).test(x.toString())
diff --git a/src/deps/is/collection.js b/src/deps/is/collection.js
new file mode 100644
index 0000000..ff87d49
--- /dev/null
+++ b/src/deps/is/collection.js
@@ -0,0 +1,11 @@
+const or = require('../conditional/or')
+const isMap = require('./map')
+const isSet = require('./set')
+
+/**
+ * @name isCollection
+ * @alias isMapOrSet
+ * @type {Function}
+ * @since 5.0.0-beta.9
+ */
+module.exports = or(isMap, isSet)
diff --git a/src/deps/is/dataView.js b/src/deps/is/dataView.js
new file mode 100644
index 0000000..806982f
--- /dev/null
+++ b/src/deps/is/dataView.js
@@ -0,0 +1,8 @@
+const tagEq = require('./tagEq')
+
+/**
+ * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView mozilla-data-view}
+ * @see {@link mozilla-data-view}
+ * @type {Function}
+ */
+module.exports = tagEq('[object DataView]')
diff --git a/src/deps/is/date.js b/src/deps/is/date.js
index 5ae70a1..1ad6290 100644
--- a/src/deps/is/date.js
+++ b/src/deps/is/date.js
@@ -1,14 +1,21 @@
const toS = require('./toS')
/**
- * @param {*} x value
+ * @param {*} x value
* @return {boolean} isDate
*
* @since 3.0.0
* @memberOf is
- * @func isDate
+ *
+ * @func
+ * @name isDate
* @extends toS
*
+ * {@link https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Date mozilla-date}
+ * {@link https://nodejs.org/api/util.html#util_util_isdate_object node-util-isdate}
+ * @see {@link node-util-isdate}
+ * @see {@link mozilla-date}
+ *
* @example
*
* isDate(new Date())
@@ -32,6 +39,7 @@ const toS = require('./toS')
* class Eh extends Date()
* isDate(new Eh())
* //=> true
+ *
*/
module.exports = function isDate(x) {
return toS(x) === '[object Date]'
diff --git a/src/deps/is/dot.js b/src/deps/is/dot.js
index 007c49c..ed212b4 100644
--- a/src/deps/is/dot.js
+++ b/src/deps/is/dot.js
@@ -1,6 +1,26 @@
+const includes = require('../conditional/includes')
const isArray = require('./array')
const isString = require('./string')
+/**
+ * @since 3.0.0
+ * @memberOf is
+ * @name isDot
+ *
+ * @TODO update with conditional
+ *
+ * @param {*} x value to check
+ * @return {boolean} x isDot
+ *
+ * @see isArray
+ * @see isString
+ * @see includes
+ *
+ * @example
+ * isDot('eh.oh') //=> true
+ * isDot('eh') //=> false
+ * isDot(['eh', 'oh']) //=> true
+ */
module.exports = function isDot(x) {
return isArray(x) || (isString(x) && x.includes('.'))
}
diff --git a/src/deps/is/element.js b/src/deps/is/element.js
new file mode 100644
index 0000000..58ba063
--- /dev/null
+++ b/src/deps/is/element.js
@@ -0,0 +1,32 @@
+const isObjectNotNull = require('./objNotNull')
+const isPlainObject = require('./objPlain')
+
+/**
+ * Checks if `x` is likely a DOM element.
+ *
+ * @since 5.0.0-beta.5
+ * @fork 0.1.0
+ * @category Lang
+ * @param {*} x The x to check.
+ * @return {boolean} Returns `true` if `x` is a DOM element, else `false`.
+ *
+ * {@link https://github.com/sstephenson/prototype/blob/master/src/prototype/lang/object.js#L347 prototype-is-element}
+ * {@link https://github.com/lodash/lodash/blob/master/isElement.js lodash-is-element}
+ * @see {@link lodash-is-element}
+ * @see {@link prototype-is-element}
+ *
+ * @example
+ *
+ * isElement(document.body)
+ * //=> true
+ *
+ * isElement('')
+ * //=> false
+ *
+ */
+function isElement(x) {
+ // typeof HTMLElement === 'object' ? o instanceof HTMLElement : // DOM2
+ return isObjectNotNull(x) && x.nodeType === 1 && !isPlainObject(x)
+}
+
+module.exports = isElement
diff --git a/src/deps/is/empty.js b/src/deps/is/empty.js
new file mode 100644
index 0000000..1d207ae
--- /dev/null
+++ b/src/deps/is/empty.js
@@ -0,0 +1,70 @@
+const EMPTY_STRING = require('../native/EMPTY_STRING')
+const size = require('../util/size')
+const isNullOrUndefined = require('./nullOrUndefined')
+const isObj = require('./objTypeof')
+
+/* prettier-ignore */
+/**
+ * Returns `true` if the given value is its type's empty value;
+ * `false` otherwise.
+ *
+ * @since 5.0.0-beta.1
+ * @memberOf is
+ *
+ * @param {*} x value to check if empty
+ * @return {boolean}
+ *
+ * @func
+ * @fork v0.1.0
+ * @category Logic
+ * @sig a -> Boolean
+ *
+ * {@link https://github.com/js-data/js-data/blob/v2/src/utils.js#L98 js-data-is-empty}
+ * {@link https://github.com/wycats/handlebars.js/blob/master/lib/handlebars/utils.js#L85 handlebars-is-empty}
+ * {@link https://github.com/bitovi/u/blob/master/js/object/isEmptyObject.js can-u-is-empty-object}
+ * {@link https://github.com/jashkenas/underscore/blob/master/underscore.js#L1293 underscore-is-empty}
+ * {@link https://github.com/ramda/ramda/issues/1228 ramda-is-empty}
+ * @see {@link can-u-is-empty-object}
+ * @see {@link underscore-is-empty}
+ * @see {@link ramda-is-empty}
+ * @see {@link handlebars-is-empty}
+ * @see {@link js-data-is-empty}
+ * @see empty
+ *
+ * @example
+ *
+ * isEmpty([1, 2, 3]); //=> false
+ * isEmpty([]); //=> true
+ * isEmpty(''); //=> true
+ * isEmpty(null); //=> false
+ * isEmpty({}); //=> true
+ * isEmpty({length: 0}); //=> false
+ *
+ */
+module.exports = function isEmpty(x) {
+ if (x === EMPTY_STRING) {
+ return true
+ }
+ else if (isNullOrUndefined(x)) {
+ return false
+ }
+ else if (isObj(x)) {
+ // @NOTE
+ // for (const property in x)
+ // return true
+ // return false
+ return size(x) === 0
+ }
+ else {
+ return false
+ }
+
+ // @NOTE old version
+ // else return (
+ // // null|undefined = empty
+ // // isNullOrUndefined(x) ||
+ // // '' = empty
+ // // [] | {} = empty
+ // keys(x).length === 0
+ // )
+}
diff --git a/src/deps/is/enumerable.js b/src/deps/is/enumerable.js
index bf3d111..d1a7464 100644
--- a/src/deps/is/enumerable.js
+++ b/src/deps/is/enumerable.js
@@ -1,2 +1,40 @@
-module.exports = (obj, prop) =>
- Object.prototype.propertyIsEnumerable.call(obj, prop)
+const propertyIsEnumerable = require('../native/propertyIsEnumerable')
+const curry = require('../fp/curry')
+
+/**
+ * @desc object at property is enumerable
+ * @memberOf is
+ * @since 3.0.0
+ *
+ * @param {Object | *} obj
+ * @param {string | *} prop
+ * @return {boolean} obj[prop] is enumerable
+ *
+ * @func
+ * @name isEnumerable
+ * @type {Function}
+ *
+ * {@link https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/propertyIsEnumerable mozilla-propertyisenumerable}
+ * @see {@link mozilla-propertyisenumerable}
+ *
+ * @TODO use fp/call
+ *
+ * @example
+ *
+ * const obj = {eh: true}
+ * isEnumerable(obj, 'eh')
+ * //=> true
+ *
+ * const objPropEnumerable = isEnumerable(obj)
+ * objPropEnumerable('eh')
+ * //=> true
+ *
+ * Object.defineProperty(obj, 'length', {
+ * enumerable: false,
+ * value: () => Object.keys(obj).length,
+ * })
+ * isEnumerable(obj, 'length')
+ * //=> false
+ *
+ */
+module.exports = curry(2, (obj, prop) => propertyIsEnumerable.call(obj, prop))
diff --git a/src/deps/is/eqeq.js b/src/deps/is/eqeq.js
deleted file mode 100644
index 49df00b..0000000
--- a/src/deps/is/eqeq.js
+++ /dev/null
@@ -1,4 +0,0 @@
-// @TODO use this in the bitwise arithmetic validation builder
-// @TODO check v8 on this
-// eslint-disable-next-line
-module.exports = (x, y) => x == y
diff --git a/src/deps/is/error.js b/src/deps/is/error.js
index 3450489..1118e3d 100644
--- a/src/deps/is/error.js
+++ b/src/deps/is/error.js
@@ -1,11 +1,23 @@
const toS = require('./toS')
/**
+ * Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`,
+ * `SyntaxError`, `TypeError`, or `URIError` object.
+ *
+ * @version 3.0.0 <- adding .message prop check
+ * @version 2.0.0 <- just string tag
+ * @version 1.0.0 <- was instanceof
+ * @since 4.0.0
+ * @memberOf is
+ *
* @param {*} x value
* @return {boolean} isError
*
- * @memberOf is
- * @func isError
+ * @name isError
+ * @func
+ *
+ * {@link https://nodejs.org/api/util.html#util_util_iserror_object node-util-iserror}
+ * @see {@link node-util-iserror}
*
* @example
*
@@ -34,5 +46,8 @@ const toS = require('./toS')
*/
module.exports = function isError(x) {
return toS(x) === '[object Error]'
+ // return tag == '[object Error]' || tag == '[object DOMException]' ||
+ // (typeof value.message == 'string' && typeof value.name == 'string' && !isPlainObject(value))
+
// x instanceof Error ||
}
diff --git a/src/deps/is/extensible.js b/src/deps/is/extensible.js
new file mode 100644
index 0000000..7007e95
--- /dev/null
+++ b/src/deps/is/extensible.js
@@ -0,0 +1,11 @@
+/**
+ * @desc Get references to ES5 object methods.
+ * @since 5.0.0-beta.6
+ * @type {Function}
+ *
+ * {@link https://tc39.github.io/ecma262/#sec-isextensible-o emca-is-extensible}
+ * {@link https://github.com/facebook/immutable-js/blob/master/src/Hash.js#L157 immutable-js-is-extensible}
+ * @see {@link immutable-js-is-extensible}
+ * @see {@link emca-is-extensible}
+ */
+module.exports = Object.isExtensible
diff --git a/src/deps/is/falsy.js b/src/deps/is/falsy.js
new file mode 100644
index 0000000..3916c3d
--- /dev/null
+++ b/src/deps/is/falsy.js
@@ -0,0 +1,32 @@
+const isReal = require('./real')
+const isFalse = require('./false')
+
+/**
+ * @desc is falsy value
+ * @since 5.0.0-beta.5
+ * @memberOf is
+ *
+ * @param {null | undefined | false | 0 | '' | *} x value to check
+ * @return {boolean} x is Falsy
+ *
+ * @name isFalsy
+ *
+ * {@link https://developer.mozilla.org/en-US/docs/Glossary/Falsy mozilla-falsy}
+ * @see {@link mozilla-falsy}
+ * @see is/real
+ *
+ * @example
+ *
+ * isFalsy(null) //=> true
+ * isFalsy(undefined) //=> true
+ * isFalsy(0) //=> true
+ * isFalsy(NaN) //=> true
+ * isFalsy('') //=> true
+ * isFalsy(1) //=> false
+ * isFalsy({}) //=> false
+ * isFalsy([]) //=> false
+ *
+ */
+module.exports = function isFalsy(x) {
+ return !isReal(x) || isFalse(x) || x === 0 || x === ''
+}
diff --git a/src/deps/is/finite.js b/src/deps/is/finite.js
new file mode 100644
index 0000000..2942cb1
--- /dev/null
+++ b/src/deps/is/finite.js
@@ -0,0 +1,26 @@
+/**
+ * @desc is not infinity, and not nan, but this parses a float and is slower
+ * @since 0.0.1
+ * @version 5.0.0
+ * @memberOf is
+ *
+ * @param {number} n value to check
+ * @return {boolean}
+ *
+ * {@link https://tc39.github.io/ecma262/#sec-isfinite-number emca-isfinite}
+ * {@link https://github.com/lodash/lodash/blob/master/toFinite.js lodash-to-finite}
+ * {@link http://stackoverflow.com/questions/18082/validate-decimal-numbers-in-javascript-isnumeric stack-overflow-isnumeric}
+ * @see {@link emca-isfinite}
+ * @see {@link stack-overflow-isnumeric}
+ * @see {@link lodash-to-finite}
+ * @see is/numberish
+ * @see is/infinity
+ *
+ * @example
+ * isFinite(100) //=> true
+ * isFinite('100') //=> true
+ * isFinite(Infinity) //=> false
+ */
+module.exports = function isFiniteNumber(n) {
+ return !isNaN(parseFloat(n)) && isFinite(n)
+}
diff --git a/src/deps/is/flattenable.js b/src/deps/is/flattenable.js
new file mode 100644
index 0000000..cd268a5
--- /dev/null
+++ b/src/deps/is/flattenable.js
@@ -0,0 +1,41 @@
+const spreadableSymbol = require('../symbols/spreadable')
+const toBoolean = require('../cast/toBoolean')
+// is
+const isArguments = require('./arguments')
+const isArray = require('./array')
+
+/**
+ * Checks if `value` is a flattenable `arguments` object or array.
+ *
+ * @since 5.0.0-beta.5
+ * @alias isConcatSpreadable
+ * @alias isSpreadable
+ *
+ * @param {*} value The value to check.
+ * @return {boolean} Returns `true` if `value` is flattenable, else `false`.
+ *
+ * @example
+ *
+ * (function() {
+ * isFlattenable(arguments) //=> true
+ * })([0, 1, 2])
+ *
+ * @example
+ *
+ * isFlattenable([[0], [1]])
+ * //=> true
+ *
+ * @example
+ * const obj = {}
+ * obj[Symbol.isConcatSpreadable] = true
+ * isFlattenable(obj)
+ * //=> true
+ *
+ */
+function isFlattenable(value) {
+ return isArray(value) ||
+ isArguments(value) ||
+ toBoolean(spreadableSymbol && value && value[spreadableSymbol])
+}
+
+module.exports = isFlattenable
diff --git a/src/deps/is/function.js b/src/deps/is/function.js
index 290d007..8ead9f1 100644
--- a/src/deps/is/function.js
+++ b/src/deps/is/function.js
@@ -1,12 +1,12 @@
/**
* Checks if `value` is classified as a `Function` object.
- * @category Lang
+ * @memberOf is
+ * @since 3.0.0
*
* @param {*} x The value to check.
* @return {boolean} x isFunction
*
- * @since 3.0.0
- * @memberOf is
+ * @category Lang
* @func isFunction
*
* @NOTE || x instanceof Function
@@ -18,6 +18,21 @@
* https://github.com/krambuhl/custom-event-polyfill/issues/2
* browser usage is < 0.3%, very edge case
*
+ * {@link https://github.com/gcanti/tcomb/blob/master/lib/isFunction.js tcomb-isfunction}
+ * {@link https://nodejs.org/api/util.html#util_util_isfunction_object node-util-is-function}
+ * {@link https://github.com/ramda/ramda/blob/master/src/internal/_isFunction.js ramda-is-function}
+ * {@link https://github.com/lodash/lodash/blob/master/functions.js#L22 lodash-is-function}
+ * {@link https://github.com/infernojs/inferno/blob/master/packages/inferno-shared/src/index.ts#L38 inferno-is-function}
+ * {@link https://github.com/js-data/js-data/blob/v2/src/utils.js#L77 js-data-is-function}
+ * {@link http://underscorejs.org/docs/underscore.html#section-141 underscore-is-function}
+ * @see {@link tcomb-is-function}
+ * @see {@link underscore-is-function}
+ * @see {@link js-data-is-function}
+ * @see {@link inferno-is-function}
+ * @see {@link lodash-is-function}
+ * @see {@link ramda-is-function}
+ * @see {@link node-util-is-function}
+ *
* @example
*
* isFunction(function() {})
@@ -32,7 +47,8 @@
* isFunction('')
* //=> false
* isFunction(/abc/)
- * // => false
+ * //=> false
+ *
*/
module.exports = function isFunction(x) {
return typeof x === 'function'
diff --git a/src/deps/is/generator.js b/src/deps/is/generator.js
index ada01b1..05b8343 100644
--- a/src/deps/is/generator.js
+++ b/src/deps/is/generator.js
@@ -7,11 +7,13 @@ const toS = require('./toS')
* @return {boolean} x isGenerator
*
* @alternate fn.constructor.name === 'GeneratorFunction'
- * @see https://github.com/jonschlinkert/kind-of/blob/master/index.js#L66
+ *
+ * {@link https://github.com/jonschlinkert/kind-of/blob/master/index.js#L66}
+ * @see {@link kind-of}
*
* @example
*
- * isGenerator(*function() {})
+ * isGenerator(*function() {})
* //=> true
* isGenerator(function() {})
* //=> false
diff --git a/src/deps/is/hasDecimals.js b/src/deps/is/hasDecimals.js
new file mode 100644
index 0000000..e4624fa
--- /dev/null
+++ b/src/deps/is/hasDecimals.js
@@ -0,0 +1,34 @@
+/**
+ * @desc remainder / 1 is 0
+ * @since 5.0.00beta.6
+ * @memberOf is
+ *
+ * @param {number | string | *} x value to check
+ * @return {boolean} x hasDecimals
+ *
+ * @func
+ * @name hasDecimals
+ * @alias isDecimalNumberish
+ *
+ * @TODO could ensure decimalNumber or isString first? (safety plus decision tree)
+ *
+ * {@link https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators#Remainder_() mozilla-arithmetic-operators-remainder}
+ * {@link https://stackoverflow.com/questions/3803331/how-can-i-modulo-when-my-numbers-start-from-1-not-zero stack-overflow-modulo-start-from-zero}
+ * @see {@link mozilla-arithmetic-operators-remainder}
+ * @see {@link stack-overflow-modulo-start-from-zero}
+ * @see is/validIndex
+ *
+ * @example
+ *
+ * hasDecimals(1) //=> false
+ * hasDecimals(Number(1)) //=> false
+ * hasDecimals(NaN) //=> false
+ * hasDecimals(new Number(1)) //=> false
+ * hasDecimals('') //=> false
+ * hasDecimals('100') //=> false
+ *
+ * hasDecimals('100.10') //=> true
+ * hasDecimals(100.1) //=> true
+ *
+ */
+module.exports = x => x % 1 === 0
diff --git a/src/deps/is/hasIn.js b/src/deps/is/hasIn.js
index ec50237..97fee85 100644
--- a/src/deps/is/hasIn.js
+++ b/src/deps/is/hasIn.js
@@ -2,13 +2,31 @@ const isNull = require('./null')
const isIn = require('./in')
/**
+ * @TODO can depreciate now that there is safety in `isIn`
+ *
+ * @desc isIn, but first checks it is not null
+ * @since 5.0.0
+ * @memberOf is
+ *
* @param {Object} obj object to check
* @param {any} prop property to check in object
* @return {boolean}
*
+ * {@link https://github.com/jashkenas/underscore/blob/master/underscore.js#L1367 underscore-has}
+ * @see {@link underscore-has}
+ *
* @extends isNull
* @extends isIn
+ *
+ * @example
+ *
+ * hasIn({}, 'eh') //=> false
+ * hasIn(null, 'eh') //=> false
+ * hasIn({eh: true}, 'eh') //=> true
+ *
*/
-module.exports = function hasIn(obj, prop) {
+function hasIn(obj, prop) {
return !isNull(obj) && isIn(obj, prop)
}
+
+module.exports = hasIn
diff --git a/src/deps/is/in.js b/src/deps/is/in.js
index 4e8accb..2f9c9ee 100644
--- a/src/deps/is/in.js
+++ b/src/deps/is/in.js
@@ -1,12 +1,31 @@
-/**
- * @func
- * @type {Function}
- * @typedef Function() {}
- */
+const toObject = require('../cast/toObj')
/**
+ * @desc prop is in Object(obj)
+ * @since 5.0.0
+ * @memberOf is
+ *
* @param {Object} obj object to check property of
* @param {Primitive} prop property in obj
* @return {boolean} property
+ *
+ * @func
+ * @type {Function}
+ * @name isIn
+ *
+ * @example
+ *
+ * isIn({eh: true}, 'eh') //=> true
+ * isIn({eh: true}, 'oh') //=> false
+ *
*/
-module.exports = (obj, prop) => prop in Object(obj)
+module.exports = (obj, prop) => (prop in toObject(obj))
+
+// @TODO
+// function isIn(set) {
+// return function(d) {
+// return !set ? false
+// : set.indexOf ? ~set.indexOf(d)
+// : d in set
+// }
+// }
diff --git a/src/deps/is/indexable.js b/src/deps/is/indexable.js
new file mode 100644
index 0000000..91ef9b0
--- /dev/null
+++ b/src/deps/is/indexable.js
@@ -0,0 +1,24 @@
+const or = require('../conditional/or')
+const isStringPrimitive = require('./stringPrimitive')
+const isObjNotNull = require('./objNotNull')
+
+/**
+ * @desc check whether a value can be indexed
+ * @since 5.0.0-beta.6
+ * @name isIndexable
+ * @memberOf is
+ *
+ * @param {Object|string|*} x value to check
+ * @return {boolean} !isNill x & x isString or & x isObj
+ *
+ * @example
+ *
+ * isIndexable({}) //=> true
+ * isIndexable('eh') //=> true
+ * isIndexable([]) //=> true
+ * isIndexable(null) //=> false
+ * isIndexable(undefined) //=> false
+ * isIndexable(-1) //=> false
+ *
+ */
+module.exports = or(isStringPrimitive, isObjNotNull)
diff --git a/src/deps/is/infinity.js b/src/deps/is/infinity.js
new file mode 100644
index 0000000..eba6025
--- /dev/null
+++ b/src/deps/is/infinity.js
@@ -0,0 +1,24 @@
+const isTrue = require('./true')
+
+/**
+ * @name isInfinity
+ * @since 5.0.0-beta.6
+ * @memberOf is
+ *
+ * @param {number} x value to check
+ * @param {boolean} [positiveNegative=undefined] should check for -+
+ * @return {boolean} x isInfinity
+ *
+ * @example
+ *
+ * isInfinity(Infinity) //=> true
+ * isInfinity(-Infinity) //=> false
+ * isInfinity(-Infinity, true) //=> true
+ * isInfinity(0) //=> false
+ *
+ */
+module.exports = function isInfinity(x, positiveNegative) {
+ if (x === Infinity) return true
+ else if (isTrue(positiveNegative)) return x === -Infinity || x === +Infinity
+ else return false
+}
diff --git a/src/deps/is/instanceOf.js b/src/deps/is/instanceOf.js
new file mode 100644
index 0000000..a58caad
--- /dev/null
+++ b/src/deps/is/instanceOf.js
@@ -0,0 +1,40 @@
+const curry = require('../fp/curry')
+const isNil = require('./nullOrUndefined')
+
+/**
+ * @desc check instanceof
+ * @since 5.0.0-beta.4
+ * @memberOf is
+ * @curried 2
+ *
+ * @param {Object} instanceToCheckAgainst check the second arg against this
+ * @param {Object} isThisInstanceOfThat check this against first arg
+ * @return {boolean} arg2 instanceof arg1
+ *
+ * @see http://documentcloud.github.io/underscore-contrib/#isinstanceof
+ * @see https://github.com/lodash/lodash/issues/620
+ * @see https://github.com/ramda/ramda/commit/9d4cb895595aca3d83ce0a4b10416ae7302bd8ac
+ * @see https://github.com/ramda/ramda/blob/v0.24.1/src/is.js
+ *
+ * @example
+ *
+ * const isObjInstance = instanceOf(Object)
+ * isObjInstance({})
+ * //=> true
+ *
+ * const isArrInstance = instanceOf(Array)
+ * isArrInstance({})
+ * //=> false
+ *
+ * isArrInstance(new Array)
+ * //=> true
+ *
+ */
+function instanceOf(instanceToCheckAgainst, isThisInstanceOfThat) {
+ return !isNil(instanceToCheckAgainst) &&
+ !isNil(isThisInstanceOfThat) &&
+ isThisInstanceOfThat instanceof instanceToCheckAgainst
+ // || arg1.constructor === arg2
+}
+
+module.exports = curry(2, instanceOf)
diff --git a/src/deps/is/integer.js b/src/deps/is/integer.js
new file mode 100644
index 0000000..d224f4d
--- /dev/null
+++ b/src/deps/is/integer.js
@@ -0,0 +1,25 @@
+/**
+ * Determine if the passed argument is an integer.
+ * @since 5.0.0-beta.5
+ * @memberOf is
+ *
+ * @param {*} x number to check if it is an integer
+ * @return {boolean} x is integer
+ *
+ * @category Type
+ *
+ * {@link https://tc39.github.io/ecma262/#sec-isinteger emca-is-integer}
+ * {@link https://github.com/ramda/ramda/blob/master/src/internal/_isInteger.js ramda-is-integer}
+ * @see {@link ramda-is-integer}
+ * @see {@link emca-is-integer}
+ *
+ * @example
+ *
+ * isInteger(10) //=> true
+ * isInteger(3.2) //=> false
+ * isInteger(false) //=> false
+ *
+ */
+module.exports = Number.isInteger || function _isInteger(x) {
+ return (x << 0) === x
+}
diff --git a/src/deps/is/iteratable.js b/src/deps/is/iteratable.js
new file mode 100644
index 0000000..7435445
--- /dev/null
+++ b/src/deps/is/iteratable.js
@@ -0,0 +1,83 @@
+const isObjNotNull = require('./objNotNull')
+const isArray = require('./array')
+const isRegExp = require('./regexp')
+const isError = require('./error')
+const isDate = require('./date')
+const isSymbol = require('./symbol')
+const isAsyncish = require('./asyncish')
+const isPrimitive = require('./primitive')
+
+/**
+ * @desc is able to be iterated on
+ * @since 5.0.0-beta.1
+ *
+ * @param {*} x node is iteratable
+ * @return {boolean} x isIteratable
+ *
+ * {@link https://github.com/canjs/can-util/blob/master/js/is-iterable/is-iterable.js can-is-iteratable}
+ * @see {@link can-is-iteratable}
+ *
+ * @extends isObj
+ * @extends isArray
+ * @extends isPrimitive
+ * @extends isRegExp
+ * @extends isDate
+ * @extends isSymbol
+ * @extends isAsync
+ * @extends isError
+ *
+ * @example
+ *
+ * isIteratable([]) //=> true
+ * isIteratable({}) //=> true
+ * isIteratable(new Date()) //=> false
+ * isIteratable(Symbol('eh')) //=> false
+ * isIteratable(new Promise(r => r())) //=> false
+ * isIteratable(new Error('eh')) //=> false
+ *
+ */
+module.exports = function isIteratable(x) {
+ // ez ones
+ if (isObjNotNull(x) || isArray(x)) return true
+
+ const notIteratable =
+ isPrimitive(x) ||
+ isRegExp(x) ||
+ isDate(x) ||
+ isSymbol(x) ||
+ isAsyncish(x) ||
+ // isNative(x) ||
+ isError(x)
+
+ // not-not is iteratable
+ return !notIteratable
+
+ // if (notIteratable) return false
+ // else return true
+ // if (isNullOrUndefined(node)) {
+ // }
+ // else if (isString(node)) {
+ // }
+ // else if (isNumber(node)) {
+ // }
+ // else if (isBoolean(node)) {
+ // }
+ // else if (isRegExp(node)) {
+ // }
+ // else if (isDate(node)) {
+ // }
+ // else if (isSymbol(node) || isAsyncish(node)) {
+ // }
+ // else if (isNative(node)) {
+ // }
+ // else {
+ // return true
+ // }
+ // return false
+}
+
+// function isSpecial(x) {
+// // isPromise(x) ||
+// return isSymbol(x) || isError(x) ||
+// // || isGenerator(x)
+// }
diff --git a/src/deps/is/iterator.js b/src/deps/is/iterator.js
index 2a66ac8..116486c 100644
--- a/src/deps/is/iterator.js
+++ b/src/deps/is/iterator.js
@@ -6,8 +6,10 @@ const toS = require('./toS')
*
* @since 3.0.0
* @memberOf is
- * @func isIterator
+ * @func
+ * @name isIterator
* @see https://github.com/jonschlinkert/kind-of/pull/12
+ * @see https://github.com/facebook/immutable-js/blob/master/src/Iterator.js#L59
*
* @example
*
diff --git a/src/deps/is/map.js b/src/deps/is/map.js
index 7e2243a..ac9fbc2 100644
--- a/src/deps/is/map.js
+++ b/src/deps/is/map.js
@@ -2,13 +2,19 @@ const toS = require('./toS')
/**
* @desc Checks if `value` is classified as a `Map` object.
+ * @since 3.0.0
+ * @memberOf is
+ *
* @param {*} x value
* @return {boolean} isMap
*
- * @since 3.0.0
- * @memberOf is
- * @func isMap
- * @see https://github.com/jonschlinkert/kind-of
+ * @func
+ * @name isMap
+ *
+ * {@link https://github.com/mobxjs/mobx/blob/master/src/utils/utils.ts#L210 mobx-is-map}
+ * {@link https://github.com/jonschlinkert/kind-of kind-of}
+ * @see {@link kind-of}
+ * @see {@link mobx-is-map}
*
* @example
*
@@ -25,7 +31,7 @@ const toS = require('./toS')
* isMap(1)
* //=> false
* isMap(new WeakMap)
- * // => false
+ * //=> false
*
* @example
*
diff --git a/src/deps/is/mapish.js b/src/deps/is/mapish.js
index 395f35e..82a6c9c 100644
--- a/src/deps/is/mapish.js
+++ b/src/deps/is/mapish.js
@@ -7,6 +7,7 @@ const isMap = require('./map')
* @memberOf is
* @since 3.0.0
* @extends isMap
+ * @alias isMapLike
* @variation also checks `instanceof Chainable`
*
* @param {*} x value to check
diff --git a/src/deps/is/match.js b/src/deps/is/match.js
new file mode 100644
index 0000000..0002ab3
--- /dev/null
+++ b/src/deps/is/match.js
@@ -0,0 +1,10 @@
+const curry = require('../fp/curry')
+const matcher = require('../matcher/matcher')
+const isEmpty = require('../is/empty')
+
+// @TODO document
+// @TODO ensure it's best here & not in matcher/
+//
+// pipe(matcher, isEmpty, not)
+const isMatch = (inputs, patterns) => !isEmpty(matcher(inputs, patterns))
+module.exports = curry(2, isMatch)
diff --git a/src/deps/is/matchWith.js b/src/deps/is/matchWith.js
new file mode 100644
index 0000000..2910446
--- /dev/null
+++ b/src/deps/is/matchWith.js
@@ -0,0 +1,14 @@
+const curry = require('../fp/curry')
+const matcher = require('../matcher/matcher')
+const isEmpty = require('../is/empty')
+
+/**
+ * @since 5.0.0-beta.6
+ * @TODO
+ * @name isMatchWith
+ * @func
+ * @memberOf is
+ */
+const isMatchWith = (inputs, patterns) => !isEmpty(matcher(inputs, patterns))
+
+module.exports = curry(2, isMatchWith)
diff --git a/src/deps/is/matcher.js b/src/deps/is/matcher.js
index 4b4b508..2ed146c 100644
--- a/src/deps/is/matcher.js
+++ b/src/deps/is/matcher.js
@@ -1,3 +1,4 @@
+const or = require('../conditional/or')
const isFunction = require('./function')
const isRegExp = require('./regexp')
@@ -9,6 +10,10 @@ const isRegExp = require('./regexp')
* @param {*} x value to check
* @return {boolean} isFunction || isRegExp
*
+ * @see is/regexp
+ * @see is/function
+ * @see conditionals/or
+ *
* @example
*
* isMatcher(/(.*)/)
@@ -23,5 +28,6 @@ const isRegExp = require('./regexp')
* //=> false
*
*/
-module.exports = x => isFunction(x) || isRegExp(x)
+module.exports = or(isFunction, isRegExp)
+// x => isFunction(x) || isRegExp(x)
// x instanceof RegExp
diff --git a/src/deps/is/native.js b/src/deps/is/native.js
index 978cb59..2461b8c 100644
--- a/src/deps/is/native.js
+++ b/src/deps/is/native.js
@@ -1,3 +1,6 @@
+const funcToString = require('../native/functionToString')
+const matchNative = require('../regexp/matchNative')
+
/**
* @desc based on isNative from react-fibers, based on isNative() from Lodash
* @since 4.0.6
@@ -7,37 +10,29 @@
* @param {*} x value to check
* @return {boolean}
*
+ * {@link https://esdiscuss.org/topic/spec-feedback-on-rev-6#content-2 esdiscuss-functiontostring}
+ * {@link https://github.com/lodash/lodash/issues/2185 lodash-functiontostring-issue}
+ * {@link http://tc39.github.io/Function-prototype-toString-revision/ functiontostring-emca}
+ * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/toString Function.toString}
+ *
+ * @see {@link Function.toString}
+ * @see {@link functiontostring-emca}
+ * @see {@link lodash-functiontostring-issue}
+ * @see {@link esdiscuss-functiontostring}
+ *
* @example
*
* isNative(Array.prototype.push)
- * // => true
+ * //=> true
*
* isNative(function normalFunction() {})
- * // => false
+ * //=> false
*
*/
module.exports = function isNative(x) {
- //
- var funcToString = Function.prototype.toString
-
- var reIsNative = RegExp(
- '^' +
- funcToString
- // Take an example native function source for comparison
- .call(Object.prototype.hasOwnProperty)
- // Strip regex characters so we can use it for regex
- .replace(/[\\^$.*+?()[\]{}|]/g, '\\$&')
- // Remove hasOwnProperty from the template to make it generic
- .replace(
- /hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,
- '$1.*?'
- ) +
- '$'
- )
-
try {
- var source = funcToString.call(x)
- return reIsNative.test(source)
+ const source = funcToString.call(x)
+ return matchNative.test(source)
}
catch (err) {
return false
diff --git a/src/deps/is/negativeInfinity.js b/src/deps/is/negativeInfinity.js
new file mode 100644
index 0000000..0383249
--- /dev/null
+++ b/src/deps/is/negativeInfinity.js
@@ -0,0 +1,17 @@
+/* eslint eqeqeq: "OFF" */
+
+const INFINITY = require('../native/INFINITY')
+
+/**
+ * @name isNegativeInfinity
+ * @since 5.0.0-beta.6
+ *
+ * @param {*} x == -INFINITY
+ * @return {boolean}
+ *
+ * @example
+ *
+ * Infinity / -1 == -INFINITY //= true -> '-0'
+ *
+ */
+module.exports = x => 1 / x == -INFINITY
diff --git a/src/deps/is/notNested.js b/src/deps/is/notNested.js
new file mode 100644
index 0000000..0e640d2
--- /dev/null
+++ b/src/deps/is/notNested.js
@@ -0,0 +1,29 @@
+const isStringOrNumber = require('../is/stringOrNumber')
+const isReal = require('../is/real')
+const isBoolean = require('../is/boolean')
+const isRegExp = require('../is/regexp')
+const isError = require('../is/error')
+
+/**
+ * @since 5.0.0
+ * @param {*} x value to check
+ * @return {boolean} x isNotNested
+ *
+ * @example
+ *
+ * isNotNested('') //=> true
+ * isNotNested(true) //=> true
+ * isNotNested(new RegExp()) //=> true
+ * isNotNested(new Error('eh')) //=> false
+ * isNotNested(null) //=> false
+ *
+ */
+module.exports = function isNotNested(x) {
+ return (
+ isStringOrNumber(x) ||
+ isBoolean(x) ||
+ !isReal(x) ||
+ isError(x) ||
+ isRegExp(x)
+ )
+}
diff --git a/src/deps/is/notRealOrIsEmpty.js b/src/deps/is/notRealOrIsEmpty.js
new file mode 100644
index 0000000..d042895
--- /dev/null
+++ b/src/deps/is/notRealOrIsEmpty.js
@@ -0,0 +1,17 @@
+const and = require('../conditional/and')
+const not = require('../conditional/not')
+const isReal = require('./real')
+const isEmpty = require('./empty')
+
+/**
+ * @SIZE: another 10bytes for these fns
+ * @name isNotRealOrIsEmpty
+ *
+ * @see is/isReal
+ * @see is/isEmpty
+ * @see conditional/and
+ * @see conditional/not
+ *
+ * @type {Function}
+ */
+module.exports = and(not(isReal), isEmpty)
diff --git a/src/deps/is/null.js b/src/deps/is/null.js
index 569806d..812ee75 100644
--- a/src/deps/is/null.js
+++ b/src/deps/is/null.js
@@ -4,8 +4,13 @@
*
* @since 3.0.0
* @memberOf is
- * @func isNull
- *
+ *
+ * @func
+ * @name isNull
+ *
+ * {@link https://nodejs.org/api/util.html#util_util_isnull_object node-util-isnull}
+ * @see {@link node-util-isnull}
+ *
* @example
*
* isNull(null)
diff --git a/src/deps/is/nullOrUndefined.js b/src/deps/is/nullOrUndefined.js
index b944e1a..6667582 100644
--- a/src/deps/is/nullOrUndefined.js
+++ b/src/deps/is/nullOrUndefined.js
@@ -3,19 +3,29 @@ const isUndefined = require('./undefined')
/**
* @desc Checks if `value` is `null` or `undefined`.
- * @alias isNil
- * @category Lang
+ * @since 4.0.0-alpha.1
+ * @memberOf is
*
* @param {*} x value
* @return {boolean} isNullOrUndefined
*
- * @since 4.0.0-alpha.1
- * @memberOf is
- * @func isNullOrUndefined
+ * @name isNullOrUndefined
+ * @alias isNill
+ * @alias isNil
+ *
+ * @func
+ * @category Lang
*
+ * {@link https://github.com/gcanti/tcomb/blob/master/lib/isNil.js tcomb-isnill}
+ * {@link http://ramdajs.com/docs/#isNil ramda-isnill}
+ * {@link https://github.com/infernojs/inferno/blob/master/packages/inferno-shared/src/index.ts#L23 inferno-isnullorundefined}
+ * {@link https://nodejs.org/api/util.html#util_util_isnullorundefined_object node-util-isnullorundefined}
+ * @see {@link inferno-isnullorundefined}
+ * @see {@link ramda-isnil}
+ * @see {@link tcomb-isnil}
+ * @see {@link node-util-isnullorundefined}
* @see is/null
* @see is/undefined
- * @see https://github.com/infernojs/inferno/blob/master/packages/inferno-shared/src/index.ts#L23
*
* @example
*
diff --git a/src/deps/is/number.js b/src/deps/is/number.js
index 415d07b..fbe656f 100644
--- a/src/deps/is/number.js
+++ b/src/deps/is/number.js
@@ -2,17 +2,25 @@ const toS = require('./toS')
const isNumberPrimitive = require('./numberPrimitive')
/**
- * @param {*} x value
- * @return {boolean} isNumber
- *
* @since 3.0.0
* @memberOf is
- * @func isNumber
- * @see is/real
+ *
+ * @param {*} x value
+ * @return {boolean} isNumber
+ *
+ * @func
+ * @name isNumber
* @extends numberPrimitive
* @variation also returns true for new Number object
*
- * @see http://stackoverflow.com/questions/18082/validate-decimal-numbers-in-javascript-isnumeric
+ * {@link https://github.com/infernojs/inferno/blob/master/packages/inferno-shared/src/index.ts#L23 inferno-isnumber}
+ * {@link http://stackoverflow.com/questions/18082/validate-decimal-numbers-in-javascript-isnumeric stack-overflow-isnumber}
+ * {@link https://github.com/gcanti/tcomb/blob/master/lib/isNumber.js tcomb-isnumber}
+ * @see {@link stack-overflow-isnumber}
+ * @see {@link tcomb-isnumber}
+ * @see {@link inferno-isnumber}
+ * @see is/real
+ *
* @alternate !isNaN(parseFloat(n)) && isFinite(n)
*
* @example
@@ -39,12 +47,5 @@ const isNumberPrimitive = require('./numberPrimitive')
* isNumber(false)
* //=> false
*
- * @NOTE was not needed except for abstract ==
- * const isObj = require('./obj')
- * const isSymbol = require('./symbol')
- * (isObj(x) || isSymbol(x)
- * ? false
- * : (/^0x[0-9a-f]+$/i).test(x) ||
- * (/^[-+]?(?:\d+(?:\.\d*)?|\.\d+)(e[-+]?\d+)?$/).test(x))
*/
module.exports = x => isNumberPrimitive(x) || toS(x) === '[object Number]'
diff --git a/src/deps/is/numberPrimitive.js b/src/deps/is/numberPrimitive.js
index 9b22477..2e5875a 100644
--- a/src/deps/is/numberPrimitive.js
+++ b/src/deps/is/numberPrimitive.js
@@ -1,34 +1,28 @@
/**
- * @param {*} x value
- * @return {boolean} isNumberPrimitive
- *
+ * @desc typeof x === number
* @since 3.0.0
* @memberOf is
- * @func isNumberPrimitive
+ *
+ * @param {*} x value to check
+ * @return {boolean} isNumberPrimitive
+ *
+ * @func
+ * @name isNumberPrimitive
* @see is/real
*
* @example
*
- * isNumberPrimitive(1)
- * //=> true
- * isNumberPrimitive(Number(1))
- * //=> true
- * isNumberPrimitive(NaN)
- * //=> true
- * isNumberPrimitive(new Number(1))
- * //=> false
+ * isNumberPrimitive(1) //=> true
+ * isNumberPrimitive(Number(1)) //=> true
+ * isNumberPrimitive(NaN) //=> true
+ * isNumberPrimitive(new Number(1)) //=> false
+ *
+ * isNumberPrimitive(null) //=> false
+ * isNumberPrimitive(undefined) //=> false
+ * isNumberPrimitive(void 0) //=> false
+ * isNumberPrimitive({}) //=> false
+ * isNumberPrimitive('') //=> false
+ * isNumberPrimitive(false) //=> false
*
- * isNumberPrimitive(null)
- * //=> false
- * isNumberPrimitive(undefined)
- * //=> false
- * isNumberPrimitive(void 0)
- * //=> false
- * isNumberPrimitive({})
- * //=> false
- * isNumberPrimitive('')
- * //=> false
- * isNumberPrimitive(false)
- * //=> false
*/
module.exports = x => typeof x === 'number'
diff --git a/src/deps/is/numberish.js b/src/deps/is/numberish.js
new file mode 100644
index 0000000..dc68772
--- /dev/null
+++ b/src/deps/is/numberish.js
@@ -0,0 +1,36 @@
+const matchInteger = require('../regexp/matchInteger')
+const matchHex = require('../regexp/matchHex')
+const isNumber = require('./number')
+const isSymbol = require('./symbol')
+
+/**
+ * @name isNumberish
+ * @alias isNumberLike
+ * @since 5.0.0-beta.6
+ * @version 5.0.1 <- added isSymbol check to avoid testing symbol
+ * @memberOf is
+ *
+ * @NOTE this was old test, is used in funwithflags, and other cli environments
+ * @NOTE this is helpful when casting strings to numbers
+ *
+ * @param {number | string | *} x numberish to check
+ * @return {boolean} x isNumberish
+ *
+ * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Grammar_and_types#Integers mozilla-integers-hex}
+ * @see {@link mozilla-integers-hex}
+ * @see is/number
+ * @see cast/number
+ *
+ * @example
+ *
+ * isNumberish('10') //=> true
+ * isNumberish(10) //=> true
+ * isNumberish('10.01') //=> true
+ *
+ */
+module.exports = function isNumberish(x) {
+ if (isSymbol(x)) return false
+ else if (isNumber(x)) return true
+ else if (matchHex.test(x)) return true
+ else return matchInteger.test(x)
+}
diff --git a/src/deps/is/numberishWithDecimals.js b/src/deps/is/numberishWithDecimals.js
new file mode 100644
index 0000000..9013d0f
--- /dev/null
+++ b/src/deps/is/numberishWithDecimals.js
@@ -0,0 +1,17 @@
+const and = require('../conditional/and')
+const isNumberish = require('./numberish')
+const hasDecimals = require('./hasDecimals')
+
+/**
+ * @since 5.0.0-beta.9
+ * @desc checks first for numberish, then decimals
+ * @name isNumberishWithDecimals
+ * @alias isFloat
+ *
+ * @param {*} x
+ * @return {boolean} x isNumberishWithDecimals
+ *
+ * @type {Function}
+ */
+const isNumberishWithDecimals = and(isNumberish, hasDecimals)
+module.exports = isNumberishWithDecimals
diff --git a/src/deps/is/obj.js b/src/deps/is/obj.js
index e37ad56..8f49bdd 100644
--- a/src/deps/is/obj.js
+++ b/src/deps/is/obj.js
@@ -1,35 +1,43 @@
const objTypeof = require('./objTypeof')
const isFunction = require('./function')
+const isNull = require('./null')
+// const objNotNull = require('./objNotNull')
/**
- * @func isObj
- *
* Checks if `value` is the
* [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
* of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
- *
+ * @memberOf is
* @since 3.0.0
* @category Lang
+ *
* @param {*} value The value to check.
* @return {boolean} Returns `true` if `value` is an object, else `false`.
*
- * @memberOf is
- * @see http://stackoverflow.com/questions/34111902/why-do-lodashs-isobject-isplainobject-behave-differently-than-typeof-x
- * @see https://github.com/lodash/lodash/blob/master/isObject.js
- * @NOTE Object.prototype.toString.call(val) === '[object Object]'
+ * @func
+ * @name isObj
+ * @alias isObject
+ *
+ * {@link https://github.com/gcanti/tcomb/blob/master/lib/isObject.js tcomb-isobject}
+ * {@link https://github.com/lodash/lodash/blob/master/isObject.js lodash-isobject}
+ * {@link https://github.com/mobxjs/mobx/blob/master/src/utils/utils.ts#L74 mobx-is-obj}
+ * @see {@link mobx-isobject}
+ * @see {@link lodash-isobject}
+ * @see {@link tcomb-isobject}
*
* @example
*
* isObject({})
- * // => true
+ * //=> true
*
* isObject([1, 2, 3])
- * // => true
+ * //=> true
*
* isObject(Function)
- * // => true
+ * //=> true
*
* isObject(null)
- * // => false
+ * //=> false
+ *
*/
-module.exports = x => x !== null && (objTypeof(x) || isFunction(x))
+module.exports = x => !isNull(x) && (objTypeof(x) || isFunction(x))
diff --git a/src/deps/is/objNotNull.js b/src/deps/is/objNotNull.js
index 550b4e4..1213ee0 100644
--- a/src/deps/is/objNotNull.js
+++ b/src/deps/is/objNotNull.js
@@ -2,17 +2,26 @@ const isObjTypeof = require('./objTypeof')
const isNullOrUndef = require('./nullOrUndefined')
/**
- * @param {*} x value
- * @return {boolean} isObjStrict
+ * name says it all
+ *
+ * @param {*} x value
+ * @return {boolean} isObjNotNull
*
* @since 3.0.0
* @memberOf is
- * @func isObjStrict
+ * @func isObjNotNull
+ * @alias isObjectLike
+ * @alias isObjectNotNull
+ *
+ * {@link https://github.com/lodash/lodash/blob/master/isObjectLike.js lodash-is-object-like}
+ * {@link https://github.com/sindresorhus/is-obj/blob/master/index.js is-obj}
* @see is/obj
* @see is/objWithKeys
* @see is/objTypeof
* @see is/null
- * @see https://github.com/sindresorhus/is-obj/blob/master/index.js
+ * @see {@link is-obj}
+ * @see {@link lodash-is-object-like}
+ *
* @TODO !Array.isArray
*
* @extends isObjTypeof
@@ -20,22 +29,22 @@ const isNullOrUndef = require('./nullOrUndefined')
*
* @example
*
- * isObjStrict(new Object())
+ * isObjNotNull(new Object())
* //=> true
- * isObjStrict({})
+ * isObjNotNull({})
* //=> true
- * isObjStrict(Object.create(null))
+ * isObjNotNull(Object.create(null))
* //=> true
- * isObjStrict(null)
+ * isObjNotNull(null)
* //=> false
*
- * isObjStrict(new Set())
+ * isObjNotNull(new Set())
* //=> false
- * isObjStrict(function() {})
+ * isObjNotNull(function() {})
* //=> false
- * isObjStrict('')
+ * isObjNotNull('')
* //=> false
- * isObjStrict(1)
+ * isObjNotNull(1)
* //=> false
*
*/
diff --git a/src/deps/is/objPlain.js b/src/deps/is/objPlain.js
new file mode 100644
index 0000000..76c420d
--- /dev/null
+++ b/src/deps/is/objPlain.js
@@ -0,0 +1,87 @@
+const funcToString = require('../native/functionToString')
+const hasOwnProperty = require('../util/hasOwnProperty')
+const getPrototypeOf = require('../util/getPrototypeOf')
+const isObjTag = require('./objTag')
+const isObjectLike = require('./objNotNull')
+const isFunction = require('./function')
+const isNull = require('./null')
+
+/** Used to infer the `Object` constructor. */
+const objectConstructorString = funcToString.call(Object)
+
+/**
+ * Checks if `value` is a plain object, that is, an object created by the
+ * `Object` constructor or one with a `[[Prototype]]` of `null`.
+ *
+ * @since 5.0.0-beta.5
+ * @memberOf is
+ *
+ * @param {*} value The value to check.
+ * @return {boolean} Returns `true` if `value` is a plain object, else `false`.
+ *
+ * @name isObjPlain
+ * @alias isPlainObject
+ * @alias isObjectPlain
+ * @alias isBlankObject
+ *
+ * {@link https://github.com/facebook/immutable-js/blob/master/src/fromJS.js#L52 immutable-is-plain-object}
+ * {@link https://github.com/mobxjs/mobx/blob/master/src/utils/utils.ts#L78 mobx-isobjectplain}
+ * {@link https://github.com/lodash/lodash/blob/master/isPlainObject.js lodash-isplainobject}
+ * {@link http://stackoverflow.com/questions/34111902/why-do-lodashs-isobject-isplainobject-behave-differently-than-typeof-x stackoverflow-lodash-isplainobject}
+ * {@link https://github.com/madrobby/zepto/blob/master/src/zepto.js#L74 zepto-isplainobject}
+ * {@link https://github.com/canjs/canjs/blob/2.3-legacy/util/object/isplain/isplain.js can-is-plain}
+ * @see {@link can-is-plain}
+ * @see {@link zepto-isplainobject}
+ * @see {@link stackoverflow-lodash-isplainobject}
+ * @see {@link lodash-isplainobject}
+ * @see {@link mobx-isobjectplain}
+ * @see {@link immutable-is-plain-object}
+ *
+ * @see is/objNotNull
+ * @see is/objTag
+ *
+ * @func
+ * @fork 0.8.0
+ * @category Lang
+ *
+ * @example
+ *
+ * function Foo() {
+ * this.a = 1
+ * }
+ *
+ * isPlainObject(new Foo)
+ * //=> false
+ *
+ * isPlainObject([1, 2, 3])
+ * //=> false
+ *
+ * isPlainObject({ 'x': 0, 'y': 0 })
+ * //=> true
+ *
+ * isPlainObject(Object.create(null))
+ * //=> true
+ *
+ */
+function isPlainObject(x) {
+ if (!isObjectLike(x) || !isObjTag(x)) {
+ return false
+ }
+
+ // --- get prototype
+ const proto = getPrototypeOf(x)
+ if (isNull(proto)) {
+ return true
+ }
+
+ // --- check if constructor is === `Object.constructor`
+
+ const constructor =
+ hasOwnProperty(proto, 'constructor') &&
+ proto.constructor
+
+ return isFunction(constructor) && constructor instanceof constructor &&
+ funcToString.call(constructor) === objectConstructorString
+}
+
+module.exports = isPlainObject
diff --git a/src/deps/is/objPure.js b/src/deps/is/objPure.js
index 2b2b843..5f514d4 100644
--- a/src/deps/is/objPure.js
+++ b/src/deps/is/objPure.js
@@ -1,20 +1,23 @@
const isArray = require('./array')
-const isObjTypeof = require('./objTypeof')
-const isNullOrUndef = require('./nullOrUndefined')
+const isObjNotNull = require('./objNotNull')
const isFunction = require('./function')
/**
* @name isObjPure
* @memberOf is
+ *
* @alias isObjNotArrayOrFunction
- * @since 3.0.0
+ * @alias isObjectNotArrayOrFunction
+ * @alias isObjectPure
+ * @alias isPureObject
*
+ * @since 3.0.0
*
* @param {*} x value to check
* @return {boolean} is obj & !null & !undefined & !array & !function
*
* @extends isArray
- * @extends isObjTypeof
+ * @extends isObjNotNull
* @extends isNullOrUndefined
* @extends isFunction
*
@@ -31,5 +34,4 @@ const isFunction = require('./function')
* //=> true
*
*/
-module.exports = x =>
- !isNullOrUndef(x) && !isArray(x) && !isFunction(x) && isObjTypeof(x)
+module.exports = x => isObjNotNull(x) && !isArray(x) && !isFunction(x)
diff --git a/src/deps/is/objTag.js b/src/deps/is/objTag.js
new file mode 100644
index 0000000..54d531a
--- /dev/null
+++ b/src/deps/is/objTag.js
@@ -0,0 +1,42 @@
+const toS = require('./toS')
+
+/**
+ * Checks if `value` toStringTag is [object Object]
+ * @NOTE Object.prototype.toString.call(val) === '[object Object]'
+ *
+ * @memberOf is
+ * @since 5.0.0-beta.1
+ *
+ * @param {*} x The value to check.
+ * @return {boolean} Returns `true` if `value` is an object, else `false`.
+ *
+ * @category Lang
+ * @func
+ * @name isObjTag
+ * @alias isObjectTag
+ *
+ * {@link https://github.com/ramda/ramda/blob/master/src/internal/_isObject.js ramda-isobject}
+ * @see {@link ramda-isobject}
+ *
+ * @example
+ *
+ * isObjectTag({})
+ * //=> true
+ *
+ * isObjectTag(Object.create(null))
+ * //=> true
+ *
+ * isObjectTag(Object({}))
+ * //=> true
+ *
+ * isObjectTag([1, 2, 3])
+ * //=> false
+ *
+ * isObjectTag(Function)
+ * //=> false
+ *
+ * isObjectTag(null)
+ * //=> false
+ *
+ */
+module.exports = x => toS(x) === '[object Object]'
diff --git a/src/deps/is/objTypeof.js b/src/deps/is/objTypeof.js
index 16e50d4..a410fa9 100644
--- a/src/deps/is/objTypeof.js
+++ b/src/deps/is/objTypeof.js
@@ -1,9 +1,14 @@
/**
- * @param {*} x value
+ * typeof == object, includes null
+ * @param {Object | null | *} x value
* @return {boolean} isObjLoose
*
* @since 3.0.0
* @memberOf is
+ * @alias isObjLoose
+ * @alias isObjectType
+ * @alias isObjectTypeof
+ *
* @func isObjLoose
* @see is/obj
* @see is/objWithKeys
diff --git a/src/deps/is/objWithKeys.js b/src/deps/is/objWithKeys.js
index 2532274..6b04ed4 100644
--- a/src/deps/is/objWithKeys.js
+++ b/src/deps/is/objWithKeys.js
@@ -1,10 +1,12 @@
const ObjectKeys = require('../util/keys')
+const size = require('../util/size')
const isObj = require('./obj')
+const isEmpty = require('./empty')
/**
* @TODO @NOTE need to be more careful, needs to check for vanilla objects, not native ones since e.g. Error has no keys
*
- * @param {*} x value
+ * @param {*} x value
* @return {boolean} isObjWithKeys
*
* @since 3.0.0
@@ -14,6 +16,7 @@ const isObj = require('./obj')
* @see is/objWithKeys
* @see is/objStrict
* @see is/null
+ * @see is/empty
*
* @extends isObj
* @variation Object.keys(obj).length !== 0
@@ -40,4 +43,4 @@ const isObj = require('./obj')
* //=> false
*
*/
-module.exports = val => isObj(val) && ObjectKeys(val).length !== 0
+module.exports = x => isObj(x) && ObjectKeys(x).length !== 0 // !isEmpty(x)
diff --git a/src/deps/is/ownPropertyIs.js b/src/deps/is/ownPropertyIs.js
new file mode 100644
index 0000000..9fa44d4
--- /dev/null
+++ b/src/deps/is/ownPropertyIs.js
@@ -0,0 +1,27 @@
+const hasOwnProperty = require('../util/hasOwnProperty')
+const curry = require('../fp/curry')
+
+/**
+ * @desc if it has own property, call fnIs(value), else false
+ * @curried 3
+ * @name ownPropertyIs
+ * @alias ownPropertySatisfies
+ *
+ * @param {string|Array} propertyPath (@TODO later, lensish)
+ * @param {Function} fnIs (obj[path]): boolean
+ * @param {Object} obj object to check
+ * @return {boolean} hasOwnProperty && fnIs
+ *
+ * @see util/hasOwnProperty
+ * @see fp/curry
+ * @see is/_core
+ *
+ * @TODO add just getting the value of the property, as a param option
+ * @TODO example
+ * @TODO use path here too when needed
+ */
+module.exports = curry(3, function ownPropertyIs(propertyPath, fnIs, obj) {
+ return hasOwnProperty(obj, propertyPath)
+ ? fnIs(obj[propertyPath])
+ : false
+})
diff --git a/src/deps/is/primitive.js b/src/deps/is/primitive.js
new file mode 100644
index 0000000..f7667be
--- /dev/null
+++ b/src/deps/is/primitive.js
@@ -0,0 +1,59 @@
+const isBooleanPrimitive = require('./booleanPrimitive')
+const isStringPrimitive = require('./stringPrimitive')
+const isNumberPrimitive = require('./numberPrimitive')
+const isNullOrUndefined = require('./nullOrUndefined')
+
+/**
+ * Checks if `value` is classified as a **primitive**
+ * `(number|string|boolean|null|undefined)`
+ *
+ * @version 5.0.0 added booleanPrimitive, is in own file
+ * @since 4.0.0 was in another file
+ * @memberOf is
+ *
+ * @param {*} x The value to check.
+ * @return {boolean} x is number|string|boolean|null|undefined
+ *
+ * @func
+ * @category Lang
+ *
+ * {@link https://github.com/andrewplummer/Sugar/blob/master/lib/common.js#L583 sugar-isprimitive}
+ * {@link https://nodejs.org/api/util.html#util_util_isprimitive_object node-util-isprimitive}
+ * {@link http://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html java-data-types}
+ * {@link https://developer.mozilla.org/en-US/docs/Glossary/Primitive mozilla-primitive}
+ * {@link http://www.adequatelygood.com/Object-to-Primitive-Conversions-in-JavaScript.html primitive-conversions-in-js}
+ *
+ * @see {@link primitive-conversions-in-js}
+ * @see {@link mozilla-primitive}
+ * @see {@link java-data-types}
+ * @see {@link node-util-isprimitive}
+ * @see {@link sugar-isprimitive}
+ *
+ * @see is/nullOrUndefined
+ * @see is/stringPrimitive
+ * @see is/booleanPrimitive
+ * @see is/numberPrimitive
+ *
+ * @example
+ *
+ * isPrimitive('abc') //=> true
+ * isPrimitive(1) //=> true
+ * isPrimitive('') //=> true
+ * isPrimitive(null) //=> true
+ * isPrimitive(undefined) //=> true
+ * isPrimitive(void 0) //=> true
+ *
+ * isPrimitive(new String('abc')) //=> false
+ * isPrimitive([]) //=> false
+ * isPrimitive(() => {}) //=> false
+ * isPrimitive({}) //=> false
+ *
+ */
+module.exports = function isPrimitive(node) {
+ return (
+ isNullOrUndefined(node) ||
+ isStringPrimitive(node) ||
+ isNumberPrimitive(node) ||
+ isBooleanPrimitive(node)
+ )
+}
diff --git a/src/deps/is/promise.js b/src/deps/is/promise.js
index 9d48db0..fe99387 100644
--- a/src/deps/is/promise.js
+++ b/src/deps/is/promise.js
@@ -1,16 +1,23 @@
+const ENV_COMPAT = require('../env/compat')
const toS = require('./toS')
/**
* @desc is a Promise
+ * @since 4.0.0-beta.2
+ * @memberOf is
+ *
* @param {*} x value
* @return {boolean} x isPromise
*
- * @since 4.0.0-beta.2
- * @memberOf is
- * @func isPromise
+ * @func
+ * @name isPromise
*
- * @see https://github.com/jonschlinkert/kind-of/blob/master/index.js#L66
- * @see https://github.com/sindresorhus/promise-fun
+ * {@link https://tc39.github.io/ecma262/#sec-ispromise emca-ispromise}
+ * {@link https://github.com/sindresorhus/promise-fun promise-fun}
+ * {@link https://github.com/jonschlinkert/kind-of/blob/master/index.js#L66 kind-of-promise}
+ * @see {@link emca-ispromise}
+ * @see {@link kind-of-promise}
+ * @see {@link promise-fun}
*
* @example
*
@@ -36,3 +43,9 @@ const toS = require('./toS')
*
*/
module.exports = x => toS(x) === '[object Promise]'
+
+if (ENV_COMPAT) {
+ const isObj = require('./obj')
+ const isFunction = require('./function')
+ module.exports = x => isObj(x) && isFunction(x.then)
+}
diff --git a/src/deps/is/prototypeOf.js b/src/deps/is/prototypeOf.js
index 313086f..2fb208c 100644
--- a/src/deps/is/prototypeOf.js
+++ b/src/deps/is/prototypeOf.js
@@ -1,2 +1,35 @@
-module.exports = (obj, comparator) =>
- Object.prototype.isPrototypeOf.call(obj, comparator)
+const isNill = require('./nullOrUndefined')
+
+const isPrototypeOf = Object.prototype.isPrototypeOf
+
+/**
+ * check if arg 1 is prototype of arg 2
+ *
+ * @TODO curry2
+ * @memberOf is
+ * @name isPrototypeOf
+ * @since 3.0.0
+ *
+ * @param {Object | *} haystack check needle against
+ * @param {Object | *} needle is prototype of haystack
+ * @return {boolean} needle isPrototypeOf haystack
+ *
+ * {@link https://tc39.github.io/ecma262/#sec-object.prototype.isprototypeof emca-is-prototype-of}
+ * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isPrototypeOf mozilla-obj-isprototypeof}
+ * @see {@link mozilla-obj-isprototypeof}
+ * @see {@link emca-is-prototype-of}
+ *
+ * @example
+ *
+ * class Eh extends Function {}
+ * class Canada extends Eh {}
+ * isPrototypeOf(Eh, Function) //=> true
+ * isPrototypeOf(Canada, Function) //=> true
+ * isPrototypeOf(Eh, Date) //=> false
+ *
+ * isPrototypeOf({}, Object) //=> true
+ * isPrototypeOf({}, Array) //=> false
+ *
+ */
+module.exports = (haystack, needle) =>
+ !isNill(haystack) && isPrototypeOf.call(haystack, needle)
diff --git a/src/deps/is/real.js b/src/deps/is/real.js
index 81a065c..75a02e9 100644
--- a/src/deps/is/real.js
+++ b/src/deps/is/real.js
@@ -1,12 +1,13 @@
const isNullOrUndefined = require('./nullOrUndefined')
+const isNotEhNumber = require('./NaN')
/**
- * @param {*} x value
- * @return {boolean} isReal
+ * @desc ensure a value is not nill, or nan
+ * @param {*} x value
+ * @return {boolean} x isReal
*
* @since 3.0.0
* @memberOf is
- * @func isReal
* @see is/null
* @see is/undefined
*
@@ -17,6 +18,8 @@ const isNullOrUndefined = require('./nullOrUndefined')
* @NOTE eslint-disable-next-line no-self-compare
* && x !== x
*
+ * @func
+ * @name isReal
* @extends isNullOrUndefined
* @variation *not* isNullOrUndefined && false for NaN
*
@@ -48,4 +51,4 @@ const isNullOrUndefined = require('./nullOrUndefined')
* //=> true
*
*/
-module.exports = x => !isNullOrUndefined(x) && !Number.isNaN(x)
+module.exports = x => !isNullOrUndefined(x) && !isNotEhNumber(x)
diff --git a/src/deps/is/regexp.js b/src/deps/is/regexp.js
index 60f3fc3..8dfd8cb 100644
--- a/src/deps/is/regexp.js
+++ b/src/deps/is/regexp.js
@@ -4,18 +4,29 @@ const toS = require('./toS')
* Checks if `value` is classified as a `RegExp` object.
*
* @since 0.1.0
- * @category Lang
+ * @memberOf is
+ *
* @param {*} x The value to check.
* @return {boolean} Returns `true` if `value` is a regexp, else `false`.
- * @see https://github.com/lodash/lodash/blob/master/isRegExp.js
*
- * @example
+ * @category Lang
+ *
+ * {@link https://tc39.github.io/ecma262/#sec-isregexp emca-isregexp}
+ * {@link https://nodejs.org/api/util.html#util_util_isregexp_object node-util-isregexp}
+ * {@link https://github.com/ramda/ramda/blob/master/src/internal/_isRegExp.js ramda-isregexp}
+ * {@link https://github.com/lodash/lodash/blob/master/isRegExp.js lodash-is-regexp}
+ * {@link https://github.com/js-data/js-data/blob/v2/src/utils.js#L52 js-data-is-regexp}
+ * @see {@link emca-isregexp}
+ * @see {@link lodash-is-regexp}
+ * @see {@link js-data-is-regexp}
+ * @see {@link ramda-isregexp}
+ * @see {@link node-util-isregexp}
*
- * isRegExp(/abc/)
- * // => true
+ * @example
*
- * isRegExp('/abc/')
- * // => false
+ * isRegExp(/abc/) //=> true
+ * isRegExp(new RegExp('abc')) //=> true
+ * isRegExp('/abc/') //=> false
*
*/
module.exports = x => toS(x) === '[object RegExp]'
diff --git a/src/deps/is/set.js b/src/deps/is/set.js
index 86dd9e3..103368d 100644
--- a/src/deps/is/set.js
+++ b/src/deps/is/set.js
@@ -8,17 +8,19 @@ const toS = require('./toS')
* @param {*} x The value to check.
* @return {boolean} Returns `true` if `value` is a set, else `false`.
*
- * @example
+ * @TODO map[Symbol.species] === Set
*
- * isSet(new Set)
- * // => true
+ * @example
*
- * isSet(new WeakSet)
- * // => false
+ * isSet(new Set)
+ * //=> true
+ *
+ * isSet(new WeakSet)
+ * //=> false
*
*/
module.exports = function isSet(x) {
- return x instanceof Set || toS(x) === '[object Set]'
- // return toS(x) === '[object Set]'
+ // return x instanceof Set || toS(x) === '[object Set]'
+ return toS(x) === '[object Set]'
}
// x instanceof Set ||
diff --git a/src/deps/is/string.js b/src/deps/is/string.js
index 32621af..4af2b4f 100644
--- a/src/deps/is/string.js
+++ b/src/deps/is/string.js
@@ -4,6 +4,7 @@ const isStringPrimitive = require('./stringPrimitive')
/**
* Checks if `value` is classified as a `String` primitive or object.
*
+ * @name isString
* @since 3.0.0
* @category Lang
*
@@ -14,18 +15,32 @@ const isStringPrimitive = require('./stringPrimitive')
* @param {*} x The value to check.
* @return {boolean} Returns `true` if `value` is a string, else `false`.
*
- * @see https://github.com/lodash/lodash/blob/master/isString.js
+ * {@link https://nodejs.org/api/util.html#util_util_isstring_object node-util-isstring}
+ * {@link https://github.com/jashkenas/underscore/blob/master/underscore.js#L1318 underscore-isstring}
+ * {@link https://github.com/infernojs/inferno/blob/master/packages/inferno-shared/src/index.ts#L42 inferno-isstring}
+ * {@link https://github.com/ramda/ramda/blob/master/src/internal/_isString.js ramda-is-string}
+ * {@link https://github.com/js-data/js-data/blob/v2/src/utils.js#L57 js-data-is-string}
+ * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String mozilla-string}
+ * {@link https://github.com/lodash/lodash/blob/master/isString.js lodash-isString}
+ * @see {@link lodash-isString}
+ * @see {@link mozilla-string}
+ * @see {@link js-data-is-string}
+ * @see {@link ramda-is-string}
+ * @see {@link inferno-isstring}
+ * @see {@link underscore-isstring}
+ * @see {@link node-util-isstring}
* @see isStringPrimitive
*
* @example
*
- * isString('abc')
- * // => true
+ * isString('abc')
+ * //=> true
*
- * isString(new String('abc'))
- * // => true
+ * isString(new String('abc'))
+ * //=> true
+ *
+ * isString(1)
+ * //=> false
*
- * isString(1)
- * // => false
*/
module.exports = x => isStringPrimitive(x) || toS(x) === '[object String]'
diff --git a/src/deps/is/stringOrNumber.js b/src/deps/is/stringOrNumber.js
index 00da788..f879285 100644
--- a/src/deps/is/stringOrNumber.js
+++ b/src/deps/is/stringOrNumber.js
@@ -1,3 +1,4 @@
+const or = require('../conditional/or')
const isString = require('./string')
const isNumber = require('./number')
@@ -5,20 +6,23 @@ const isNumber = require('./number')
* Checks if `value` is classified as a `String` primitive or object.
*
* @since 3.0.0
- * @category Lang
* @memberOf is
+ *
* @param {*} x The value to check.
* @return {boolean} Returns `true` if `value` is a string, else `false`.
*
- * @see https://github.com/infernojs/inferno/blob/master/packages/inferno-shared/src/index.ts#L23
- * @see https://github.com/lodash/lodash/blob/master/isString.js
+ * @category Lang
+ *
+ * {@link https://github.com/infernojs/inferno/blob/master/packages/inferno-shared/src/index.ts#L23 inferno-isstringornumber}
+ * @see {@link inferno-isstringornumber}
*
* @example
*
- * isString('abc')
- * // => true
+ * isString('abc')
+ * //=> true
+ *
+ * isString(1)
+ * //=> false
*
- * isString(1)
- * // => false
*/
-module.exports = x => isString(x) || isNumber(x)
+module.exports = or(isString, isNumber)
diff --git a/src/deps/is/stringPrimitive.js b/src/deps/is/stringPrimitive.js
index dc63300..cc8f40f 100644
--- a/src/deps/is/stringPrimitive.js
+++ b/src/deps/is/stringPrimitive.js
@@ -9,6 +9,7 @@ const toS = require('./toS')
* @param {*} x The value to check.
* @returns {boolean} Returns `true` if `value` is a string, else `false`.
*
+ * @see https://github.com/canjs/can-util/blob/master/js/is-string/is-string.js
* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String
* @see https://github.com/lodash/lodash/blob/master/isString.js
* @see is/string
@@ -16,12 +17,12 @@ const toS = require('./toS')
* @example
*
* isString('abc')
- * // => true
+ * //=> true
*
* isString(new String('abc'))
- * // => false
+ * //=> false
*
* isString(1)
- * // => false
+ * //=> false
*/
module.exports = x => typeof x === 'string'
diff --git a/src/deps/is/symbol.js b/src/deps/is/symbol.js
index c23f383..6d1bc0a 100644
--- a/src/deps/is/symbol.js
+++ b/src/deps/is/symbol.js
@@ -1,22 +1,25 @@
const toS = require('./toS')
/**
- * Checks if `value` is classified as a `Symbol` primitive or object.
- *
+ * @desc checks if `value` is classified as a `Symbol` primitive or object.
* @since 4.0.0
- * @category Lang
* @memberOf is
*
* @param {*} value The value to check.
* @return {boolean} Returns `true` if `value` is a symbol, else `false`.
+ *
+ * @category Lang
*
+ * {@link https://nodejs.org/api/util.html#util_util_issymbol_object node-util-issymbol}
+ * @see {@link node-util-issymbol}
+ *
* @example
*
- * isSymbol(Symbol.iterator)
- * // => true
+ * isSymbol(Symbol.iterator)
+ * //=> true
*
- * isSymbol('abc')
- * // => false
+ * isSymbol('abc')
+ * //=> false
*
*/
module.exports = x => toS(x) === '[object Symbol]'
diff --git a/src/deps/is/tagEq.js b/src/deps/is/tagEq.js
new file mode 100644
index 0000000..a6f7401
--- /dev/null
+++ b/src/deps/is/tagEq.js
@@ -0,0 +1,91 @@
+// const curry = require('../fp/curry')
+
+/**
+ * @desc typeof x === type
+ * @since 5.0.0-beta.6
+ * @name tagEq
+ * @alias isTagEq
+ * @alias tagEquals
+ * @alias isA
+ *
+ * @curried 2
+ *
+ * @param {string} type to match
+ * @param {string} x object to match `typeof x === type`
+ * @return {boolean}
+ *
+ * {@link https://github.com/andrewplummer/Sugar/blob/master/lib/common.js#L66 sugar-tags}
+ * {@link https://github.com/jasmine/jasmine.github.io/blob/master/lib/jasmine-1.3.1/jasmine.js#L171 jasmine-isA}
+ * {@link https://github.com/gcanti/tcomb/blob/master/lib/isType.js tcomb-istype}
+ * {@link https://github.com/yesvods/sanife/blob/master/src/type.js#L3 sanife-type}
+ * @see {@link sanife-type}
+ * @see {@link tcomb-istype}
+ * @see {@link jasmine-isA}
+ * @see {@link sugar-tags}
+ *
+ * @example
+ * isType('string')('eh') //=> true
+ *
+ */
+const symbolToString = require('../symbols/toString')
+const symbolToStringTag = require('../symbols/toStringTag')
+const toStringTag = require('./toS')
+const hasIn = require('./hasIn')
+
+// const hasOwnProperty = require('../util/hasOwnProperty')
+// if (value === null || value === undefined) {
+// return value === undefined ? '[object Undefined]' : '[object Null]'
+// }
+
+function getForSymbol(symbolToGet, value) {
+ // typeof value[symbolToString] === 'function' ? value[symbolToString]() : value[symbolToString]
+ let atSymbol = value[symbolToString]
+
+ // @NOTE not sure if we really need this
+ if (typeof atSymbol === 'function') {
+ atSymbol = atSymbol()
+ }
+ if (typeof atSymbol === 'string') {
+ return atSymbol
+ }
+
+ return undefined
+}
+
+/**
+ * The base implementation of `getTag` without fallbacks for buggy environments.
+ *
+ * @curried 2
+ *
+ * @param {*} x The value to query.
+ * @param {*} value getTag(x) === value
+ * @return {string} Returns the `toStringTag`.
+ */
+module.exports = function tagEquals(x, value) {
+ let type
+
+ if (value === undefined) {
+ type = '[object Undefined]'
+ }
+ else if (value === null) {
+ type = '[object Null]'
+ }
+ else if (hasIn(symbolToStringTag, value)) {
+ let atSymbol = getForSymbol(symbolToStringTag, value)
+ if (atSymbol !== undefined) type = atSymbol
+ }
+
+ // @NOTE not sure if we would really need to call a toString symbol
+ // ...when there is toStringTag?
+ // else if (hasIn(symbolToString, value)) {}
+
+ if (type === null || typeof type !== 'string') {
+ type = toStringTag(value)
+ }
+
+ return type === value
+}
+
+// module.exports = curry(2, tagEquals)
+
+// const xIsType = flip2(isType)
diff --git a/src/deps/is/toS.js b/src/deps/is/toS.js
index 22202f3..032ab2a 100644
--- a/src/deps/is/toS.js
+++ b/src/deps/is/toS.js
@@ -1,8 +1,14 @@
+const invoke = require('../fp/invoke')
+const objectToString = require('../native/objectToString')
+
/**
* The base implementation of `getTag` without fallbacks for buggy environments.
*
* @memberOf is
* @since 3.0.0
+ * @alias getTag
+ * @alias toStringTag
+ * @alias toS
*
* @param {*} obj The value to `Object.prototype.toString.call(obj)`.
* @return {string} Returns the `toStringTag`.
@@ -10,16 +16,22 @@
* @see https://github.com/lodash/lodash/blob/master/.internal/baseGetTag.js
* @see https://github.com/jonschlinkert/kind-of
* @see https://github.com/substack/js-traverse/blob/master/index.js#L285
+ * @see http://luxiyalu.com/object-prototype-tostring-call/
*
* @TODO obj[Symbol.toStringTag]
+ * @TODO run deopt check on this invoking see how many invocations... are needed to inline
*
* @example
*
* toS({})
- * //=> '[Object object]'
+ * //=> '[object Object]'
*
* toS(function() {})
- * //=> '[Object function]'
+ * //=> '[Object Function]'
+ *
+ * getTag([])
+ * //=> '[object Array]'
*
*/
-module.exports = obj => Object.prototype.toString.call(obj)
+// module.exports = obj => objectToString.call(obj)
+module.exports = invoke(objectToString, 'call')
diff --git a/src/deps/is/type.js b/src/deps/is/type.js
new file mode 100644
index 0000000..3f7d5c5
--- /dev/null
+++ b/src/deps/is/type.js
@@ -0,0 +1,30 @@
+const curry = require('../fp/curry')
+
+/**
+ * @desc typeof x === type
+ * @since 5.0.0-beta.6
+ * @name isType
+ * @alias typeEq
+ *
+ * @curried 2
+ *
+ * @param {string} type to match
+ * @param {string} x object to match `typeof x === type`
+ * @return {boolean}
+ *
+ * {@link https://github.com/facebook/jest/blob/master/packages/jest-get-type/src/index.js jest-get-type}
+ * {@link https://github.com/yesvods/sanife/blob/master/src/type.js#L3 sanife-type}
+ * @see {@link sanife-type}
+ * @see {@link jest-get-type}
+ *
+ * @example
+ * isType('string')('eh') //=> true
+ *
+ */
+function isType(type, x) {
+ return typeof x === type
+}
+
+module.exports = curry(2, isType)
+
+// const xIsType = flip2(isType)
diff --git a/src/deps/is/undefined.js b/src/deps/is/undefined.js
index f561f63..3b4f615 100644
--- a/src/deps/is/undefined.js
+++ b/src/deps/is/undefined.js
@@ -10,9 +10,10 @@
* @func isUndefined
*
* @see is/nullOrUndefined
- * @see https://github.com/infernojs/inferno/blob/master/packages/inferno-shared/src/index.ts#L57
- *
- * @NOTE || typeof x === 'undefined'
+ * {@link https://github.com/infernojs/inferno/blob/master/packages/inferno-shared/src/index.ts#L57 inferno-isundefined}
+ * {@link https://nodejs.org/api/util.html#util_util_isundefined_object node_util_isundefined}
+ * @see {@link node_util_isundefined}
+ * @see {@link inferno-isundefined}
*
* @example
*
diff --git a/src/deps/is/undefinedLike.js b/src/deps/is/undefinedLike.js
new file mode 100644
index 0000000..bd1203c
--- /dev/null
+++ b/src/deps/is/undefinedLike.js
@@ -0,0 +1,35 @@
+const isUndefined = require('./undefined')
+const isString = require('./string')
+
+/**
+ * @desc Checks if `value` is `undefined`
+ * OR `"undefined"`
+ * OR `'"undefined"'` (which happens say when you save localStorage or cookie for undefined)
+ *
+ * @since 5.0.0-beta.4
+ * @memberOf is
+ *
+ * @param {*} x value
+ * @return {boolean} x isUndefinedLike
+ *
+ * @func
+ * @extends isUndefined
+ * @name isUndefinedLike
+ * @category Lang
+ *
+ * @see is/nullOrUndefined
+ *
+ * @example
+ *
+ * isUndefined(void 0) //=> true
+ * isUndefined(undefined) //=> true
+ * isUndefined('undefined') //=> true
+ * isUndefined('"undefined"') //=> true
+ * isUndefined(NaN) //=> false
+ * isUndefined({}) //=> false
+ *
+ */
+module.exports = x =>
+ isUndefined(x) ||
+ x === 'undefined' ||
+ (isString(x) && (/undefined/).test(x))
diff --git a/src/deps/is/unsignedInteger.js b/src/deps/is/unsignedInteger.js
new file mode 100644
index 0000000..07f893f
--- /dev/null
+++ b/src/deps/is/unsignedInteger.js
@@ -0,0 +1,12 @@
+const matchUnsigned = require('../regexp/matchUnsigned')
+
+/**
+ * @TODO use `test` util
+ * @param {number | *} x value to test with regexp
+ * @return {boolean} x isUnsignedInteger
+ *
+ * @see regexp/matchUnsigned
+ */
+module.exports = function isUnsignedInteger(x) {
+ return matchUnsigned.test(x)
+}
diff --git a/src/deps/is/url.js b/src/deps/is/url.js
new file mode 100644
index 0000000..0017ef4
--- /dev/null
+++ b/src/deps/is/url.js
@@ -0,0 +1,24 @@
+const isStringPrimitive = require('../is/stringPrimitive')
+const matchUrl = require('../regexp/matchUrl')
+
+/**
+ * @TODO var urlRegExp = /^(?:(?:https?|ftp):\/\/)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})))(?::\d{2,5})?(?:\/\S*)?$/i
+ *
+ * @see https://github.com/arasatasaygin/is.js
+ * @see http://mathiasbynens.be/demo/url-regex
+ * @see https://github.com/chriso/validator.js/blob/master/src/lib/isURL.js
+ * @see https://stackoverflow.com/questions/38704811/javascript-isurl-function
+ * @see https://github.com/jquery-validation/jquery-validation
+ *
+ * @since 5.0.0-beta.5
+ *
+ * @param {string | *} x possible url
+ * @return {boolean}
+ */
+function isUrl(x) {
+ if (!isStringPrimitive(x)) return false
+ else if (matchUrl.test(x)) return true
+ else return false
+}
+
+module.exports = isUrl
diff --git a/src/deps/is/validArrayIndex.js b/src/deps/is/validArrayIndex.js
new file mode 100644
index 0000000..8a63d4a
--- /dev/null
+++ b/src/deps/is/validArrayIndex.js
@@ -0,0 +1,50 @@
+const MAX_32_BIT = require('../native/MAX_32_BIT')
+const toInt32 = require('../cast/toInt32')
+const isStringPrimitive = require('./stringPrimitive')
+
+/**
+ * This implements "is array index" which the ECMAString spec defines as:
+ * > A String property name P is an array index if and only if
+ * > ToString(ToUint32(P)) is equal to P and ToUint32(P) is not equal
+ * > to 2^32−1.
+ *
+ * @since 5.0.0-beta.6
+ * @name isValidArrayIndex
+ *
+ * @param {string | number} x value to check
+ * @return {boolean} x isValidArrayIndex
+ *
+ * {@link http://www.ecma-international.org/ecma-262/6.0/#sec-array-exotic-objects emca-array-exotic-objects}
+ * {@link https://github.com/andrewplummer/Sugar/blob/master/lib/common.js#L815 sugar-isarrayindex}
+ * {@link https://github.com/facebook/immutable-js/blob/master/src/TrieUtils.js#L58 immutablejs-trieutils}
+ * @see {@link immutablejs-trieutils}
+ * @see {@link emca-array-exotic-objects}
+ * @see {@link sugar-isarrayindex}
+ * @see cast/toInt32
+ * @see cast/toIndex
+ * @see is/validIndex
+ *
+ *
+ * @example
+ *
+ * isValidArrayIndex(100) //=> true
+ * isValidArrayIndex('100') //=> true
+ * isValidArrayIndex('100.1') //=> false
+ * isValidArrayIndex('eh') //=> false
+ *
+ */
+module.exports = function isValidArrayIndex(x) {
+ // @TODO ensure this is good ternary, could be 1 line if
+ // or `!isNumberPrimitive`
+ if (isStringPrimitive(x)) {
+ if ('' + toInt32(x) !== x || toInt32(x) === MAX_32_BIT) {
+ return false
+ }
+ else {
+ return true
+ }
+ }
+ else {
+ return true
+ }
+}
diff --git a/src/deps/is/validIndex.js b/src/deps/is/validIndex.js
new file mode 100644
index 0000000..8b6c7ad
--- /dev/null
+++ b/src/deps/is/validIndex.js
@@ -0,0 +1,60 @@
+const MAX_SAFE_INTEGER = require('../native/MAX_SAFE_INTEGER')
+const isSymbol = require('./symbol')
+const isNil = require('./nullOrUndefined')
+const isNumberPrimitive = require('./numberPrimitive')
+const isUnsignedInteger = require('./unsignedInteger')
+const hasDecimals = require('./hasDecimals')
+
+/**
+ * @name isValidIndex
+ * @desc Checks if `value` is a valid array-like index.
+ * @since 5.0.0-beta.6
+ * @memberOf is
+ *
+ * @param {*} x The value to check.
+ * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
+ * @return {boolean} Returns `true` if `value` is a valid index, else `false`.
+ *
+ * {@link https://github.com/lodash/lodash/blob/master/.internal/isIndex.js lodash-is-valid-index}
+ * @see {@link lodash-is-valid-index}
+ * @see is/hasDecimals
+ * @see native/MAX_SAFE_INTEGER
+ *
+ * @example
+ *
+ * isValidIndex(0) //=> true
+ * isValidIndex(100) //=> true
+ * isValidIndex('100') //=> true
+ *
+ * isValidIndex('100.1') //=> false
+ *
+ */
+module.exports = function isValidIndex(x, length) {
+ length = isNil(length) ? MAX_SAFE_INTEGER : length
+
+ // !! so 0 would be false
+ // but this is a silly check
+ // because if it is 0, that does not matter until isUnsignedInteger check
+ // and in that case we already check > -1 anyway
+ //
+ // eslint-disable-next-line
+ // if (!!length) {
+ // return false
+ // }
+ if (isNumberPrimitive(x)) {
+ return true
+ }
+ // above 0, has no decimals, is less than length
+ else if (!isSymbol(x) && isUnsignedInteger(x)) {
+ return x > -1 && !hasDecimals(x) && x < length && length >= 0
+ }
+ else {
+ return false
+ }
+
+ // @NOTE was some other libs version, hard to read
+ // return !!length &&
+ // (type == 'number' ||
+ // (type != 'symbol' && reIsUint.test(value))) &&
+ // (value > -1 && value % 1 == 0 && value < length)
+}
diff --git a/src/deps/is/validPropertyKey.js b/src/deps/is/validPropertyKey.js
new file mode 100644
index 0000000..8d8ece5
--- /dev/null
+++ b/src/deps/is/validPropertyKey.js
@@ -0,0 +1,55 @@
+const matchDeepProp = require('../regexp/matchDeepProp')
+const matchPlainProp = require('../regexp/matchPlainProp')
+const isSymbol = require('./symbol')
+const isPrimitive = require('./primitive')
+const isArray = require('./array')
+const hasIn = require('./hasIn')
+
+/**
+ * @desc Checks if `value` is a valid PROPERTY/KEY
+ * @since 5.0.0-beta.7
+ * @memberOf is
+ *
+ * @param {*} value The value to check.
+ * @param {Object} [obj] The object to query keys on.
+ * @return {boolean} Returns `true` if `value` is a property name, else `false`.
+ *
+ * @name isValidPropertyKey
+ * @alias isProp
+ * @alias isValidProp
+ * @alias isKey
+ * @alias isValidKey
+ * @alias isValidPropKey
+ *
+ * {@link https://tc39.github.io/ecma262/#sec-ispropertykey emca-ispropertykey}
+ * {@link https://github.com/lodash/lodash/blob/master/.internal/isKey.js lodash-iskey}
+ * @see {@link emca-ispropertykey}
+ * @see {@link lodash-iskey}
+ *
+ * @example
+ *
+ * isValidPropertyKey(100) //=> true
+ * isValidPropertyKey('100') //=> true
+ * isValidPropertyKey('100.1') //=> true
+ * isValidPropertyKey('ehoh') //=> true
+ * isValidPropertyKey(Symbol('eh')) //=> true
+ * isValidPropertyKey(null) //=> true
+ *
+ * // try in browser
+ * // var obj = {}
+ * // obj[new Array(10)] = []
+ * isValidPropertyKey([]) //=> false
+ * isValidPropertyKey('deep.prop') //=> false
+ *
+ */
+module.exports = function isValidPropertyKey(x, obj) {
+ if (isPrimitive(x) || isSymbol(x)) {
+ return true
+ }
+ else if (isArray(x)) {
+ return false
+ }
+ else {
+ return matchPlainProp.test(x) || !matchDeepProp.test(x) || hasIn(obj, x)
+ }
+}
diff --git a/src/deps/is/weakMap.js b/src/deps/is/weakMap.js
new file mode 100644
index 0000000..63a4887
--- /dev/null
+++ b/src/deps/is/weakMap.js
@@ -0,0 +1,25 @@
+const isObjNotNull = require('./objNotNull')
+const toS = require('./toS')
+
+/**
+ * Checks if `value` is classified as a `WeakMap` object.
+ *
+ * @since 5.0.0-beta.4
+ * @category Lang
+ * @param {*} x The value to check.
+ * @return {boolean} Returns `true` if `value` is a weak map, else `false`.
+ *
+ * @example
+ *
+ * isWeakMap(new WeakMap)
+ * //=> true
+ *
+ * isWeakMap(new Map)
+ * //=> false
+ *
+ */
+function isWeakMap(x) {
+ return isObjNotNull(x) && toS(x) === '[object WeakMap]'
+}
+
+module.exports = isWeakMap
diff --git a/src/deps/is/weakMapUsable.js b/src/deps/is/weakMapUsable.js
new file mode 100644
index 0000000..7007474
--- /dev/null
+++ b/src/deps/is/weakMapUsable.js
@@ -0,0 +1,8 @@
+/**
+ * @desc If possible, use a WeakMap.
+ * @name isWeakMapUsable
+ * @TODO isWeakCollectionUsable
+ * @since 5.0.0-beta.6
+ * @type {boolean}
+ */
+module.exports = typeof WeakMap === 'function'
diff --git a/src/deps/is/weakSet.js b/src/deps/is/weakSet.js
new file mode 100644
index 0000000..2c9cd49
--- /dev/null
+++ b/src/deps/is/weakSet.js
@@ -0,0 +1,25 @@
+const isObjNotNull = require('./objNotNull')
+const toS = require('./toS')
+
+/**
+ * Checks if `value` is classified as a `isWeakSet` object.
+ *
+ * @since 5.0.0-beta.4
+ * @category Lang
+ * @param {*} x The value to check.
+ * @return {boolean} Returns `true` if `value` is a weak map, else `false`.
+ *
+ * @example
+ *
+ * isWeakSet(new WeakSet)
+ * //=> true
+ *
+ * isWeakSet(new Set)
+ * //=> false
+ *
+ */
+function isWeakSet(x) {
+ return isObjNotNull(x) && toS(x) === '[object WeakSet]'
+}
+
+module.exports = isWeakSet
diff --git a/src/deps/is/webWorker.js b/src/deps/is/webWorker.js
new file mode 100644
index 0000000..5745dd2
--- /dev/null
+++ b/src/deps/is/webWorker.js
@@ -0,0 +1,30 @@
+/* globals WorkerGlobalScope */
+const isUndefinedLike = require('./undefinedLike')
+
+/**
+ * @desc Determines if the code is running with a [Web Worker](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers).
+ * @name isWebWorker
+ * @since 5.0.0-beta.5
+ * @signature `isWebWorker()`
+ *
+ * @return {boolean} True if running in a Web Worker.
+ *
+ * {@link https://developer.mozilla.org/en-US/docs/Web/API/WorkerGlobalScope mozilla-webworkerglobalscope}
+ * {@link https://github.com/canjs/can-util/blob/master/js/is-web-worker/is-web-worker.js can-js-is-web-worker}
+ * @see {@link can-js-is-web-worker}
+ * @see {@link mozilla-webworkerglobalscope}
+ *
+ * @example
+ *
+ * var isWebWorker = require("can-util/js/is-web-worker/is-web-worker");
+ * var GLOBAL = require("can-util/js/global/global");
+ *
+ * if (isWebWorker()) {
+ * GLOBAL() === self) //=> true
+ * }
+ *
+ */
+module.exports = function() {
+ return !isUndefinedLike(typeof WorkerGlobalScope) &&
+ (this instanceof WorkerGlobalScope)
+}
diff --git a/src/deps/is/zeroish.js b/src/deps/is/zeroish.js
new file mode 100644
index 0000000..651aa36
--- /dev/null
+++ b/src/deps/is/zeroish.js
@@ -0,0 +1,20 @@
+/* eslint eqeqeq: "OFF" */
+
+/**
+ * @name isZeroish
+ *
+ * @since 5.0.0-beta.6
+ *
+ * @param {*} x == 0
+ * @return {boolean}
+ *
+ * @TODO is the || the same?
+ *
+ * @example
+ *
+ * isZeroish('0') //= true
+ * isZeroish(0) //= true
+ * isZeroish(10) //= true
+ *
+ */
+module.exports = x => x === 0 || x === '0' || '' + x == '0'
diff --git a/src/deps/loop/README.md b/src/deps/loop/README.md
new file mode 100644
index 0000000..b4605f5
--- /dev/null
+++ b/src/deps/loop/README.md
@@ -0,0 +1,10 @@
+* _ramda_
+ + has a sanctuary structure to keep a standard, very extendable
+ - is super hard to read [has a perf hit with the additional keys (minor)]
+* _lodash_
+ + has more functions to have easier ones to use the one you need,
+ - but they are
+* _chain-able_
+ + has chains to iterate & transform on the classes which have the best names
+ - has larger file size, longer to implement in a way that can be used fp & oop
+ + could easily handle compatibility to allow api usage with ramda &| lodash, external functionality
diff --git a/src/deps/loop/each/arrayEach.js b/src/deps/loop/each/arrayEach.js
new file mode 100644
index 0000000..322d299
--- /dev/null
+++ b/src/deps/loop/each/arrayEach.js
@@ -0,0 +1,24 @@
+const isNill = require('../../is/nullOrUndefined')
+
+/**
+ * A specialized version of `forEach` for arrays.
+ * @since 5.0.0-beta.5
+ * @memberOf loop
+ *
+ * @param {Array} [array] The array to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @return {Array} Returns `array`.
+ */
+function arrayEach(array, iteratee) {
+ let index = -1
+ const length = isNill(array) ? 0 : array.length
+
+ while (++index < length) {
+ if (iteratee(array[index], index, array) === false) {
+ break
+ }
+ }
+ return array
+}
+
+module.exports = arrayEach
diff --git a/src/deps/loop/each/baseEach.js b/src/deps/loop/each/baseEach.js
new file mode 100644
index 0000000..fa07fea
--- /dev/null
+++ b/src/deps/loop/each/baseEach.js
@@ -0,0 +1,40 @@
+const isArrayLike = require('../../is/arrayLike')
+const isNill = require('../../is/nullOrUndefined')
+const baseForOwn = require('./baseForOwn')
+
+/**
+ * The base implementation of `forEach`.
+ * @since 5.0.0-beta.6
+ * @memberOf loop
+ *
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @return {Array|Object} Returns `collection`.
+ *
+ * @see https://github.com/lodash/lodash/blob/master/.internal/baseEach.js
+ *
+ */
+function baseEach(collection, iteratee) {
+ if (isNill(collection)) {
+ return collection
+ }
+ else if (!isArrayLike(collection)) {
+ return baseForOwn(collection, iteratee)
+ }
+
+ // @TODO toObj, length
+ const length = collection.length
+ const iterable = Object(collection)
+ let index = -1
+
+ while (++index < length) {
+ // stop when they return false
+ if (iteratee(iterable[index], index, iterable) === false) {
+ break
+ }
+ }
+
+ return collection
+}
+
+module.exports = baseEach
diff --git a/src/deps/loop/each/baseFor.js b/src/deps/loop/each/baseFor.js
new file mode 100644
index 0000000..59460b1
--- /dev/null
+++ b/src/deps/loop/each/baseFor.js
@@ -0,0 +1,29 @@
+/**
+ * The base implementation of `baseForOwn` which iterates over `object`
+ * properties returned by `keysFunc` and invokes `iteratee` for each property.
+ * Iteratee functions may exit iteration early by explicitly returning `false`.
+ * @since 5.0.0-beta.6
+ * @memberOf loop
+ *
+ * @param {Object} object The object to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @param {Function} keysFunc The function to get the keys of `object`.
+ * @return {Object} Returns `object`.
+ *
+ */
+function baseFor(object, iteratee, keysFunc) {
+ const iterable = Object(object)
+ const props = keysFunc(object)
+ let {length} = props
+ let index = -1
+
+ while (length--) {
+ const key = props[++index]
+ if (iteratee(iterable[key], key, iterable) === false) {
+ break
+ }
+ }
+ return object
+}
+
+module.exports = baseFor
diff --git a/src/deps/loop/each/baseForOwn.js b/src/deps/loop/each/baseForOwn.js
new file mode 100644
index 0000000..e3d0156
--- /dev/null
+++ b/src/deps/loop/each/baseForOwn.js
@@ -0,0 +1,18 @@
+const keys = require('../../util/keys')
+const baseFor = require('./baseFor')
+
+/**
+ * The base implementation of `forOwn`.
+ *
+ * @private
+ * @param {Object} object The object to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @return {Object} Returns `object`.
+ *
+ * @see https://github.com/lodash/lodash/blob/master/.internal/baseForOwn.js
+ */
+function baseForOwn(object, iteratee) {
+ return object && baseFor(object, iteratee, keys)
+}
+
+module.exports = baseForOwn
diff --git a/src/deps/loop/each/forEach.js b/src/deps/loop/each/forEach.js
new file mode 100644
index 0000000..4cd0559
--- /dev/null
+++ b/src/deps/loop/each/forEach.js
@@ -0,0 +1,41 @@
+const isArray = require('../../is/array')
+const arrayEach = require('./arrayEach')
+const baseEach = require('./baseEach')
+
+/**
+ * Iterates over elements of `collection` and invokes `iteratee` for each element.
+ * The iteratee is invoked with three arguments: (value, index|key, collection).
+ * Iteratee functions may exit iteration early by explicitly returning `false`.
+ *
+ * **Note:** As with other "Collections" methods, objects with a "length"
+ * property are iterated like arrays. To avoid this behavior use `forIn`
+ * or `forOwn` for object iteration.
+ * @since 5.0.0-beta.6
+ * @memberOf loop
+ *
+ * @fork 0.1.0
+ * @alias each
+ * @category Collection
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @return {Array|Object} Returns `collection`.
+ *
+ * @see forEachRight, forIn, forInRight, forOwn, forOwnRight
+ * @see https://github.com/lodash/lodash/blob/master/forEach.js
+ * @see https://github.com/ramda/ramda/blob/master/src/forEach.js
+ *
+ * @example
+ *
+ * forEach([1, 2], value => console.log(value))
+ * //=> Logs `1` then `2`.
+ *
+ * forEach({ 'a': 1, 'b': 2 }, (value, key) => console.log(key))
+ * //=> Logs 'a' then 'b' (iteration order is not guaranteed).
+ *
+ */
+function forEach(collection, iteratee) {
+ const func = isArray(collection) ? arrayEach : baseEach
+ return func(collection, iteratee)
+}
+
+module.exports = forEach
diff --git a/src/deps/loop/each/forInUnguarded.js b/src/deps/loop/each/forInUnguarded.js
new file mode 100644
index 0000000..a63b91d
--- /dev/null
+++ b/src/deps/loop/each/forInUnguarded.js
@@ -0,0 +1,15 @@
+/**
+ * @desc loop for in, no checks on hasOwnProperty, useful for flattening proto
+ * @since 5.0.0-beta.6
+ * @memberOf loop
+ * @curried 2
+ *
+ * @param {Array|Object|Iteratable} collection collection to iterate
+ * @param {Function} iteratee The function invoked per iteration
+ * @return {Object|Array|*} collection
+ */
+module.exports = function forInUnguarded(collection, iteratee) {
+ // eslint-disable-next-line
+ for (let prop in collection) iteratee(collection[prop], prop, collection)
+ return collection
+}
diff --git a/src/deps/loop/each/forOwn.js b/src/deps/loop/each/forOwn.js
new file mode 100644
index 0000000..f2b1b01
--- /dev/null
+++ b/src/deps/loop/each/forOwn.js
@@ -0,0 +1,51 @@
+/* eslint no-unused-expressions: "OFF" */
+/* eslint guard-for-in: "OFF" */
+const toObj = require('../../cast/toObj')
+const hasOwnProperty = require('../../util/hasOwnProperty')
+
+/**
+ * Iterates over own enumerable string keyed properties of an object and
+ * invokes `iteratee` for each property. The iteratee is invoked with three
+ * arguments: (value, key, object). Iteratee functions may exit iteration
+ * early by explicitly returning `false`.
+ *
+ * @since 5.0.0-beta.6
+ * @memberOf loop
+ *
+ * @param {Object} object The object to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @return {Object} object passed in originally
+ *
+ * @fork 0.3.0
+ * @category Object
+ *
+ * @NOTE for array, object, and string, iterates over property/index/key
+ * @TODO !!! did not return object, consistently the others do, why?
+ *
+ * @see forEach, forEachRight, forIn, forInRight, forOwnRight
+ * {@link https://github.com/lodash/lodash/blob/master/forOwn.js lodash-forown}
+ * @see {@link lodash-forown}
+ *
+ * @example
+ *
+ * function Foo() {
+ * this.a = 1
+ * this.b = 2
+ * }
+ *
+ * Foo.prototype.c = 3
+ *
+ * forOwn(new Foo, (value, key) => console.log(key))
+ * //=> Logs 'a' then 'b' (iteration order is not guaranteed).
+ *
+ */
+function forOwn(object, iteratee) {
+ const obj = toObj(object)
+
+ for (const key in obj)
+ hasOwnProperty(obj, key) && iteratee(obj[key], key, obj)
+
+ return obj
+}
+
+module.exports = forOwn
diff --git a/src/deps/loop/fantasy/_each.js b/src/deps/loop/fantasy/_each.js
new file mode 100644
index 0000000..f76e643
--- /dev/null
+++ b/src/deps/loop/fantasy/_each.js
@@ -0,0 +1,57 @@
+const preferExistingMethod = require('../../fp/preferExistingMethod')
+const curry = require('../../fp/curry')
+
+/**
+ * Iterate over an input `list`, calling a provided function `fn` for each
+ * element in the list.
+ *
+ * `fn` receives one argument: *(value)*.
+ *
+ * Note: `R.forEach` does not skip deleted or unassigned indices (sparse
+ * arrays), unlike the native `Array.prototype.forEach` method. For more
+ * details on this behavior, see:
+ * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach#Description
+ *
+ * Also note that, unlike `Array.prototype.forEach`, Ramda's `forEach` returns
+ * the original array. In some libraries this function is named `each`.
+ *
+ * Dispatches to the `forEach` method of the second argument, if present.
+ *
+ * @memberOf fp
+ * @since 5.0.0-beta.6
+ * @curried 2
+ *
+ * @param {Function} fn The function to invoke. Receives one argument, `value`.
+ * @param {Array} list The list to iterate over.
+ * @return {Array} The original list.
+ *
+ * @func
+ * @fork v0.1.1
+ * @category List
+ * @sig (a -> *) -> [a] -> [a]
+ * @symb R.forEach(f, [a, b, c]) = [a, b, c]
+ *
+ * @see addIndex
+ *
+ * @example
+ *
+ * var printXPlusFive = x => console.log(x + 5);
+ * forEach(printXPlusFive, [1, 2, 3]); //=> [1, 2, 3]
+ * // logs 6
+ * // logs 7
+ * // logs 8
+ *
+ *
+ */
+function _forEach(fn, list) {
+ const len = list.length
+ let index = 0
+ while (index < len) {
+ fn(list[index++])
+ // fn(list[index])
+ // index += 1
+ }
+ return list
+}
+
+module.exports = curry(2, preferExistingMethod('forEach', _forEach))
diff --git a/src/deps/loop/fantasy/_map.js b/src/deps/loop/fantasy/_map.js
new file mode 100644
index 0000000..0e460fa
--- /dev/null
+++ b/src/deps/loop/fantasy/_map.js
@@ -0,0 +1,52 @@
+const isFunction = require('../../is/function')
+const isObjTag = require('../../is/objTag')
+const curry = require('../../fp/curry')
+const keys = require('../../util/keys')
+const preAllocate = require('../../array/preAllocate')
+const reduce = require('./_reduce')
+
+/**
+ * @desc `while (index < list.length) push fn(list[index++])`
+ * @name _map
+ * @alias baseMaps
+ * @since 5.0.0-beta.1
+ * @memberOf loop
+ *
+ * {@link https://github.com/ramda/ramda/blob/master/src/internal/_map.js ramda-_map}
+ * @see {@link ramda-_map}
+ *
+ * @param {Function} fn function to apply
+ * @param {Function|List} functorList function/list
+ * @return {Array}
+ */
+function _map(fn, functorList) {
+ let idx = 0
+ const len = functorList.length
+ const result = preAllocate(len)
+
+ while (idx < len) {
+ result[idx] = fn(functorList[idx])
+ idx += 1
+ }
+
+ return result
+}
+
+function map(fn, functor) {
+ if (isFunction(functor)) {
+ return curry(functor.length, function() {
+ return fn.call(this, functor.apply(this, arguments))
+ })
+ }
+ else if (isObjTag(functor)) {
+ return reduce(function(acc, key) {
+ acc[key] = fn(functor[key])
+ return acc
+ }, {}, keys(functor))
+ }
+ else {
+ return _map(fn, functor)
+ }
+}
+
+module.exports = map
diff --git a/src/deps/loop/fantasy/_reduce.js b/src/deps/loop/fantasy/_reduce.js
new file mode 100644
index 0000000..ce9bc4b
--- /dev/null
+++ b/src/deps/loop/fantasy/_reduce.js
@@ -0,0 +1,97 @@
+const isNil = require('../../is/nullOrUndefined')
+const isFunction = require('../../is/function')
+const hasOwnProperty = require('../../util/hasOwnProperty')
+const symIterator = require('../../symbols/iterator')
+const isArrayLike = require('../../is/arrayLike')
+const bind = require('../../fp/bind')
+
+const ON_INIT = '@@transducer/init'
+const ON_STEP = '@@transducer/step'
+const ON_REDUCED = '@@transducer/reduced'
+const ON_VALUE = '@@transducer/value'
+const ON_RESULT = '@@transducer/result'
+const FANTASY_LAND_REDUCE = 'fantasy-land/reduce'
+
+var _xwrap = (function() {
+ function XWrap(fn) {
+ this.f = fn
+ }
+ XWrap.prototype[ON_INIT] = function() {
+ throw new Error('init not implemented on XWrap')
+ }
+ XWrap.prototype[ON_RESULT] = function(acc) { return acc }
+ XWrap.prototype[ON_STEP] = function(acc, x) {
+ return this.f(acc, x)
+ }
+
+ // @TODO construct?
+ return function _xwrap(fn) {
+ return new XWrap(fn)
+ }
+})()
+
+/**
+ * @name _reduce
+ * @since 5.0.0-beta.6
+ * @memberOf loop
+ * @return {Function}
+ */
+// list aka functor
+const reduce = (function() {
+ function _arrayReduce(xf, acc, list) {
+ let idx = 0
+ const len = list.length
+ while (idx < len) {
+ acc = xf[ON_STEP](acc, list[idx])
+ if (acc && acc[ON_REDUCED]) {
+ acc = acc[ON_VALUE]
+ break
+ }
+ idx += 1
+ }
+ return xf[ON_RESULT](acc)
+ }
+
+ function _iterableReduce(xf, acc, iter) {
+ let step = iter.next()
+ while (!step.done) {
+ acc = xf[ON_STEP](acc, step.value)
+ if (hasOwnProperty(acc, ON_REDUCED)) {
+ acc = acc[ON_VALUE]
+ break
+ }
+ step = iter.next()
+ }
+ return xf[ON_RESULT](acc)
+ }
+
+ function _methodReduce(xf, acc, obj, methodName) {
+ return xf[ON_RESULT](obj[methodName](bind(xf[ON_STEP], xf), acc))
+ }
+
+ return function _reduce(fn, acc, list) {
+ if (isFunction(fn)) {
+ fn = _xwrap(fn)
+ }
+
+ if (isArrayLike(list)) {
+ return _arrayReduce(fn, acc, list)
+ }
+ else if (isFunction(list[FANTASY_LAND_REDUCE])) {
+ return _methodReduce(fn, acc, list, FANTASY_LAND_REDUCE)
+ }
+ else if (!isNil(list[symIterator])) {
+ return _iterableReduce(fn, acc, list[symIterator]())
+ }
+ else if (isFunction(list.next)) {
+ return _iterableReduce(fn, acc, list)
+ }
+ else if (isFunction(list.reduce)) {
+ return _methodReduce(fn, acc, list, 'reduce')
+ }
+
+ throw new TypeError('reduce: list must be array or iterable')
+ }
+})()
+
+module.exports = reduce
diff --git a/src/deps/loop/fantasy/_reduceBy.js b/src/deps/loop/fantasy/_reduceBy.js
new file mode 100644
index 0000000..92c6e7e
--- /dev/null
+++ b/src/deps/loop/fantasy/_reduceBy.js
@@ -0,0 +1,59 @@
+// var _curryN = require('./internal/_curryN')
+// var _dispatchable = require('./internal/_dispatchable')
+// var _has = require('./internal/_has')
+// var _reduce = require('./internal/_reduce')
+// var _xreduceBy = require('./internal/_xreduceBy')
+//
+//
+// /**
+// * Groups the elements of the list according to the result of calling
+// * the String-returning function `keyFn` on each element and reduces the elements
+// * of each group to a single value via the reducer function `valueFn`.
+// *
+// * This function is basically a more general [`groupBy`](#groupBy) function.
+// *
+// * Acts as a transducer if a transformer is given in list position.
+// *
+// * @func
+// * @memberOf R
+// * @since v0.20.0
+// * @category List
+// * @sig ((a, b) -> a) -> a -> (b -> String) -> [b] -> {String: a}
+// * @param {Function} valueFn The function that reduces the elements of each group to a single
+// * value. Receives two values, accumulator for a particular group and the current element.
+// * @param {*} acc The (initial) accumulator value for each group.
+// * @param {Function} keyFn The function that maps the list's element into a key.
+// * @param {Array} list The array to group.
+// * @return {Object} An object with the output of `keyFn` for keys, mapped to the output of
+// * `valueFn` for elements which produced that key when passed to `keyFn`.
+// * @see R.groupBy, R.reduce
+// * @example
+// *
+// * var reduceToNamesBy = R.reduceBy((acc, student) => acc.concat(student.name), []);
+// * var namesByGrade = reduceToNamesBy(function(student) {
+// * var score = student.score;
+// * return score < 65 ? 'F' :
+// * score < 70 ? 'D' :
+// * score < 80 ? 'C' :
+// * score < 90 ? 'B' : 'A';
+// * });
+// * var students = [{name: 'Lucy', score: 92},
+// * {name: 'Drew', score: 85},
+// * // ...
+// * {name: 'Bart', score: 62}];
+// * namesByGrade(students);
+// * // {
+// * // 'A': ['Lucy'],
+// * // 'B': ['Drew']
+// * // // ...,
+// * // 'F': ['Bart']
+// * // }
+// */
+// module.exports = _curryN(4, [], _dispatchable([], _xreduceBy,
+// function reduceBy(valueFn, valueAcc, keyFn, list) {
+// return _reduce(function(acc, elt) {
+// var key = keyFn(elt)
+// acc[key] = valueFn(_has(key, acc) ? acc[key] : valueAcc, elt)
+// return acc
+// }, {}, list)
+// }))
diff --git a/src/deps/loop/fantasy/converge.js b/src/deps/loop/fantasy/converge.js
new file mode 100644
index 0000000..acb0a98
--- /dev/null
+++ b/src/deps/loop/fantasy/converge.js
@@ -0,0 +1,59 @@
+const ENV_DEBUG = require('../../env/debug')
+const argumentor = require('../../cast/argumentor')
+const curry = require('../../fp/curry')
+const max = require('../../math/max')
+const reduce = require('./_reduce')
+const pluck = require('./pluck')
+const map = require('./_map')
+
+/**
+ * Accepts a converging function and a list of branching functions and returns
+ * a new function. When invoked, this new function is applied to some
+ * arguments, each branching function is applied to those same arguments. The
+ * results of each branching function are passed as arguments to the converging
+ * function to produce the return value.
+ * @since 5.0.0-beta.6
+ * @memberOf fp
+ *
+ * @param {Function} after A function. `after` will be invoked with the return values of
+ * `fn1` and `fn2` as its arguments.
+ * @param {Array} functions A list of functions.
+ * @return {Function} A new function.
+ *
+ * @NOTE important to use 2+ functions in functions param
+ *
+ * @func
+ * @fork v0.4.2
+ * @category Function
+ * @sig ((x1, x2, ...) -> z) -> [((a, b, ...) -> x1), ((a, b, ...) -> x2), ...] -> (a -> b -> ... -> z)
+ * @symb converge(f, [g, h])(a, b) = f(g(a, b), h(a, b))
+ *
+ * @see useWith
+ *
+ * @example
+ *
+ * var average = converge(divide, [sum, length])
+ * average([1, 2, 3, 4, 5, 6, 7]) //=> 4
+ *
+ * var strangeConcat = converge(concat, [toUpper, toLower])
+ * strangeConcat("Yodel") //=> "YODELyodel"
+ *
+ */
+function _converge(after, fns) {
+ const num = reduce(max, 0, pluck('length', fns))
+ return curry(num, function() {
+ const args = argumentor.apply(null, arguments)
+ const self = this
+ let index = 0
+
+ return after.apply(self, map(function(fn) {
+ fn = fn || fns[index++]
+
+ // console.log({fn, args, fns, after, index, i: fns[index++]})
+ return fn.apply(self, args)
+ }, fns))
+ })
+}
+
+const converge = curry(2, _converge)
+module.exports = converge
diff --git a/src/deps/loop/fantasy/juxt.js b/src/deps/loop/fantasy/juxt.js
new file mode 100644
index 0000000..6613201
--- /dev/null
+++ b/src/deps/loop/fantasy/juxt.js
@@ -0,0 +1,28 @@
+const converge = require('./converge')
+const argumentor = require('../../cast/argumentsToArray')
+
+/**
+ * juxt applies a list of functions to a list of values.
+ * @since 5.0.0-beta.7
+ * @memberOf loop
+ * @curried 1
+ *
+ * @param {Array} fns An array of functions
+ * @return {Function} A function that returns a list of values after applying each of the original `fns` to its parameters.
+ *
+ * @func
+ * @fork v0.19.0
+ * @category Function
+ * @sig [(a, b, ..., m) -> n] -> ((a, b, ..., m) -> [n])
+ * @symb R.juxt([f, g, h])(a, b) = [f(a, b), g(a, b), h(a, b)]
+ * @see R.applySpec
+ *
+ * @example
+ *
+ * var getRange = juxt([Math.min, Math.max]);
+ * getRange(3, 4, 9, -3); //=> [-3, 9]
+ *
+ */
+module.exports = (function juxt(fns) {
+ return converge(argumentor, fns)
+})
diff --git a/src/deps/loop/fantasy/pluck.js b/src/deps/loop/fantasy/pluck.js
new file mode 100644
index 0000000..844593a
--- /dev/null
+++ b/src/deps/loop/fantasy/pluck.js
@@ -0,0 +1,42 @@
+const prop = require('../../fp/prop')
+const curry = require('../../fp/curry')
+const map = require('./_map')
+
+/**
+ * Returns a new list by plucking the same named property off all objects in
+ * the list supplied.
+ *
+ * `pluck` will work on
+ * any [functor](https://github.com/fantasyland/fantasy-land#functor) in
+ * addition to arrays, as it is equivalent to `map(prop(k), f)`.
+ * @since 5.0.0-beta.6
+ * @memberOf loop
+ *
+ * @func
+ * @fork v0.1.0
+ * @category List
+ * @sig Functor f => k -> f {k: v} -> f v
+ *
+ * @param {Number|String} path The key name to pluck off of each object.
+ * @param {Array} functorList The array or functor to consider.
+ * @return {Array} The list of values for the given key.
+ *
+ * @see fp/props
+ * {@link https://github.com/ramda/ramda/blob/master/src/pluck.js ramda-pluck}
+ * @see {@link ramda-pluck}
+ *
+ * @symb pluck('x', [{x: 1, y: 2}, {x: 3, y: 4}, {x: 5, y: 6}]) = [1, 3, 5]
+ * @symb pluck(0, [[1, 2], [3, 4], [5, 6]]) = [1, 3, 5]
+ *
+ * @example
+ *
+ * pluck('a')([{a: 1}, {a: 2}]); //=> [1, 2]
+ * pluck(0)([[1, 2], [3, 4]]); //=> [1, 3]
+ * pluck('val', {a: {val: 3}, b: {val: 5}}); //=> {a: 3, b: 5}
+ *
+ */
+function _pluck(path, functorList) {
+ return map(prop(path), functorList)
+}
+
+module.exports = curry(2, _pluck)
diff --git a/src/deps/loop/filter/filterWhere.js b/src/deps/loop/filter/filterWhere.js
new file mode 100644
index 0000000..05ff275
--- /dev/null
+++ b/src/deps/loop/filter/filterWhere.js
@@ -0,0 +1,63 @@
+const isArray = require('../../is/array')
+const objOrArrayKeys = require('../../util/keysObjOrArray')
+const curry = require('../../fp/curry')
+const emptyTarget = require('../../dopemerge/emptyTarget')
+const defaultTo = require('../../cast/defaultTo')
+
+/**
+ * filters an object or array
+ * `iteratee`. The iteratee is invoked with three arguments: (value, key, object).
+ * @memberOf loop
+ *
+ * @param {Object} obj The object to iterate over.
+ * @param {Function} predicate The function invoked per iteration.
+ * @param {Object} [init={}] output result object initial value
+ * @return {Array} Returns the new mapped array.
+ *
+ * @name filterWhere
+ * @alias pluckWhere
+ * @alias filter
+ *
+ * @since 5.0.0
+ * @category Object
+ *
+ * {@link https://github.com/ramda/ramda/tree/v0.24.1/src/filter.js ramda-filter}
+ * {@link https://github.com/lodash/lodash/blob/master/mapObject.js lodash-map-obj}
+ * {@link https://github.com/jashkenas/underscore/blob/master/underscore.js#L1021 underscore-map-obj}
+ * {@link https://github.com/lodash/lodash/blob/master/map.js lodash-map}
+ * @see {@link lodash-map}
+ * @see {@link underscore-map}
+ * @see {@link ramda-filter}
+ *
+ * @TODO add `key first` sig option
+ *
+ * @example
+ *
+ * map([1, 2, 3, 'nope'], isNumber)
+ * //=> [1, 2, 3]
+ *
+ * @example
+ *
+ * /// because `value` is first
+ * map({'1': 1, 'nope': 'nope'}, isNumber)
+ * //=> [1, 2, 3]
+ *
+ */
+function filterMap(obj, predicate, init) {
+ const result = defaultTo(emptyTarget(obj), init)
+ const isArrayObj = isArray(obj)
+ const keys = objOrArrayKeys(obj)
+
+ for (let index = 0; index < keys.length; index++) {
+ const key = isArrayObj ? index : keys[index]
+ const value = obj[key]
+
+ if (predicate(value, key, obj)) {
+ result[key] = value
+ }
+ }
+
+ return result
+}
+
+module.exports = curry(2, filterMap)
diff --git a/src/deps/loop/filterMap.js b/src/deps/loop/filterMap.js
new file mode 100644
index 0000000..9f9284b
--- /dev/null
+++ b/src/deps/loop/filterMap.js
@@ -0,0 +1,16 @@
+// slower & smaller would be filterWhere, then mapWhere
+// faster & bigger would be remake the whole thing, use `base` things
+
+const filterWhere = require('./filter/filterWhere')
+const mapObjOrArray = require('./map/mapObjOrArray')
+
+// could use `isMatch`
+// filterKey
+// filterValue
+function filterMapObjOrArray(obj, filter, onValue, onKey, result = {}) {
+ result = filterWhere(obj, filter, result)
+ result = mapObjOrArray(obj, onValue, onKey, result)
+ return result
+}
+
+module.exports = filterMapObjOrArray
diff --git a/src/deps/loop/findIndex.js b/src/deps/loop/findIndex.js
new file mode 100644
index 0000000..caca8c8
--- /dev/null
+++ b/src/deps/loop/findIndex.js
@@ -0,0 +1,23 @@
+/**
+ * The base implementation of `findIndex` and `findLastIndex`.
+ *
+ * @private
+ * @param {Array} array The array to inspect.
+ * @param {Function} predicate The function invoked per iteration.
+ * @param {number} fromIndex The index to search from.
+ * @param {boolean} [fromRight] Specify iterating from right to left.
+ * @returns {number} Returns the index of the matched value, else `-1`.
+ */
+function baseFindIndex(array, predicate, fromIndex, fromRight) {
+ const {length} = array
+ let index = fromIndex + (fromRight ? 1 : -1)
+
+ while ((fromRight ? index-- : ++index < length)) {
+ if (predicate(array[index], index, array)) {
+ return index
+ }
+ }
+ return -1
+}
+
+module.exports = baseFindIndex
diff --git a/src/deps/loop/flattenForIn.js b/src/deps/loop/flattenForIn.js
new file mode 100644
index 0000000..4b2923d
--- /dev/null
+++ b/src/deps/loop/flattenForIn.js
@@ -0,0 +1,14 @@
+const forInUnguarded = require('./each/forInUnguarded')
+
+/**
+ * @desc copies forInUnguarded
+ * @since 5.0.0-beta.6
+ * @name flattenForIn
+ * @alias flattenProto
+ * @alias flattenPrototype
+ * @param {Object} x copy proto to self
+ * @return {number}
+ */
+module.exports = x => forInUnguarded(x, (value, key) => {
+ x[key] = value
+})
diff --git a/src/deps/loop/flipped/README.md b/src/deps/loop/flipped/README.md
new file mode 100644
index 0000000..0f3093e
--- /dev/null
+++ b/src/deps/loop/flipped/README.md
@@ -0,0 +1 @@
+usually the iterator callbacks do `value, key`, instead do `key, value`
diff --git a/src/deps/loop/flipped/filterWhereFlipped.js b/src/deps/loop/flipped/filterWhereFlipped.js
new file mode 100644
index 0000000..7bb70e7
--- /dev/null
+++ b/src/deps/loop/flipped/filterWhereFlipped.js
@@ -0,0 +1,6 @@
+const filterWhere = require('../filter/filterWhere')
+const flip2 = require('../../fp/flip2')
+
+module.exports = function filterWhereKeyValue(array, iteratee) {
+ return filterWhere(array, flip2(iteratee))
+}
diff --git a/src/deps/loop/flipped/forEachFlipped.js b/src/deps/loop/flipped/forEachFlipped.js
new file mode 100644
index 0000000..27e1ed7
--- /dev/null
+++ b/src/deps/loop/flipped/forEachFlipped.js
@@ -0,0 +1,7 @@
+const forEach = require('../each/forEach')
+const flip2 = require('../../fp/flip2')
+
+// @TODO nthArg, flip2
+module.exports = function forEachKeyValue(array, iteratee) {
+ return forEach(array, flip2(iteratee))
+}
diff --git a/src/deps/loop/flipped/forOwnFlipped.js b/src/deps/loop/flipped/forOwnFlipped.js
new file mode 100644
index 0000000..0fcc102
--- /dev/null
+++ b/src/deps/loop/flipped/forOwnFlipped.js
@@ -0,0 +1,7 @@
+const forOwn = require('../each/forOwn')
+const flip2 = require('../../fp/flip2')
+
+// @TODO nthArg, flip2
+module.exports = function forOwnKeyValue(array, iteratee) {
+ return forOwn(array, flip2(iteratee))
+}
diff --git a/src/deps/loop/flipped/mapArrayFlipped.js b/src/deps/loop/flipped/mapArrayFlipped.js
new file mode 100644
index 0000000..f3d6f0e
--- /dev/null
+++ b/src/deps/loop/flipped/mapArrayFlipped.js
@@ -0,0 +1,6 @@
+const mapArray = require('../map/mapArray')
+const flip2 = require('../../fp/flip2')
+
+module.exports = function mapArrayFlipped(array, iteratee) {
+ return mapArray(array, flip2(iteratee))
+}
diff --git a/src/deps/loop/flipped/mapObjFlipped.js b/src/deps/loop/flipped/mapObjFlipped.js
new file mode 100644
index 0000000..008d9eb
--- /dev/null
+++ b/src/deps/loop/flipped/mapObjFlipped.js
@@ -0,0 +1,6 @@
+const mapObjOrArray = require('../map/mapObjOrArray')
+const flip2 = require('../../fp/flip2')
+
+module.exports = function mapObjOrArrayFlipped(array, iteratee) {
+ return mapObjOrArray(array, flip2(iteratee))
+}
diff --git a/src/deps/loop/flipped/mapObjOrArrayFlipped.js b/src/deps/loop/flipped/mapObjOrArrayFlipped.js
new file mode 100644
index 0000000..008d9eb
--- /dev/null
+++ b/src/deps/loop/flipped/mapObjOrArrayFlipped.js
@@ -0,0 +1,6 @@
+const mapObjOrArray = require('../map/mapObjOrArray')
+const flip2 = require('../../fp/flip2')
+
+module.exports = function mapObjOrArrayFlipped(array, iteratee) {
+ return mapObjOrArray(array, flip2(iteratee))
+}
diff --git a/src/deps/loop/flipped/mapObjOrArrayKeysFlipped.js b/src/deps/loop/flipped/mapObjOrArrayKeysFlipped.js
new file mode 100644
index 0000000..68b5284
--- /dev/null
+++ b/src/deps/loop/flipped/mapObjOrArrayKeysFlipped.js
@@ -0,0 +1,6 @@
+const mapObjOrArrayKeys = require('../map/mapObjOrArrayKeys')
+const flip2 = require('../../fp/flip2')
+
+module.exports = function mapObjOrArrayKeysFlipped(array, iteratee) {
+ return mapObjOrArrayKeys(array, flip2(iteratee))
+}
diff --git a/src/deps/loop/flipped/mapObjOrArrayValsFlipped.js b/src/deps/loop/flipped/mapObjOrArrayValsFlipped.js
new file mode 100644
index 0000000..bcd8985
--- /dev/null
+++ b/src/deps/loop/flipped/mapObjOrArrayValsFlipped.js
@@ -0,0 +1,6 @@
+const mapObjOrArrayVals = require('../map/mapObjOrArrayVals')
+const flip2 = require('../../fp/flip2')
+
+module.exports = function mapObjOrArrayValsFlipped(array, iteratee) {
+ return mapObjOrArrayVals(array, flip2(iteratee))
+}
diff --git a/src/deps/loop/flipped/reduceArrayFlipped.js b/src/deps/loop/flipped/reduceArrayFlipped.js
new file mode 100644
index 0000000..5f1e85a
--- /dev/null
+++ b/src/deps/loop/flipped/reduceArrayFlipped.js
@@ -0,0 +1,4 @@
+const reduceArray = require('../reduce/reduceArray')
+const flip2 = require('../../fp/flip2')
+
+module.exports = flip2(reduceArray)
diff --git a/src/deps/loop/index.js b/src/deps/loop/index.js
new file mode 100644
index 0000000..746d35b
--- /dev/null
+++ b/src/deps/loop/index.js
@@ -0,0 +1 @@
+module.exports = require('./loop')
diff --git a/src/deps/loop/loop.js b/src/deps/loop/loop.js
new file mode 100644
index 0000000..d966ad2
--- /dev/null
+++ b/src/deps/loop/loop.js
@@ -0,0 +1,105 @@
+/* eslint import/max-dependencies: "OFF" */
+
+// each
+const arrayEach = require('./each/arrayEach')
+const baseEach = require('./each/baseEach')
+const baseFor = require('./each/baseFor')
+const forEach = require('./each/forEach')
+const forOwn = require('./each/forOwn')
+const forInUnguarded = require('./each/forInUnguarded')
+const baseForOwn = require('./each/baseForOwn')
+// filter
+const filterWhere = require('./filter/filterWhere')
+// map
+const mapArray = require('./map/mapArray')
+const mapAcum = require('./map/mapAcum')
+const mapArrayIndex = require('./map/mapArrayKeys')
+const mapObjKeys = require('./map/mapObjKeys')
+const mapObjVals = require('./map/mapObjVals')
+const mapObjOrArray = require('./map/mapObjOrArray')
+const mapObjOrArrayKeys = require('./map/mapObjOrArrayKeys')
+const mapObjOrArrayVals = require('./map/mapObjOrArrayVals')
+// sort
+const sort = require('./sort/sort')
+const sortBy = require('./sort/sortBy')
+const sortByR = require('./sort/sortByR')
+const sortWith = require('./sort/sortWith')
+const comparator = require('./sort/comparator')
+// flipped
+const filterWhereFlipped = require('./flipped/filterWhereFlipped')
+const forOwnFlipped = require('./flipped/forOwnFlipped')
+const forEachFlipped = require('./flipped/forEachFlipped')
+const mapObjOrArrayKeysFlipped = require('./flipped/mapObjOrArrayKeysFlipped')
+const mapObjValsFlipped = require('./flipped/mapObjOrArrayValsFlipped')
+const mapObjOrArrayFlipped = require('./flipped/mapObjOrArrayFlipped')
+const mapArrayFlipped = require('./flipped/mapArrayFlipped')
+const mapObjFlipped = require('./flipped/mapArrayFlipped')
+// fantasy
+const mapFantasy = require('./fantasy/_map')
+const reduceFantasy = require('./fantasy/_reduce')
+const converge = require('./fantasy/converge')
+const pluck = require('./fantasy/pluck')
+
+const keyVal = {
+ filterWhere: filterWhereFlipped,
+ mapKey: mapObjOrArrayKeysFlipped,
+ forOwn: forOwnFlipped,
+ forEach: forEachFlipped,
+ mapObj: mapObjFlipped,
+ mapObjOrArray: mapObjOrArrayFlipped,
+ mapArray: mapArrayFlipped,
+}
+
+/**
+ * @member loop
+ * @symb 🔁
+ * @since 5.0.0-beta.6
+ */
+module.exports = {
+ // each
+ arrayEach,
+ baseEach,
+ baseFor,
+ forEach,
+ forOwn,
+ // filter
+ filterWhere,
+ // arr
+ mapArray,
+ mapArrayIndex,
+ mapObjKeys,
+ mapAcum,
+ // obj
+ mapObjVals,
+ mapObjOrArray,
+ mapObjOrArrayKeys,
+ mapObjOrArrayVals,
+ mapObjValsFlipped,
+ // sort
+ sort,
+ sortBy,
+ sortByR,
+ sortWith,
+ comparator,
+ // fantasy
+ mapFantasy,
+ reduceFantasy,
+ converge,
+ pluck,
+
+ // flipped
+ map: mapObjOrArray,
+ // named
+ // keyVal,
+ flipped: keyVal,
+
+ forInUnguarded,
+ baseForOwn,
+ filterWhereFlipped,
+ mapObjOrArrayKeysFlipped,
+ forOwnFlipped,
+ forEachFlipped,
+ mapObjFlipped,
+ mapObjOrArrayFlipped,
+ mapArrayFlipped,
+}
diff --git a/src/deps/loop/map/README.md b/src/deps/loop/map/README.md
new file mode 100644
index 0000000..05d33b0
--- /dev/null
+++ b/src/deps/loop/map/README.md
@@ -0,0 +1,4 @@
+TODO: mapIn using `for in`
+
+// could be a chain too
+TODO: mapAnything({init: {}, keys(), values())
diff --git a/src/deps/loop/map/mapAcum.js b/src/deps/loop/map/mapAcum.js
new file mode 100644
index 0000000..bd36444
--- /dev/null
+++ b/src/deps/loop/map/mapAcum.js
@@ -0,0 +1,59 @@
+const curry = require('../../fp/curry')
+
+/**
+ * The `mapAccum` function behaves like a combination of map and reduce; it
+ * applies a function to each element of a list, passing an accumulating
+ * parameter from left to right, and returning a final value of this
+ * accumulator together with the new list.
+ *
+ * The iterator function receives two arguments, *acc* and *value*, and should
+ * return a tuple *[acc, value]*.
+ * @since 5.0.0-beta.6
+ * @memberOf loop
+ * @alias functionOnEach
+ *
+ * @param {Function} fn The function to be called on every element of the input `list`.
+ * @param {*} acc The accumulator value.
+ * @param {Array} list The list to iterate over.
+ * @return {*} The final, accumulated value.
+ *
+ * @func
+ * @fork v0.10.0
+ * @category List
+ * @sig (acc -> x -> (acc, y)) -> acc -> [x] -> (acc, [y])
+ * @symb mapAccum(f, a, [b, c, d]) = [f(f(f(a, b)[0], c)[0], d)[0],
+ * [
+ * f(a, b)[1],
+ * f(f(a, b)[0], c)[1],
+ * f(f(f(a, b)[0], c)[0], d)[1]
+ * ]]
+ *
+ * @see addIndex, mapAccumRight
+ *
+ * @example
+ *
+ * var digits = ['1', '2', '3', '4'];
+ * var appender = (a, b) => [a + b, a + b];
+ *
+ * mapAccum(appender, 0, digits);
+ * //=> ['01234', ['01', '012', '0123', '01234']]
+ *
+ *
+ */
+module.exports = curry(3, function mapAccum(fn, acc, list) {
+ // nums
+ let idx = 0
+ const len = list.length
+
+ // arrs
+ const result = []
+ let tuple = [acc]
+
+ while (idx < len) {
+ tuple = fn(tuple[0], list[idx])
+ result[idx] = tuple[1]
+ idx += 1
+ }
+
+ return [tuple[0], result]
+})
diff --git a/src/deps/loop/map/mapArray.js b/src/deps/loop/map/mapArray.js
new file mode 100644
index 0000000..05867eb
--- /dev/null
+++ b/src/deps/loop/map/mapArray.js
@@ -0,0 +1,40 @@
+const size = require('../../util/size')
+const preAllocate = require('../../array/preAllocate')
+
+/**
+ * Creates an array of values by running each element of `array` thru `iteratee`.
+ * The iteratee is invoked with three arguments: (value, index, array).
+ * @memberOf loop
+ * @since 5.0.0-beta.6
+ *
+ * @name mapArray
+ * @alias mapArrayVals
+ *
+ * @param {Array} array The array to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @return {Array} Returns the new mapped array.
+ *
+ * @category Array
+ *
+ * {@link https://github.com/lodash/lodash/blob/master/map.js lodash-map}
+ * @see {@link lodash-map}
+ *
+ * @example
+ *
+ * const square = n => n * n
+ * mapArray([4, 8], square)
+ * //=> [16, 64]
+ *
+ */
+function mapArray(array, iteratee) {
+ let index = -1
+ const length = size(array)
+ const result = preAllocate(length)
+
+ while (++index < length) {
+ result[index] = iteratee(array[index], index, array)
+ }
+ return result
+}
+
+module.exports = mapArray
diff --git a/src/deps/loop/map/mapArrayKeys.js b/src/deps/loop/map/mapArrayKeys.js
new file mode 100644
index 0000000..de01d7f
--- /dev/null
+++ b/src/deps/loop/map/mapArrayKeys.js
@@ -0,0 +1,44 @@
+const ObjectKeys = require('../../util/keys')
+const toArray = require('../../cast/toArray')
+const preAllocate = require('../../array/preAllocate')
+
+/**
+ * The opposite of `mapValue` this method creates an ARRAY with the
+ * same values as `ARRAY` and keys generated by running each own enumerable
+ * string keyed property of `ARRAY` thru `iteratee`. The iteratee is invoked
+ * with three arguments: (value, key, ARRAY).
+ * @since 5.0.0-beta.6
+ * @memberOf loop
+ * @alias mapArrayIndex
+ * @alias mapArrayIndexes
+ * @alias mapIndex
+ *
+ * @param {Array} array The array to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @return {Array} Returns the new mapped ARRAY.
+ *
+ * @fork 3.8.0
+ * @category Array
+ *
+ * @see mapValue
+ *
+ * @example
+ *
+ * mapKey({ 'a': 1, 'b': 2 }, (value, key) => key + value)
+ * //=> { 'a1': 1, 'b2': 2 }
+ *
+ */
+function mapIndex(array, iteratee) {
+ // const arr = toArray(array)
+ const result = preAllocate(array)
+
+ for (let i = 0; i < array.length; i++) {
+ const key = array[i]
+ const value = array[key]
+ result[iteratee(value, key, array)] = value
+ }
+
+ return result
+}
+
+module.exports = mapIndex
diff --git a/src/deps/loop/map/mapForInUnguarded.js b/src/deps/loop/map/mapForInUnguarded.js
new file mode 100644
index 0000000..26bb8c0
--- /dev/null
+++ b/src/deps/loop/map/mapForInUnguarded.js
@@ -0,0 +1,14 @@
+/**
+ * @desc loop for in, no checks on hasOwnProperty, useful for flattening proto
+ * @since 5.0.0-beta.6
+ * @param {Array|Object|Iteratable} collection collection to iterate
+ * @param {Function} iteratee The function invoked per iteration
+ * @return {Object|Array|*} initial with results of iteratee returns
+ */
+module.exports = function forInUnguarded(collection, iteratee, initial = {}) {
+ // eslint-disable-next-line
+ for (let prop in collection) {
+ initial[prop] = collection[prop]
+ }
+ return initial
+}
diff --git a/src/deps/loop/map/mapObjKeys.js b/src/deps/loop/map/mapObjKeys.js
new file mode 100644
index 0000000..daa362a
--- /dev/null
+++ b/src/deps/loop/map/mapObjKeys.js
@@ -0,0 +1,42 @@
+const ObjectKeys = require('../../util/keys')
+const toObj = require('../../cast/toObj')
+
+/**
+ * The opposite of `mapValue` this method creates an object with the
+ * same values as `object` and keys generated by running each own enumerable
+ * string keyed property of `object` thru `iteratee`. The iteratee is invoked
+ * with three arguments: (value, key, object).
+ * @since 5.0.0-beta.6
+ * @memberOf loop
+ * @alias mapObjKeys
+ *
+ * @param {Object} object The object to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @return {Object} Returns the new mapped object.
+ *
+ * @fork 3.8.0
+ * @category Object
+ *
+ * @see mapValue
+ *
+ * @example
+ *
+ * var concatKey = (value, key) => key + value)
+ * mapKey({ 'a': 1, 'b': 2 }, concatKey)
+ * //=> { 'a1': 1, 'b2': 2 }
+ *
+ */
+function mapObjKey(object, iteratee) {
+ const obj = toObj(object)
+ const result = {}
+
+ const keys = ObjectKeys(obj)
+ for (let i = 0; i < keys.length; i++) {
+ const key = keys[i]
+ const value = obj[key]
+ result[iteratee(value, key, obj)] = value
+ }
+ return result
+}
+
+module.exports = mapObjKey
diff --git a/src/deps/loop/map/mapObjOrArray.js b/src/deps/loop/map/mapObjOrArray.js
new file mode 100644
index 0000000..e6053ab
--- /dev/null
+++ b/src/deps/loop/map/mapObjOrArray.js
@@ -0,0 +1,53 @@
+const ENV_DEBUG = require('../../env/debug')
+const isArray = require('../../is/array')
+const curry = require('../../fp/curry')
+const identity = require('../../fp/identity')
+const emptyTarget = require('../../dopemerge/emptyTarget')
+const defaultTo = require('../../cast/defaultTo')
+const objOrArrayKeys = require('../../util/keysObjOrArray')
+const size = require('../../util/size')
+
+// const always = require('../../fp/always')
+// pipe(nthArg(2), always)
+const defaultKeyTransformer = (value, key) => key
+const defaultValTransformer = identity
+
+/**
+ * @desc maps keys and vals
+ * probably needs a `mapArrayKeyVal` & `mapObjKeyVal`
+ * maybe `mapMap` haha
+ *
+ * @TODO this is huge perf killer just super easy util
+ *
+ * https://github.com/jashkenas/underscore/blob/master/underscore.js#L1021 underscore-map-obj
+ * @alias mapAny
+ * @memberOf loop
+ * @since 5.0.0-beta.6
+ */
+function mapObjOrArray(obj, onValue, onKey, init) {
+ const result = defaultTo(emptyTarget(obj), init)
+ const valTransformer = defaultTo(defaultValTransformer, onValue)
+ const keyTransformer = defaultTo(defaultKeyTransformer, onKey)
+
+ const isArrayObj = isArray(obj)
+ const keys = objOrArrayKeys(obj)
+
+ if (ENV_DEBUG) {
+ console.log('loop_mapObjOrArray', {keys, result, isArrayObj, obj, init})
+ }
+
+ for (let index = 0; index < keys.length; index++) {
+ const key = isArrayObj ? index : keys[index]
+ const value = obj[key]
+
+ if (ENV_DEBUG) {
+ console.log('loop_mapObjOrArray', {key, value, obj, index})
+ }
+
+ result[keyTransformer(value, key, obj)] = valTransformer(value, key, obj)
+ }
+
+ return result
+}
+
+module.exports = curry(2, mapObjOrArray)
diff --git a/src/deps/loop/map/mapObjOrArrayKeys.js b/src/deps/loop/map/mapObjOrArrayKeys.js
new file mode 100644
index 0000000..47c8270
--- /dev/null
+++ b/src/deps/loop/map/mapObjOrArrayKeys.js
@@ -0,0 +1,24 @@
+const isArray = require('../../is/array')
+const objOrArrayKeys = require('../../util/keysObjOrArray')
+const curry = require('../../fp/curry')
+
+/**
+ * @alias mapAnyKeys
+ * @memberOf loop
+ * @since 5.0.0-beta.6
+ */
+function mapObjOrArrayKeys(obj, iteratee, result = {}) {
+ const isArrayObj = isArray(obj)
+ const keys = objOrArrayKeys(obj)
+
+ for (let index = 0; index < keys.length; index++) {
+ const key = isArrayObj ? index : keys[index]
+ const value = obj[key]
+
+ result[iteratee(value, key, obj)] = value
+ }
+
+ return result
+}
+
+module.exports = curry(2, mapObjOrArrayKeys)
diff --git a/src/deps/loop/map/mapObjOrArrayVals.js b/src/deps/loop/map/mapObjOrArrayVals.js
new file mode 100644
index 0000000..d530c57
--- /dev/null
+++ b/src/deps/loop/map/mapObjOrArrayVals.js
@@ -0,0 +1,41 @@
+const isArray = require('../../is/array')
+const objOrArrayKeys = require('../../util/keysObjOrArray')
+const curry = require('../../fp/curry')
+
+/**
+ * Creates an array of values by running each property of `object`
+ * or index of `array` thru `iteratee`.
+ * The iteratee is invoked with three arguments: (value, key, object).
+ *
+ * @alias mapAnyVals
+ * @memberOf loop
+ * @since 5.0.0
+ * @category Object
+ *
+ * @param {Object|Array} obj The object or array to iterate over.
+ * @param {Function} predicate The function invoked per iteration.
+ * @param {Object} [result = {}] initial value, accumulated, output
+ * @return {Array|Object} Returns the new mapped array or object
+ *
+ * @example
+ *
+ * const square = n => n * n
+ * map({ 'a': 4, 'b': 8 }, square)
+ * //=> [16, 64] (iteration order is not guaranteed)
+ *
+ */
+function mapObjOrArrayVals(obj, iteratee, result = {}) {
+ const isArrayObj = isArray(obj)
+ const keys = objOrArrayKeys(obj)
+
+ for (let index = 0; index < keys.length; index++) {
+ const key = isArrayObj ? index : keys[index]
+ const value = obj[key]
+
+ result[key] = iteratee(value, key, obj)
+ }
+
+ return result
+}
+
+module.exports = curry(2, mapObjOrArrayVals)
diff --git a/src/deps/loop/map/mapObjVals.js b/src/deps/loop/map/mapObjVals.js
new file mode 100644
index 0000000..f674d0c
--- /dev/null
+++ b/src/deps/loop/map/mapObjVals.js
@@ -0,0 +1,42 @@
+const ObjectKeys = require('../../util/keys')
+const preAllocate = require('../../array/preAllocate')
+
+/**
+ * Creates an array of values by running each property of `object` thru
+ * `iteratee`. The iteratee is invoked with three arguments: (value, key, object).
+ *
+ * @name mapObjVals
+ * @since 5.0.0-beta.6
+ * @memberOf loop
+ *
+ * @param {Object} object The object to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @return {Array} Returns the new mapped array.
+ *
+ * @func
+ * @category Object
+ *
+ * {@link https://github.com/lodash/lodash/blob/master/map.js lodash-map}
+ * @see {@link lodash-map}
+ *
+ * @example
+ *
+ * const square = n => n * n
+ * map({ 'a': 4, 'b': 8 }, square)
+ * //=> [16, 64] (iteration order is not guaranteed)
+ *
+ */
+function mapObjectValues(object, iteratee) {
+ const props = ObjectKeys(object)
+ const result = new Array(props.length)
+
+ for (let index = 0; index < props.length; index++) {
+ const key = props[index]
+ const value = object[key]
+ result[index] = iteratee(value, key, object)
+ }
+
+ return result
+}
+
+module.exports = mapObjectValues
diff --git a/src/deps/loop/reduce/README.md b/src/deps/loop/reduce/README.md
new file mode 100644
index 0000000..a3d47fa
--- /dev/null
+++ b/src/deps/loop/reduce/README.md
@@ -0,0 +1,3 @@
+https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce
+
+@TODO move reduce from deps into here
diff --git a/src/deps/loop/reduce/baseReduce.js b/src/deps/loop/reduce/baseReduce.js
new file mode 100644
index 0000000..3a026f3
--- /dev/null
+++ b/src/deps/loop/reduce/baseReduce.js
@@ -0,0 +1,23 @@
+/**
+ * The base implementation of `reduce` and `reduceRight` which iterates
+ * over `collection` using `eachFunc`.
+ *
+ * @private
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @param {*} accumulator The initial value.
+ * @param {boolean} initAccum Specify using the first or last element of
+ * `collection` as the initial value.
+ * @param {Function} eachFunc The function to iterate over `collection`.
+ * @returns {*} Returns the accumulated value.
+ */
+function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) {
+ eachFunc(collection, (value, index, collection) => {
+ accumulator = initAccum
+ ? (initAccum = false, value)
+ : iteratee(accumulator, value, index, collection)
+ })
+ return accumulator
+}
+
+module.exports = baseReduce
diff --git a/src/deps/loop/reduce/index.js b/src/deps/loop/reduce/index.js
new file mode 100644
index 0000000..76137f5
--- /dev/null
+++ b/src/deps/loop/reduce/index.js
@@ -0,0 +1,3 @@
+/**
+ * @icon ⏬
+ */
diff --git a/src/deps/loop/reduce/reduceArray.js b/src/deps/loop/reduce/reduceArray.js
new file mode 100644
index 0000000..2d7d47b
--- /dev/null
+++ b/src/deps/loop/reduce/reduceArray.js
@@ -0,0 +1,27 @@
+const size = require('../../util/size')
+
+/**
+ * A specialized version of `reduce` for arrays.
+ * @since 5.0.0-beta.6
+ *
+ * @param {Array} [array] The array to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @param {*} [accumulator] The initial value.
+ * @param {boolean} [initAccum] Specify using the first element of `array` as
+ * the initial value.
+ * @return {*} Returns the accumulated value.
+ */
+function arrayReduce(array, iteratee, accumulator, initAccum) {
+ let index = -1
+ const length = size(array)
+
+ if (initAccum && length) {
+ accumulator = array[++index]
+ }
+ while (++index < length) {
+ accumulator = iteratee(accumulator, array[index], index, array)
+ }
+ return accumulator
+}
+
+module.exports = arrayReduce
diff --git a/src/deps/loop/reduce/reduceArrayRight.js b/src/deps/loop/reduce/reduceArrayRight.js
new file mode 100644
index 0000000..f93de55
--- /dev/null
+++ b/src/deps/loop/reduce/reduceArrayRight.js
@@ -0,0 +1,31 @@
+const size = require('../../util/size')
+
+/**
+ * A specialized version of `reduceRight` for arrays.
+ *
+ * @since 5.0.0-beta.7.2
+ *
+ * @param {Array} [array] The array to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @param {*} [accumulator] The initial value.
+ * @param {boolean} [initAccum] Specify using the last element of `array` as
+ * the initial value.
+ * @return {*} Returns the accumulated value.
+ */
+function arrayReduceRight(array, iteratee, accumulator, initAccum) {
+ let length = size(array)
+
+ // setup
+ if (initAccum && length) {
+ accumulator = array[--length]
+ }
+
+ // iterate backwards
+ while (length--) {
+ accumulator = iteratee(accumulator, array[length], length, array)
+ }
+
+ return accumulator
+}
+
+module.exports = arrayReduceRight
diff --git a/src/deps/loop/reduce/reduceArrayToObj.js b/src/deps/loop/reduce/reduceArrayToObj.js
new file mode 100644
index 0000000..0212eca
--- /dev/null
+++ b/src/deps/loop/reduce/reduceArrayToObj.js
@@ -0,0 +1,39 @@
+const toKey = require('../../cast/toKey')
+const isNil = require('../../is/nullOrUndefined')
+const isObj = require('../../is/obj')
+
+// @TODO ~ also see reduceMap it has keyValReducer, can do `isPairs`
+const defaultReduceArrayToObjIterator = (reduced, next, index) => {
+ if (isObj(next)) Object.assign(reduced, next)
+ else reduced[toKey(index)] = next
+
+ return reduced
+}
+
+/**
+ * @since 4.0.0
+ * @version 5.0.0 <- added index
+ *
+ * @param {Array} array array to reduce to object
+ * @param {Function} iterator function to call on reduced, with `next`
+ * @return {Object} reduced array
+ *
+ *
+ * @name reduceObj
+ * @alias reduceObject
+ * @alias toObj
+ *
+ * @see Chainable
+ *
+ * @TODO example
+ * @TODO @curried 2
+ */
+module.exports = function reduceArrayToObj(array, iterator) {
+ if (isNil(iterator)) iterator = defaultReduceArrayToObjIterator
+
+ let index = 0
+ return array.reduce(function(reduced, next) {
+ iterator(reduced, next, index)
+ return reduced
+ }, {})
+}
diff --git a/src/deps/loop/reduce/reduceMap.js b/src/deps/loop/reduce/reduceMap.js
new file mode 100644
index 0000000..e16e836
--- /dev/null
+++ b/src/deps/loop/reduce/reduceMap.js
@@ -0,0 +1,45 @@
+const ArrayFrom = require('../../util/from')
+const reduceArrayToObj = require('./reduceArrayToObj')
+
+// @TODO cask index if needed
+const keyValReducer = (acc, [key, value]) => {
+ acc[key] = value
+ return acc
+}
+
+/**
+ * @desc Map -> Object
+ * @since 4.0.0
+ * @version 5.0.0 <- moved from /reduce to loop/reduce
+ *
+ * @param {Map} map map to reduce, calls entries, turns into an array, then object
+ * @return {Object} reduced object
+ *
+ * @see ArrayFrom
+ *
+ * @example
+ *
+ * var emptyMap = new Map()
+ * reduce(emptyMap)
+ * //=> {}
+ *
+ * @example
+ *
+ * var map = new Map()
+ * map.set('eh', 1)
+ * reduce(map)
+ * //=> {eh: 1}
+ *
+ */
+module.exports = map => {
+ // only need to do this if we actually have values in our Map
+ if (map.size === 0) {
+ return {}
+ }
+ else {
+ return reduceArrayToObj(
+ ArrayFrom(map.entries()),
+ keyValReducer
+ )
+ }
+}
diff --git a/src/deps/loop/reduce/reduceMapRecursive.js b/src/deps/loop/reduce/reduceMapRecursive.js
new file mode 100644
index 0000000..e163010
--- /dev/null
+++ b/src/deps/loop/reduce/reduceMapRecursive.js
@@ -0,0 +1,90 @@
+const hasIn = require('../../is/in')
+const ignored = require('../../meta/ignored')
+const ObjectKeys = require('../../util/keys')
+const ObjectAssign = require('../../util/assign')
+
+/**
+ * @desc recursively reduce maps and objects that include reducable data
+ * @since 4.0.0
+ * @version 5.0.0 <- moved from /reduce to loop/reduce
+ *
+ * @param {Object | any} reduced merged object and reduced
+ * @return {Function} Function(values: Object)
+ *
+ * @sig reduced => object => isMap(object) -> reduced; merge(object, reduced)
+ *
+ * @see https://www.airpair.com/javascript/javascript-array-reduce
+ * @see ChainedMap
+ * @NOTE could curry, but this is super hot function
+ *
+ * @example
+ *
+ * const map = new Map()
+ * map.set('eh', true)
+ * const nested = new Map()
+ * nested.set('reduced', true)
+ *
+ * const chain = {
+ * entries() {
+ * return {
+ * nested: reduce(nested),
+ * key: true,
+ * }
+ * },
+ * }
+ * const reduced = reduce(map)
+ * reduceEntries(reduced)({chain})
+ * //=> {
+ * eh: true,
+ * chain: {
+ * nested: {
+ * reduced: true,
+ * key: true,
+ * },
+ * },
+ * }
+ *
+ * @example
+ *
+ * const reducedIgnored = {
+ * canada: {
+ * store: chain,
+ * },
+ * }
+ * const ignored = reduceEntries(reduced)(reducedIgnored)
+ * //=> {
+ * eh: true,
+ * chain: {
+ * nested: {
+ * reduced: true,
+ * },
+ * key: true,
+ * },
+ * }
+ *
+ */
+module.exports = reduced => obj => {
+ const keys = ObjectKeys(obj)
+
+ // const filter = (value, key) =>
+ // !ignored(key) && hasIn(value, 'entries')
+ // const transform = (value, key) =>
+ // ObjectAssign(reduced, {[key]: value.entries(true) || {}})
+ // mapFilterWhere(obj, filter, transform)
+
+ for (let k = 0; k < keys.length; k++) {
+ const key = keys[k]
+
+ if (ignored(key)) {
+ continue
+ }
+
+ const value = obj[key]
+
+ if (hasIn(value, 'entries')) {
+ ObjectAssign(reduced, {[key]: value.entries(true) || {}})
+ }
+ }
+
+ return reduced
+}
diff --git a/src/deps/loop/sort/README.md b/src/deps/loop/sort/README.md
new file mode 100644
index 0000000..c192dc2
--- /dev/null
+++ b/src/deps/loop/sort/README.md
@@ -0,0 +1,6 @@
+https://www.npmjs.com/package/sort-by
+https://www.npmjs.com/package/lodash.sortby
+https://github.com/lodash/lodash/tree/4.7.0-npm-packages/lodash.sortby
+http://janetriley.net/2014/12/sort-on-multiple-keys-with-underscores-sortby.html
+
+@icon 🔢
diff --git a/src/deps/loop/sort/comparator.js b/src/deps/loop/sort/comparator.js
new file mode 100644
index 0000000..0a768f3
--- /dev/null
+++ b/src/deps/loop/sort/comparator.js
@@ -0,0 +1,29 @@
+/**
+ * Makes a comparator function out of a function that reports whether the first
+ * element is less than the second.
+ *
+ * @since 5.0.0-beta.5
+ * @memberOf sort
+ *
+ * @param {Function} predicate A predicate function of arity two which will return `true` if the first argument
+ * is less than the second, `false` otherwise
+ * @return {Function} A Function :: a -> b -> Int that returns `-1` if a < b, `1` if b < a, otherwise `0`
+ *
+ * @func
+ * @fork v0.1.0
+ * @category Function
+ * @sig (a, b -> Boolean) -> (a, b -> Number)
+ *
+ * @example
+ *
+ * var byAge = R.comparator((a, b) => a.age < b.age);
+ * var people = [
+ * // ...
+ * ];
+ * var peopleByIncreasingAge = R.sort(byAge, people);
+ */
+module.exports = function comparator(predicate) {
+ return function(a, b) {
+ return predicate(a, b) ? -1 : predicate(b, a) ? 1 : 0
+ }
+}
diff --git a/src/deps/loop/sort/defaultComparator.js b/src/deps/loop/sort/defaultComparator.js
new file mode 100644
index 0000000..ebe5c20
--- /dev/null
+++ b/src/deps/loop/sort/defaultComparator.js
@@ -0,0 +1,57 @@
+const isUndefined = require('../../is/undefined')
+
+/**
+ * @since 5.0.0-beta.6
+ * @name defaultComparator
+ * @alias defaultComparer
+ * @memberOf sort
+ * @memberOf loop
+ *
+ * {@link https://github.com/facebook/immutable-js/blob/master/src/Operations.js#L875 immutable-default-comparator}
+ * {@link https://github.com/mobxjs/mobx/blob/master/src/types/comparer.ts mobx-default-comparer}
+ * @see {@link mobx-default-comparer}
+ * @see {@link immutable-default-comparator}
+ *
+ * @param {number | undefined} a compare to b
+ * @param {number | undefined} b compare to a
+ * @return {number} 0 | 1 | -1
+ *
+ * @example
+ *
+ * /// a > b
+ * defaultComparator(1, 2)
+ * //=> 1
+ *
+ * @example
+ *
+ * /// a < b
+ * defaultComparator(2, 1)
+ * //=> -1
+ *
+ * @example
+ *
+ * /// a == b
+ * defaultComparator(1, 1)
+ * //=> 0
+ *
+ * @example
+ *
+ * defaultComparator(undefined, undefined) //=> 0
+ * defaultComparator(undefined, 1) //=> 1
+ * defaultComparator(1, undefined) //=> -1
+ *
+ */
+module.exports = function defaultComparator(a, b) {
+ if (isUndefined(a) && isUndefined(b)) {
+ return 0
+ }
+ else if (isUndefined(a)) {
+ return 1
+ }
+ else if (isUndefined(b)) {
+ return -1
+ }
+ else {
+ return a > b ? 1 : a < b ? -1 : 0
+ }
+}
diff --git a/src/deps/loop/sort/sort.js b/src/deps/loop/sort/sort.js
new file mode 100644
index 0000000..6c69e66
--- /dev/null
+++ b/src/deps/loop/sort/sort.js
@@ -0,0 +1,30 @@
+const slice = require('../../native/arraySlice')
+const curry = require('../../fp/curry')
+
+/**
+ * Returns a copy of the list, sorted according to the comparator function,
+ * which should accept two values at a time and return a negative number if the
+ * first value is smaller, a positive number if it's larger, and zero if they
+ * are equal. Please note that this is a **copy** of the list. It does not
+ * modify the original.
+ * @since 5.0.0-beta.5
+ * @memberOf loop
+ *
+ * @param {Function} comparator A sorting function :: a -> b -> Int
+ * @param {Array} list The list to sort
+ * @return {Array} a new array with its elements sorted by the comparator function.
+ *
+ * @func
+ * @fork v0.1.0
+ * @category List
+ * @sig (a,a -> Number) -> [a] -> [a]
+ *
+ * @example
+ *
+ * var diff = function(a, b) { return a - b; }
+ * sort(diff, [4,2,7,5]); //=> [2, 4, 5, 7]
+ *
+ */
+module.exports = curry(2, function sort(comparator, list) {
+ return slice.call(list, 0).sort(comparator)
+})
diff --git a/src/deps/loop/sort/sortBy.js b/src/deps/loop/sort/sortBy.js
new file mode 100644
index 0000000..664a721
--- /dev/null
+++ b/src/deps/loop/sort/sortBy.js
@@ -0,0 +1,66 @@
+// https://github.com/jashkenas/underscore/blob/master/underscore.js#L410
+// https://github.com/lodash/lodash/blob/4.7.0-npm-packages/lodash.sortby/index.js#L2079
+const isArrayLike = require('../../is/array')
+const isUndefined = require('../../is/undefined')
+const ObjectKeys = require('../../util/keys')
+
+// External wrapper for our callback generator. Users may customize
+// `_.iteratee` if they want additional predicate/iteratee shorthand styles.
+// This abstraction hides the internal-only argCount argument.
+
+// var builtinIteratee = function(value, context) {
+// return cb(value, context, Infinity)
+// }
+// var iteratee = builtinIteratee
+
+// An internal function to generate callbacks that can be applied to each
+// element in a collection, returning the desired result — either `identity`,
+// an arbitrary callback, a property matcher, or a property accessor.
+// var cb = function(value, context, argCount) {
+// if (iteratee !== builtinIteratee) return iteratee(value, context)
+// // if (value == null) return _.identity
+// // if (_.isFunction(value)) return optimizeCb(value, context, argCount)
+// // if (_.isObject(value) && !_.isArray(value)) return _.matcher(value)
+// // return _.property(value)
+// }
+
+// _.map = _.collect
+// Return the results of applying the iteratee to each element.
+const map = function(obj, iteratee, context) {
+ // iteratee = cb(iteratee, context)
+
+ const keys = !isArrayLike(obj) && ObjectKeys(obj)
+ const length = (keys || obj).length
+ const results = Array(length)
+
+ for (var index = 0; index < length; index++) {
+ var currentKey = keys ? keys[index] : index
+ results[index] = iteratee(obj[currentKey], currentKey, obj)
+ }
+ return results
+}
+
+const sortBy = function(obj, iteratee, context) {
+ var index = 0
+
+ const mapper = function(value, key, list) {
+ return {
+ value,
+ index: index++,
+ criteria: iteratee(value, key, list),
+ }
+ }
+ const sorter = function(left, right) {
+ var a = left.criteria
+ var b = right.criteria
+ if (a !== b) {
+ if (a > b || isUndefined(a)) return 1
+ if (a < b || isUndefined(b)) return -1
+ }
+ return left.index - right.index
+ }
+
+ // iteratee = cb(iteratee, context)
+ // _.pluck(returned, 'value')
+ return map(obj, mapper).sort(sorter)
+}
diff --git a/src/deps/loop/sort/sortByR.js b/src/deps/loop/sort/sortByR.js
new file mode 100644
index 0000000..c6c0f0e
--- /dev/null
+++ b/src/deps/loop/sort/sortByR.js
@@ -0,0 +1,47 @@
+const curry = require('../../fp/curry')
+const slice = require('../../native/arraySlice')
+
+/**
+ * Sorts the list according to the supplied function.
+ * @since 5.0.0-beta.1
+ * @memberOf sort
+ *
+ * @param {Function} fn
+ * @param {Array} list The list to sort.
+ * @return {Array} A new list sorted by the keys generated by `fn`.
+ *
+ * @func
+ * @fork v0.1.0
+ * @category Relation
+ * @sig Ord b => (a -> b) -> [a] -> [a]
+ *
+ * @example
+ *
+ * var sortByFirstItem = R.sortBy(R.prop(0));
+ * var sortByNameCaseInsensitive = R.sortBy(R.compose(R.toLower, R.prop('name')));
+ * var pairs = [[-1, 1], [-2, 2], [-3, 3]];
+ * sortByFirstItem(pairs); //=> [[-3, 3], [-2, 2], [-1, 1]]
+ * var alice = {
+ * name: 'ALICE',
+ * age: 101
+ * };
+ * var bob = {
+ * name: 'Bob',
+ * age: -10
+ * };
+ * var clara = {
+ * name: 'clara',
+ * age: 314.159
+ * };
+ * var people = [clara, bob, alice];
+ * sortByNameCaseInsensitive(people);
+ * //=> [alice, bob, clara]
+ *
+ */
+module.exports = curry(2, function sortBy(fn, list) {
+ return slice.call(list, 0).sort(function(a, b) {
+ var aa = fn(a)
+ var bb = fn(b)
+ return aa < bb ? -1 : aa > bb ? 1 : 0
+ })
+})
diff --git a/src/deps/loop/sort/sortWith.js b/src/deps/loop/sort/sortWith.js
new file mode 100644
index 0000000..3228843
--- /dev/null
+++ b/src/deps/loop/sort/sortWith.js
@@ -0,0 +1,50 @@
+const curry = require('../../fp/curry')
+const slice = require('../../native/arraySlice')
+
+/**
+ * Sorts a list according to a list of comparators.
+ *
+ * @since 5.0.0-beta.5
+ * @memberOf sort
+ *
+ * @param {Array} functions A list of comparator functions.
+ * @param {Array} list The list to sort.
+ * @return {Array} A new list sorted according to the comarator functions.
+ *
+ * @func
+ * @fork v0.23.0
+ * @category Relation
+ * @sig [a -> a -> Number] -> [a] -> [a]
+ *
+ * @example
+ *
+ * var alice = {
+ * name: 'alice',
+ * age: 40
+ * };
+ * var bob = {
+ * name: 'bob',
+ * age: 30
+ * };
+ * var clara = {
+ * name: 'clara',
+ * age: 40
+ * };
+ * var people = [clara, bob, alice];
+ * var ageNameSort = R.sortWith([
+ * R.descend(R.prop('age')),
+ * R.ascend(R.prop('name'))
+ * ]);
+ * ageNameSort(people); //=> [alice, clara, bob]
+ */
+module.exports = curry(2, function sortWith(fns, list) {
+ return slice.call(list, 0).sort(function(a, b) {
+ var result = 0
+ var i = 0
+ while (result === 0 && i < fns.length) {
+ result = fns[i](a, b)
+ i += 1
+ }
+ return result
+ })
+})
diff --git a/src/deps/matcher/escape-string-regex.js b/src/deps/matcher/escape-string-regex.js
deleted file mode 100644
index 5e8f9fc..0000000
--- a/src/deps/matcher/escape-string-regex.js
+++ /dev/null
@@ -1,22 +0,0 @@
-/**
- * @func escapeStringRegExp
- * @module escape-string-regexp
- * @memberOf matcher
- * @since 3.0.0
- *
- * @param {string} str string to escape
- * @return {string} escaped string
- *
- * {@link https://github.com/sindresorhus/escape-string-regexp escape-string-regexp}
- * @see {@link escape-string-regexp *} 🍴
- *
- * @NOTE also as const escapeStringRegexp = require('escape-string-regexp');
- *
- * @example
- *
- * const escaped = escapeStringRegexp('how much $ for a unicorn?');
- * //=> 'how much \$ for a unicorn\?'
- * new RegExp(escaped);
- *
- */
-module.exports = str => str.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&')
diff --git a/src/deps/matcher/matcher.js b/src/deps/matcher/matcher.js
index ca27ce9..e5937cb 100644
--- a/src/deps/matcher/matcher.js
+++ b/src/deps/matcher/matcher.js
@@ -6,11 +6,18 @@
* @types matcher
* @tests deps/matcher
*/
+
const ObjectAssign = require('../util/assign')
const isMatcher = require('../is/matcher')
const cache = require('../cache')
const toarr = require('../to-arr')
-const toRegExp = require('./to-regexp')
+const newRegExp = require('../construct/regexp')
+const pipe = require('../fp/pipeTwo')
+const toEscapedRegExp = require('../cast/toRegExp')
+const replaceEscapedStar = require('../string/escapedToDotStar')
+const escapeStringRegExp = require('../string/escapeRegExp')
+
+const esc = pipe(escapeStringRegExp, replaceEscapedStar)
const m = {}
@@ -40,25 +47,25 @@ const m = {}
*
* var strings = x => typeof x === 'string'
* matcher.make(strings)
- * // {test: strings}
+ * //=> {test: strings}
*
* @example
*
* var tester = {test: x => x === true}
* matcher.make(tester)
- * // tester
+ * //=> tester
*
* @example
*
* var noName = '!name'
* matcher.make(noName, true)
- * // new RegExp('(?:name)', 'i')
+ * //=> new RegExp('(?:name)', 'i')
*
* @example
*
* var noName = '!name'
* matcher.make(noName, true, true)
- * // new RegExp('^(?:name)$', 'i')
+ * //=> new RegExp('^(?:name)$', 'i')
*
*/
m.make = (pattern, shouldNegate, alphaOmega) => {
@@ -74,12 +81,13 @@ m.make = (pattern, shouldNegate, alphaOmega) => {
// }
let negated = matchable[0] === '!'
if (negated) matchable = matchable.slice(1)
- matchable = toRegExp(matchable)
+
+ matchable = esc(matchable)
if (negated && shouldNegate) matchable = `(?!${matchable})`
if (alphaOmega) matchable = `^${matchable}$`
- matchable = new RegExp(`${matchable}`, 'i')
+ matchable = newRegExp(`${matchable}`, 'i')
matchable.negated = negated
cache.set(pattern, matchable)
diff --git a/src/deps/matcher/test.js b/src/deps/matcher/test.js
new file mode 100644
index 0000000..3a17cb1
--- /dev/null
+++ b/src/deps/matcher/test.js
@@ -0,0 +1,33 @@
+const curry = require('../fp/curry')
+
+/**
+ * Determines whether a given string matches a given regular expression.
+ * @memberOf matcher
+ * @since 5.0.0-beta.5
+ *
+ * @curried 2
+ * `const toTest = x => y => x.test(y)`
+ *
+ * @param {RegExp|Matchable} pattern call .test on this
+ * @param {string} x value to test with pattern
+ * @return {boolean} test result
+ *
+ * @func
+ * @fork v0.12.0
+ * @category String
+ * @sig RegExp -> String -> Boolean
+ *
+ * {@link https://github.com/ramda/ramda/blob/v0.24.1/src/test.js ramda-test}
+ * @see {@link ramda-test}
+ *
+ * @example
+ *
+ * test(/^x/, 'xyz') //=> true
+ * test(/^y/, 'xyz') //=> false
+ *
+ */
+function test(pattern, x) {
+ return pattern.test(x)
+}
+
+module.exports = curry(2, test)
diff --git a/src/deps/matcher/any-key-val.js b/src/deps/matcher/testKeysVals.js
similarity index 94%
rename from src/deps/matcher/any-key-val.js
rename to src/deps/matcher/testKeysVals.js
index dd15c5f..25d978b 100644
--- a/src/deps/matcher/any-key-val.js
+++ b/src/deps/matcher/testKeysVals.js
@@ -1,4 +1,4 @@
-const tester = require('./to-test')
+const tester = require('../cast/toTestable')
/**
* the original simple to-test matcher for traversable,
diff --git a/src/deps/matcher/to-regexp.js b/src/deps/matcher/to-regexp.js
deleted file mode 100644
index 986c45c..0000000
--- a/src/deps/matcher/to-regexp.js
+++ /dev/null
@@ -1,21 +0,0 @@
-const escapeStringRegExp = require('./escape-string-regex')
-
-/**
- * @func toRegExp
- * @memberOf matcher
- * @module to-regexp
- * @extends escapeStringRegExp
- *
- * @param {string} str string to escape
- * @return {string} escaped str
- *
- * @example
- *
- * toRegExp('*')
- * => '.*'
- *
- * toRegExp('eh')
- * => 'eh'
- *
- */
-module.exports = str => escapeStringRegExp(str).replace(/\\\*/g, '.*')
diff --git a/src/deps/matcher/to-test.js b/src/deps/matcher/to-test.js
deleted file mode 100644
index adc951a..0000000
--- a/src/deps/matcher/to-test.js
+++ /dev/null
@@ -1,45 +0,0 @@
-const isString = require('../is/string')
-const isFunction = require('../is/function')
-const esc = require('./escape-string-regex')
-
-/**
- * @desc like matcher, but .isMatch
- * @since 3.0.0
- *
- * @param {Matchable} matchable any matchable
- * @param {any} [arg1=undefined] arg to match with
- * @param {any} [arg2=undefined] optional second arg to pass into tester
- * @return {boolean} is a match, passes the test
- *
- * @NOTE as else-if for easier ternary uglification
- *
- * @example
- *
- * matcher('kinga', 'kinga')
- * //=> true
- * matcher('k*nga', 'kinga')
- * //=> true
- * matcher('kinga', 'nope')
- * //=> false
- *
- * matcher(new RegExp(/kinga/), 'kinga')
- * //=> true
- * matcher(new RegExp(/kinga/), 'nope')
- * //=> false
- *
- * matcher(x => x === 'kinga', 'kinga')
- * //=> true
- * matcher(x => x === 'kinga', 'nope')
- * //=> false
- *
- * matcher({test: x => x === 'kinga'}, 'kinga')
- * //=> true
- * matcher({test: x => x === 'kinga'}, 'nope')
- * //=> false
- *
- */
-module.exports = (matchable, arg1, arg2) => {
- if (isString(matchable)) return !!new RegExp(esc(matchable)).test(arg1)
- else if (isFunction(matchable) && !matchable.test) return !!matchable(arg1)
- else return !!matchable.test(arg1, arg2)
-}
diff --git a/src/deps/math/README.md b/src/deps/math/README.md
new file mode 100644
index 0000000..d7f975d
--- /dev/null
+++ b/src/deps/math/README.md
@@ -0,0 +1,22 @@
+http://documentcloud.github.io/underscore-contrib/#util.existential
+
+basic math expressions,
+above,
+below,
+between,
+even,
+odd,
+multiply,
+increment,
+decrement,
+subtract,
+add,
+sum
+
+gte
+lte
+
+ascending
+descending
+
+https://github.com/processing-js/processing-js/blob/master/src/P5Functions/Math.js
diff --git a/src/deps/math/above.js b/src/deps/math/above.js
new file mode 100644
index 0000000..19ae4d0
--- /dev/null
+++ b/src/deps/math/above.js
@@ -0,0 +1,25 @@
+const curry = require('../fp/curry')
+
+/**
+ * @memberOf math
+ * @since 5.0.0-beta.4
+ * @alias gt
+ * @alias isGreaterThan
+ * @alias greaterThan
+ *
+ * @param {number} aboveThis x is `aboveThis`
+ * @param {number} x is above `abovethis`
+ * @return {boolean} x > aboveThis
+ *
+ * @category Math
+ *
+ * @example
+ * isAbove(0, 1) //=> true
+ * isAbove(1, 1) //=> false
+ * isAbove(1, 0) //=> false
+ */
+function isAbove(aboveThis, x) {
+ return x > aboveThis
+}
+
+module.exports = curry(2, isAbove)
diff --git a/src/deps/math/aboveOrEq.js b/src/deps/math/aboveOrEq.js
new file mode 100644
index 0000000..25b624a
--- /dev/null
+++ b/src/deps/math/aboveOrEq.js
@@ -0,0 +1,32 @@
+const curry = require('../fp/curry')
+
+/**
+ * @memberOf math
+ * @since 5.0.0-beta.7
+ * @name isAboveOrEq
+ * @alias gte
+ * @alias aboveOrEq
+ * @alias greaterThanOrEq
+ * @alias isAboveOrEqual
+ * @alias isAboveOrEqualTo
+ * @alias isAboveOrEqTo
+ * @alias isGreaterOrEqTo
+ * @alias isGreaterThanOrEq
+ * @alias isGreaterThanOrEqTo
+ *
+ * @param {number} aboveThis x is `aboveThis` or equalTo
+ * @param {number} x is above `abovethis`
+ * @return {boolean} x >= aboveThis
+ *
+ * @category Math
+ *
+ * @example
+ * isAboveOrEq(0, 1) //=> true
+ * isAboveOrEq(1, 1) //=> true
+ * isAboveOrEq(1, 0) //=> false
+ */
+const isAboveOrEq = function(aboveThis, x) {
+ return x >= aboveThis
+}
+
+module.exports = curry(2, isAboveOrEq)
diff --git a/src/deps/math/add.js b/src/deps/math/add.js
new file mode 100644
index 0000000..7d35614
--- /dev/null
+++ b/src/deps/math/add.js
@@ -0,0 +1,18 @@
+const curry = require('../fp/curry')
+
+/**
+ * @memberOf math
+ * @since 5.0.0-beta.4
+ *
+ * @name add
+ * @curried 2
+ * @category Math
+ *
+ * @param {number} target number to add TO
+ * @param {number} x number to ADD
+ * @return {number} target + x
+ *
+ * @example
+ * add(2, 2) //=> 4
+ */
+module.exports = curry(2, (target, x) => target + x)
diff --git a/src/deps/math/below.js b/src/deps/math/below.js
new file mode 100644
index 0000000..c99aef1
--- /dev/null
+++ b/src/deps/math/below.js
@@ -0,0 +1,27 @@
+const curry = require('../fp/curry')
+
+/**
+ * @memberOf math
+ * @since 5.0.0-beta.4
+ *
+ * @name isBelow
+ * @alias lt
+ * @alias below
+ * @alias isLessThan
+ * @alias lessThan
+ *
+ * @param {number} belowThis x is `belowThis`
+ * @param {number} x is < `belowThis`
+ * @return {boolean} x < belowThis
+ *
+ * @category Math
+ *
+ * @example
+ * isBelow(0, 1) //=> false
+ * isBelow(1, 0) //=> true
+ */
+function isBelow(belowThis, x) {
+ return x < belowThis
+}
+
+module.exports = curry(2, isBelow)
diff --git a/src/deps/math/belowOrEq.js b/src/deps/math/belowOrEq.js
new file mode 100644
index 0000000..b82b149
--- /dev/null
+++ b/src/deps/math/belowOrEq.js
@@ -0,0 +1,30 @@
+const curry = require('../fp/curry')
+
+/**
+ * @memberOf math
+ * @since 5.0.0-beta.7
+ * @name isBelowOrEq
+ * @alias lte
+ * @alias isBelowOrEqualTo
+ * @alias belowOrEq
+ * @alias isBelowOrEq
+ * @alias isLessThanOrEqTo
+ * @alias isLessThan
+ * @alias lessThan
+ *
+ * @param {number} belowThis x is `belowThis` or equalTo
+ * @param {number} x is lessThan `belowThis` or equalTo
+ * @return {boolean} x <= belowThis
+ *
+ * @category Math
+ *
+ * @example
+ * isBelowOrEq(1, 0) //=> true
+ * isBelowOrEq(1, 1) //=> true
+ * isBelowOrEq(0, 1) //=> false
+ */
+const isBelowOrEq = function(belowThis, x) {
+ return x >= belowThis
+}
+
+module.exports = curry(2, isBelowOrEq)
diff --git a/src/deps/math/between.js b/src/deps/math/between.js
new file mode 100644
index 0000000..9528a6f
--- /dev/null
+++ b/src/deps/math/between.js
@@ -0,0 +1,23 @@
+const curry = require('../fp/curry')
+
+/**
+ * @alias isBetween
+ *
+ * @param {number} x number between
+ * @param {number} min minimum
+ * @param {number} max maximum
+ * @param {boolean} greaterThanOrEqualTo strictly between, not equal to (left right)
+ * @return {boolean} x >= min && x <= max
+ *
+ * @category Math
+ *
+ * @example
+ * between(100, 0, 200) //=> true
+ * between(100, 100, 100) //=> true
+ * between(100, 10, 99) //=> false
+ */
+function between(x, min, max, greaterThanOrEqualTo = true) {
+ return x >= min && x <= max
+}
+
+module.exports = curry(3, between)
diff --git a/src/deps/math/bitwiseMathOperator.js b/src/deps/math/bitwiseMathOperator.js
new file mode 100644
index 0000000..b712777
--- /dev/null
+++ b/src/deps/math/bitwiseMathOperator.js
@@ -0,0 +1,7 @@
+// https://github.com/aretecode/collection-pipeline/blob/master/src/AbstractExpressionBuilder.php
+// from expression evaluator in php collection
+// module.exports = function bitwiseMathOperator(x, y) {
+// if (x === 1) {
+// return x > y
+// }
+// }
diff --git a/src/deps/math/decrement.js b/src/deps/math/decrement.js
new file mode 100644
index 0000000..e51a3cf
--- /dev/null
+++ b/src/deps/math/decrement.js
@@ -0,0 +1,16 @@
+/**
+ * @since 5.0.0-beta.4
+ * @memberOf math
+ * @name decrement
+ * @alias dec
+ * @alias minusOne
+ * @category Math
+ *
+ * @param {number} x number to decrement
+ * @return {number} x - 1
+ *
+ * @example
+ * decrement(2) //=> 1
+ */
+// module.exports = subtract(1)
+module.exports = x => x - 1
diff --git a/src/deps/math/even.js b/src/deps/math/even.js
new file mode 100644
index 0000000..dc799c3
--- /dev/null
+++ b/src/deps/math/even.js
@@ -0,0 +1,24 @@
+const not = require('../conditional/not')
+const isEven = require('./even')
+
+/**
+ * @desc isEven
+ * @param {number | any} x value to check
+ * @return {boolean} isEven
+ *
+ * @extends isOdd
+ * @variations inverse
+ *
+ * @example
+ *
+ * isEven(1)
+ * //=> false
+ * isEven(2)
+ * //=> true
+ *
+ * var rando = Math.floor(Math.random(0, 10000))
+ * isEven(rando) !== isOdd(rando)
+ * //=> true
+ *
+ */
+module.exports = not(isEven)
diff --git a/src/deps/math/increment.js b/src/deps/math/increment.js
new file mode 100644
index 0000000..49fc8f4
--- /dev/null
+++ b/src/deps/math/increment.js
@@ -0,0 +1,21 @@
+/**
+ * increment, decrement, sum, subtract, add, multiply...
+ * these should just stay external
+ * there was something with the bitwise operator experiment
+ * only to use this alongside the conditional for an insane sized evaluator
+ *
+ * @since 5.0.0-beta.4
+ * @name increment
+ * @memberOf math
+ *
+ * @alias inc
+ * @alias plusOne
+ *
+ * @param {number} x number to increment
+ * @return {number} x + 1
+ *
+ * @example
+ * increment(2) //=> 1
+ */
+// module.exports = add(1)
+module.exports = x => x + 1
diff --git a/src/deps/math/index.js b/src/deps/math/index.js
new file mode 100644
index 0000000..3099fad
--- /dev/null
+++ b/src/deps/math/index.js
@@ -0,0 +1,3 @@
+/* istanbul ignore next */
+
+module.exports = require('./math')
diff --git a/src/deps/math/math.js b/src/deps/math/math.js
new file mode 100644
index 0000000..a7d76b3
--- /dev/null
+++ b/src/deps/math/math.js
@@ -0,0 +1,67 @@
+const above = require('./above')
+const below = require('./below')
+const aboveOrEq = require('./aboveOrEq')
+const belowOrEq = require('./belowOrEq')
+const between = require('./between')
+const even = require('./even')
+const odd = require('./odd')
+const add = require('./add')
+const increment = require('./increment')
+const decrement = require('./decrement')
+const min = require('./min')
+const max = require('./max')
+const range = require('./range')
+const multiplySigned = require('./multiplySigned')
+const modulo = require('./modulo')
+const subtract = require('./subtract')
+const sum = require('./sum')
+
+const gt = above
+const lt = below
+const gte = aboveOrEq
+const lte = belowOrEq
+const isEven = even
+const isOdd = odd
+const sub = subtract
+const inc = increment
+const dec = decrement
+
+/**
+ * @icon ➗
+ * @member math
+ * @type {Object}
+ */
+module.exports = {
+ // lt, gt,
+ above,
+ below,
+ belowOrEq,
+ aboveOrEq,
+ between,
+ // even odd etc
+ isEven,
+ isOdd,
+ odd,
+ even,
+ // ops
+ subtract,
+ add,
+ increment,
+ decrement,
+ modulo,
+ // calculate
+ max,
+ min,
+ // create
+ range,
+ sum,
+ multiplySigned,
+ // @TODO alias these
+ sub,
+ inc,
+ dec,
+ gt,
+ lt,
+ gte,
+ lte,
+}
diff --git a/src/deps/math/max.js b/src/deps/math/max.js
new file mode 100644
index 0000000..c2efe95
--- /dev/null
+++ b/src/deps/math/max.js
@@ -0,0 +1,35 @@
+const curry = require('../fp/curry')
+
+/**
+ * Returns the larger of its two arguments.
+ * @since 5.0.0-beta.6
+ * @name max
+ * @alias biggest
+ * @memberOf math
+ *
+ * @param {number|*} a
+ * @param {number|*} b
+ * @return {number|*} if (b > a) b; else b
+ *
+ * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/max mozilla-math.max}
+ * @see {@link mozilla-math.max}
+ *
+ * @TODO add maxAll for `reduce(max)`
+ *
+ * @func
+ * @fork v0.1.0
+ * @category Relation
+ * @sig Ord a => a -> a -> a
+ *
+ * @see maxBy, min
+ * @see math/min
+ *
+ * @example
+ *
+ * max(789, 123); //=> 789
+ * max('a', 'b'); //=> 'b'
+ *
+ */
+module.exports = curry(2, function max(a, b) {
+ return b > a ? b : a
+})
diff --git a/src/deps/math/min.js b/src/deps/math/min.js
new file mode 100644
index 0000000..706de48
--- /dev/null
+++ b/src/deps/math/min.js
@@ -0,0 +1,32 @@
+const flip2 = require('../fp/flip2')
+const max = require('./max')
+
+/**
+ * Returns the *smallest* of its two arguments.
+ * @since 5.0.0-beta.6
+ * @name min
+ * @alias smallest
+ * @memberOf math
+ *
+ * @param {number|*} a
+ * @param {number|*} b
+ * @return {number|*} if (b < a) b; else a
+ *
+ * @func
+ * @fork v0.1.0
+ * @category Relation
+ * @sig Ord a => a -> a -> a
+ *
+ * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/max mozilla-math.min}
+ * @see {@link mozilla-math.min}
+ *
+ * @see maxBy, min
+ * @see math/min
+ *
+ * @example
+ *
+ * min(789, 123); //=> 789
+ * min('a', 'b'); //=> 'b'
+ *
+ */
+module.exports = flip2(max)
diff --git a/src/deps/math/modulo.js b/src/deps/math/modulo.js
new file mode 100644
index 0000000..0dcb112
--- /dev/null
+++ b/src/deps/math/modulo.js
@@ -0,0 +1,26 @@
+const curry = require('../fp/curry')
+
+/**
+ * @desc a % b
+ * @memberOf math
+ * @since 5.0.0-beta.7
+ * @curried 2
+ *
+ * @param {number} a a - (b [...])
+ * @param {number} b [...] (Math.floor(a / b) * b)
+ * @return {number} a % b
+ *
+ * {@link https://tc39.github.io/ecma262/#eqn-modulo emca-modulo}
+ * {@link http://2ality.com/2012/02/js-integers.html 2ality-integers}
+ * @see {@link 2ality-integers}
+ * @see {@link emca-modulo}
+ *
+ * @example
+ * 1 % 200 //=> 1
+ */
+const modulo = function(a, b) {
+ return a % b
+ // return a - (Math.floor(a / b) * b)
+}
+
+module.exports = curry(2, modulo)
diff --git a/src/deps/math/multiplySigned.js b/src/deps/math/multiplySigned.js
new file mode 100644
index 0000000..87aa130
--- /dev/null
+++ b/src/deps/math/multiplySigned.js
@@ -0,0 +1,33 @@
+/**
+ * @name multiplySigned
+ * @alias imul
+ *
+ * @desc multiply signed integers
+ * @see math/signed
+ *
+ * @see https://stackoverflow.com/questions/21052816/why-would-i-use-math-imul
+ * @see https://github.com/facebook/immutable-js/blob/master/src/Math.js#L10
+ * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/imul
+ */
+module.exports = Math.imul
+
+// @TODO polyfil
+// typeof Math.imul === 'function' &&
+// Math.imul(0xffffffff, 2) === -2
+// ? Math.imul
+// :
+// /**
+// * @param {number} a
+// * @param {number} b
+// * @return {int}
+// *
+// */
+// function imul(a, b) {
+// a |= 0 // int
+// b |= 0 // int
+// const c = a & 0xffff
+// const d = b & 0xffff
+// // Shift by 0 fixes the sign on the high part.
+// // eslint-disable-next-line
+// return c * d + ((a >>> 16) * d + c * (b >>> 16) << 16 >>> 0) | 0
+// }
diff --git a/src/deps/math/odd.js b/src/deps/math/odd.js
new file mode 100644
index 0000000..cb12fba
--- /dev/null
+++ b/src/deps/math/odd.js
@@ -0,0 +1,27 @@
+const isNumber = require('../is/number')
+
+/* prettier-ignore */
+/**
+ * @desc isOdd
+ * @memberOf math
+ * @since 5.0.0-beta.4
+ * @category Math
+ *
+ * @param {number | any} x value to check
+ * @return {boolean} isOdd
+ *
+ * @see https://github.com/the-grid/finitedomain/blob/master/src/distribution/value.js#L395 qfox-iseven
+ * @see https://stackoverflow.com/questions/6211613/testing-whether-a-value-is-odd-or-even (smaller solution than original)
+ * @extends isNumber
+ * @alternate n % 2 === 0
+ *
+ * @example
+ *
+ * isOdd(1)
+ * //=> true
+ * isOdd(2)
+ * //=> false
+ */
+module.exports = function isOdd(x) {
+ return isNumber(x) && (x & 1)
+}
diff --git a/src/deps/math/range.js b/src/deps/math/range.js
new file mode 100644
index 0000000..fd0535c
--- /dev/null
+++ b/src/deps/math/range.js
@@ -0,0 +1,51 @@
+const isNill = require('../is/nullOrUndefined')
+
+/**
+ * Generate an integer Array containing an arithmetic progression. A port of
+ * the native Python `range()` function. See
+ * [the Python documentation](http://docs.python.org/library/functions.html#range).
+ *
+ * @name range
+ * @since 5.0.0-beta.6
+ * @memberOf math
+ *
+ * @param {number} start starting number
+ * @param {number} [stop] ending number, defaultsTo(start)
+ * @param {number} [step] step, defaultsto(-1 || 1)
+ * @return {Array} [start...stop]
+ *
+ * {@link https://github.com/jashkenas/underscore/blob/master/underscore.js#L714 underscore-range}
+ * @see {@link underscore-range}
+ *
+ * @example
+ *
+ * range(10)
+ * //=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+ * range(1, 11)
+ * //=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
+ * range(0, 30, 5)
+ * //=> [0, 5, 10, 15, 20, 25]
+ * range(0, -10, -1)
+ * //=> [0, -1, -2, -3, -4, -5, -6, -7, -8, -9]
+ * range(0)
+ * //=> []
+ *
+ */
+module.exports = function range(start, stop, step) {
+ if (isNill(stop)) {
+ stop = start || 0
+ start = 0
+ }
+ if (!step) {
+ step = stop < start ? -1 : 1
+ }
+
+ const length = Math.max(Math.ceil((stop - start) / step), 0)
+ const result = new Array(length)
+
+ for (let idx = 0; idx < length; idx++, start += step) {
+ result[idx] = start
+ }
+
+ return result
+}
diff --git a/src/deps/math/subtract.js b/src/deps/math/subtract.js
new file mode 100644
index 0000000..8799380
--- /dev/null
+++ b/src/deps/math/subtract.js
@@ -0,0 +1,21 @@
+const curry = require('../fp/curry')
+
+/**
+ * @name subtract
+ * @memberOf math
+ * @since 5.0.0-beta.4
+ * @category Math
+ *
+ * @curried 2
+ *
+ * @alias minus
+ * @alias sub
+ *
+ * @param {number} target number to subtract FROM
+ * @param {number} x number to subtract
+ * @return {number} target - x
+ *
+ * @example
+ * subtract(2, 2) //=> 0
+ */
+module.exports = curry(2, (target, x) => target - x)
diff --git a/src/deps/math/sum.js b/src/deps/math/sum.js
new file mode 100644
index 0000000..db3ed33
--- /dev/null
+++ b/src/deps/math/sum.js
@@ -0,0 +1,29 @@
+const reduce = require('../loop/flipped/reduceArrayFlipped')
+const add = require('./add')
+
+/**
+ * Adds together all the elements of a list.
+ * @since 5.0.0-beta.5
+ * @memberOf conditional
+ *
+ * @param {Array} list An array of numbers
+ * @return {Number} The sum of all the numbers in the list.
+ *
+ * @func
+ * @fork v0.1.0
+ * @category Math
+ * @sig [Number] -> Number
+ *
+ * {@link https://github.com/ramda/ramda/blob/master/src/sum.js ramda-sum}
+ * {@link https://github.com/lodash/lodash/blob/master/sum.js lodash-sum}
+ * @see {@link lodash-sum}
+ * @see {@link ramda-sum}
+ * @see loop/reduce
+ *
+ * @example
+ *
+ * sum([2,4,6,8,100,1])
+ * //=> 121
+ *
+ */
+module.exports = reduce(add, 0)
diff --git a/src/deps/meta/decorated.js b/src/deps/meta/DECORATED_KEY.js
similarity index 100%
rename from src/deps/meta/decorated.js
rename to src/deps/meta/DECORATED_KEY.js
diff --git a/src/deps/meta/observers.js b/src/deps/meta/OBSERVERS_KEY.js
similarity index 100%
rename from src/deps/meta/observers.js
rename to src/deps/meta/OBSERVERS_KEY.js
diff --git a/src/deps/meta/shorthands.js b/src/deps/meta/SHORTHANDS_KEY.js
similarity index 100%
rename from src/deps/meta/shorthands.js
rename to src/deps/meta/SHORTHANDS_KEY.js
diff --git a/src/deps/meta/transformers.js b/src/deps/meta/TRANSFORMERS_KEY.js
similarity index 100%
rename from src/deps/meta/transformers.js
rename to src/deps/meta/TRANSFORMERS_KEY.js
diff --git a/src/deps/ignored.js b/src/deps/meta/ignored.js
similarity index 100%
rename from src/deps/ignored.js
rename to src/deps/meta/ignored.js
diff --git a/src/deps/meta/keymap.js b/src/deps/meta/keymap.js
index c07e2c9..b0f67fe 100644
--- a/src/deps/meta/keymap.js
+++ b/src/deps/meta/keymap.js
@@ -1,49 +1,50 @@
-const isUndefined = require('../is/undefined')
-const isString = require('../is/string')
-
-const keys = [
- /* --- chain --- */
- /* 0 */ 'parent',
- /* 1 */ 'store',
- /* 2 */ 'meta',
- /* 3 */ 'className',
- /* --- meta --- */
- /* 4 */ 'observers',
- /* 5 */ 'transformers',
- /* 6 */ 'decorated',
- /* 7 */ 'shorthands',
- /* --- types --- */
- /* 8 */ 'undefined',
- /* 9 */ 'null',
- /* 10 */ 'string',
- /* 11 */ 'number',
- /* 12 */ 'function',
- /* 13 */ 'array',
- /* 14 */ 'boolean',
- /* --- next --- */
- '_', // ?
-]
-
-/* prettier-ignore */
-/**
- * @param {number} [index=Number]
- * @param {undefined | Object | Array} [obj=undefined]
- * @param {undefined | any} [val=undefined]
- * @return {string | number | any}
- */
-function access(index = -Infinity, obj = undefined, val = undefined) {
- if (isString(index)) index = keys.indexOf(index)
- // now map this to the arrays...
- let key = keys[index]
- // just name
- if (isUndefined(obj)) return key
- // get prop
- else if (isUndefined(val)) return obj[key]
- // set prop
- else if (!isUndefined(val)) return (obj[key] = val)
-}
-
-module.exports = Object.assign(access, require('./enums'), {access})
+// const isUndefined = require('../is/undefined')
+// const isString = require('../is/string')
+//
+// const keys = [
+// /* --- chain --- */
+// /* 0 */ 'parent',
+// /* 1 */ 'store',
+// /* 2 */ 'meta',
+// /* 3 */ 'className',
+// /* --- meta --- */
+// /* 4 */ 'observers',
+// /* 5 */ 'transformers',
+// /* 6 */ 'decorated',
+// /* 7 */ 'shorthands',
+// /* --- types --- */
+// /* 8 */ 'undefined',
+// /* 9 */ 'null',
+// /* 10 */ 'string',
+// /* 11 */ 'number',
+// /* 12 */ 'function',
+// /* 13 */ 'array',
+// /* 14 */ 'boolean',
+// /* --- next --- */
+// '_', // ?
+// ]
+//
+// /* prettier-ignore */
+// /**
+// * @param {number} [index=Number]
+// * @param {undefined | Object | Array} [obj=undefined]
+// * @param {undefined | any} [val=undefined]
+// * @return {string | number | any}
+// */
+// function access(index = -Infinity, obj = undefined, val = undefined) {
+// if (isString(index)) index = keys.indexOf(index)
+// // now map this to the arrays...
+// let key = keys[index]
+// // just name
+// if (isUndefined(obj)) return key
+// // get prop
+// else if (isUndefined(val)) return obj[key]
+// // set prop
+// else if (!isUndefined(val)) return (obj[key] = val)
+// }
+//
+// const enums = require('./enums')
+// module.exports = Object.assign(access, enums, {access})
// const eh = {parent: 100}
// const timer = require('fliplog').fliptime()
diff --git a/src/deps/meta/meta.js b/src/deps/meta/meta.js
index 2c381c7..4ae134a 100644
--- a/src/deps/meta/meta.js
+++ b/src/deps/meta/meta.js
@@ -1,15 +1,23 @@
-// without it, the arguments & caller are uglier when drbugging
-'use strict'
+/**
+ * @file without it, the arguments & caller are uglier when debugging
+ * @TODO freeze store props
+ * @TODO callsites are super polymorphic
+ */
+const ENV_DEBUG = require('../env/debug')
+const EMPTY_ARRAY = require('../native/EMPTY_ARRAY')
const isSet = require('../is/set')
+const hasOwnProperty = require('../util/hasOwnProperty')
+const iteratorToArray = require('../cast/iteratorToArray')
const ArrayFrom = require('../util/from')
const isUndefined = require('../is/undefined')
-const concat = require('../concat')
+const concat = require('../array/concat')
const toarr = require('../to-arr')
-const TRANSFORMERS_KEY = require('./transformers')
-const OBSERVERS_KEY = require('./observers')
-const SHORTHANDS_KEY = require('./shorthands')
-const DECORATED_KEY = require('./decorated')
+const size = require('../util/size')
+const TRANSFORMERS_KEY = require('./TRANSFORMERS_KEY')
+const OBSERVERS_KEY = require('./OBSERVERS_KEY')
+const SHORTHANDS_KEY = require('./SHORTHANDS_KEY')
+const DECORATED_KEY = require('./DECORATED_KEY')
// will expand this later
const isInKeyMapAsSet = x => x === OBSERVERS_KEY
@@ -25,7 +33,7 @@ const isInKeyMapAsSet = x => x === OBSERVERS_KEY
*/
function getMeta(_this) {
// if we already have it, keep it
- if (_this.meta) return _this.meta
+ if (hasOwnProperty(_this, 'meta')) return _this.meta
// the store
// shorthands: key -> method
@@ -61,7 +69,7 @@ function getMeta(_this) {
* @return {boolean}
*/
const has = (key, prop) => {
- if (isUndefined(prop)) return !!store[key].size
+ if (isUndefined(prop)) return !!size(store[key])
else return store[key].has(prop)
}
/**
@@ -70,7 +78,11 @@ function getMeta(_this) {
* @param {Primitive | undefined} [prop=undefined]
* @return {any}
*/
- const get = (key, prop) => (has(key, prop) ? store[key].get(prop) : [])
+ const get = (key, prop) => (
+ has(key, prop)
+ ? store[key].get(prop)
+ : EMPTY_ARRAY
+ )
/**
* @since 4.0.0
@@ -81,6 +93,7 @@ function getMeta(_this) {
*/
const set = (key, prop, value) => {
const storage = store[key]
+
// when it's a set, we have no `prop`, we just have .add
// so `prop = value` && `value = undefined`
if (isSet(storage)) {
@@ -108,17 +121,19 @@ function getMeta(_this) {
* @return {Array | Chain} depending on args
*/
function meta(key, prop, value) {
- if (process.env.NODE_ENV === 'DEBUG') {
- console.log('USING META', {key, prop, value})
- }
-
/* prettier-ignore */
if (isUndefined(value)) {
// when we want to just access the property, return an array
// @example `.meta('transformers')`
if (isUndefined(prop)) {
- if (isUndefined(store[key])) return []
- else return store[key].size === 0 ? [] : ArrayFrom(store[key].values())
+ if (ENV_DEBUG) {
+ console.log('META_CALL_GETTER', {[key]: store[key]})
+ }
+
+ if (isUndefined(store[key])) return EMPTY_ARRAY
+ else return size(store[key]) === 0
+ ? EMPTY_ARRAY
+ : ArrayFrom(store[key])
}
// we have `key, prop`
//
@@ -126,23 +141,48 @@ function getMeta(_this) {
else if (isInKeyMapAsSet(key)) {
ensureInitialized(key)
set(key, prop)
+ if (ENV_DEBUG) {
+ console.log('META_CALL_SET_SETTER', {key, value: prop, store})
+ }
}
// 2: prop is a key, we want to return the [..] for that specific property
// @example `.meta('transformers', 'eh')`
- else if (isUndefined(store[key])) return []
+ else if (isUndefined(store[key])) return EMPTY_ARRAY
else return toarr(get(key, prop))
}
// we have `key, prop, value`
else {
ensureInitialized(key)
+
// we have a value, let's add it
set(key, prop, value)
+
+ if (ENV_DEBUG) {
+ console.log('META_CALL_MAP_SETTER', {key, prop, value, store})
+ }
}
+
return _this
}
// for debugging
meta.store = store
+
+ // @NOTE not really needed, can just do `meta.store.[prop].clear`
+ // meta.clear = prop => meta.store[prop].clear()
+
+ // @TODO use `remove` here, so it will delete say, index
+ //
+ // @example store.transformers = Map({eh: [transformer, anotherTransformer]})
+ // store.delete('transformers.eh[0]')
+ //
+ // @example store.observers = Map({eh: [transformer, anotherTransformer]})
+ // store.delete('observers[-1]')
+ //
+ // eslint-disable-next-line
+ // meta['delete'] = (prop, valueOrKey) => meta.store[prop].delete(valueOrKey)
+
+ // default value
// meta.debug = false
return meta
diff --git a/src/deps/native/EMPTY_ARRAY.js b/src/deps/native/EMPTY_ARRAY.js
new file mode 100644
index 0000000..18a377b
--- /dev/null
+++ b/src/deps/native/EMPTY_ARRAY.js
@@ -0,0 +1,16 @@
+const freeze = require('../util/freeze')
+
+/**
+ * @desc frozen empty array
+ * @name EMPTY_ARRAY
+ * @alias emptyArray
+ * @type {Array}
+ *
+ * @frozen
+ *
+ * {@link https://github.com/mobxjs/mobx/blob/master/src/utils/utils.ts#L1 mobx-empty-array}
+ * @see {@link mobx-empty-array}
+ */
+const EMPTY_ARRAY = []
+freeze(EMPTY_ARRAY)
+module.exports = EMPTY_ARRAY
diff --git a/src/deps/native/EMPTY_OBJ.js b/src/deps/native/EMPTY_OBJ.js
new file mode 100644
index 0000000..a357060
--- /dev/null
+++ b/src/deps/native/EMPTY_OBJ.js
@@ -0,0 +1,13 @@
+const freeze = require('../util/freeze')
+
+/**
+ * @desc frozen empty object
+ * @name EMPTY_OBJ
+ * @alias emptyObject
+ * @alias emptyObj
+ * @frozen
+ * @type {Object}
+ */
+const EMPTY_OBJ = {}
+freeze(EMPTY_OBJ)
+module.exports = EMPTY_OBJ
diff --git a/src/deps/native/EMPTY_STRING.js b/src/deps/native/EMPTY_STRING.js
new file mode 100644
index 0000000..c72add9
--- /dev/null
+++ b/src/deps/native/EMPTY_STRING.js
@@ -0,0 +1,2 @@
+// https://github.com/the-grid/finitedomain/blob/master/src/domain.js#L49
+module.exports = ''
diff --git a/src/deps/native/FALSEY_LIST.js b/src/deps/native/FALSEY_LIST.js
new file mode 100644
index 0000000..0cf01d7
--- /dev/null
+++ b/src/deps/native/FALSEY_LIST.js
@@ -0,0 +1,10 @@
+const freeze = require('../util/freeze')
+
+/**
+ * @desc used to provide falsey values to methods.
+ * @frozen
+ * @name FALSEY_LIST
+ * @type {Array}
+ */
+// eslint-disable-next-line
+var falsey = freeze([, null, undefined, false, 0, NaN, ''])
diff --git a/src/deps/native/INFINITY.js b/src/deps/native/INFINITY.js
new file mode 100644
index 0000000..cd69a69
--- /dev/null
+++ b/src/deps/native/INFINITY.js
@@ -0,0 +1,6 @@
+/**
+ * Used as references for various `Number` constants.
+ * @name INFINITY
+ * @type {number}
+ */
+module.exports = 1 / 0
diff --git a/src/deps/native/LARGE_ARRAY_SIZE.js b/src/deps/native/LARGE_ARRAY_SIZE.js
new file mode 100644
index 0000000..9bfbb2e
--- /dev/null
+++ b/src/deps/native/LARGE_ARRAY_SIZE.js
@@ -0,0 +1,8 @@
+/**
+ * @desc Used as the size to enable large array optimizations.
+ * @name LARGE_ARRAY_SIZE
+ * @since 5.0.0-beta.6
+ * @type {number}
+ * @see array/preAllocate
+ */
+module.exports = 200
diff --git a/src/deps/native/MAX_32_BIT.js b/src/deps/native/MAX_32_BIT.js
new file mode 100644
index 0000000..5e958a7
--- /dev/null
+++ b/src/deps/native/MAX_32_BIT.js
@@ -0,0 +1,8 @@
+/**
+ * @desc 2^32
+ * @name MAX_32_BIT
+ * @type {number}
+ * @example `Math.pow(2, 32)`
+ * @NOTE this is -1
+ */
+module.exports = 4294967295
diff --git a/src/deps/native/MAX_ARRAY_INDEX.js b/src/deps/native/MAX_ARRAY_INDEX.js
new file mode 100644
index 0000000..40e1730
--- /dev/null
+++ b/src/deps/native/MAX_ARRAY_INDEX.js
@@ -0,0 +1,9 @@
+const MAX_ARRAY_LENGTH = require('./MAX_ARRAY_LENGTH')
+
+/**
+ * @desc Used as references for the maximum length and index of an array.
+ * @type {number}
+ * @name MAX_ARRAY_INDEX
+ * @see native/MAX_ARRAY_LENGTH
+ */
+module.exports = MAX_ARRAY_LENGTH - 1
diff --git a/src/deps/native/MAX_ARRAY_LENGTH.js b/src/deps/native/MAX_ARRAY_LENGTH.js
new file mode 100644
index 0000000..299bbda
--- /dev/null
+++ b/src/deps/native/MAX_ARRAY_LENGTH.js
@@ -0,0 +1,6 @@
+/**
+ * @desc Used as references for the maximum length and index of an array.
+ * @name MAX_ARRAY_LENGTH
+ * @type {number}
+ */
+module.exports = 4294967295
diff --git a/src/deps/native/MAX_INTEGER.js b/src/deps/native/MAX_INTEGER.js
new file mode 100644
index 0000000..018472b
--- /dev/null
+++ b/src/deps/native/MAX_INTEGER.js
@@ -0,0 +1,7 @@
+/**
+ * @desc Used as references for the maximum length and index of an array.
+ * @type {number}
+ * @name MAX_INTEGER
+ * @see cast/toFinite
+ */
+module.exports = 1.7976931348623157e+308
diff --git a/src/deps/native/MAX_SAFE_INTEGER.js b/src/deps/native/MAX_SAFE_INTEGER.js
new file mode 100644
index 0000000..1727e02
--- /dev/null
+++ b/src/deps/native/MAX_SAFE_INTEGER.js
@@ -0,0 +1,12 @@
+/**
+ * @name MAX_SAFE_INTEGER
+ * @desc Used as references for various `Number` constants.
+ * @type {number}
+ *
+ * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER mozilla-numbermaxsafeinteger}
+ * @see {@link mozilla-numbermaxsafeinteger}
+ * @see cast/toNumber
+ *
+ * @example `Math.pow(2, 53) + 1`
+ */
+module.exports = 9007199254740991
diff --git a/src/deps/native/MAX_SPLICE_SIZE.js b/src/deps/native/MAX_SPLICE_SIZE.js
new file mode 100644
index 0000000..eac9574
--- /dev/null
+++ b/src/deps/native/MAX_SPLICE_SIZE.js
@@ -0,0 +1,6 @@
+/**
+ * @name MAX_SPLICE_SIZE
+ * {@link https://github.com/mobxjs/mobx/blob/master/src/types/observablearray.ts#L10 mobx-max-splice-size}
+ * @see {@link mobx-max-splice-size}
+ */
+module.exports = 10000
diff --git a/src/deps/native/NON_ENUMERABLE.js b/src/deps/native/NON_ENUMERABLE.js
new file mode 100644
index 0000000..9779883
--- /dev/null
+++ b/src/deps/native/NON_ENUMERABLE.js
@@ -0,0 +1,25 @@
+const freeze = require('../util/freeze')
+
+/**
+ * properies that are reserved and should not be enumerated
+ * unless they `haveOwnProperty`
+ *
+ * @name NATIVE_PROPS_NON_ENUMERABLE
+ * @frozen
+ * @type {Array}
+ */
+module.exports = freeze([
+ '__defineGetter__',
+ '__defineSetter__',
+ '__proto__',
+ '__lookupGetter__',
+ '__lookupSetter__',
+ 'hasOwnProperty',
+ 'propertyIsEnumerable',
+ 'toLocaleString',
+ 'isPrototypeOf',
+ 'toString',
+ 'constructor',
+ 'prototype',
+ 'valueOf',
+])
diff --git a/src/deps/native/OBJECT_STRING_TAGS.js b/src/deps/native/OBJECT_STRING_TAGS.js
new file mode 100644
index 0000000..e3a5ad7
--- /dev/null
+++ b/src/deps/native/OBJECT_STRING_TAGS.js
@@ -0,0 +1,63 @@
+// Object.getOwnPropertyNames(window).filter(name => /[A-Z]/.test(name.charAt(0))
+// Object
+// .getOwnPropertyNames(window)
+// .filter(name => (/[A-Z]/).test(name.charAt(0)))
+// .map(name => {
+// return name + ': ' + Object.prototype.toString.call(window[name])
+// })
+// .filter((value, index, arr) => arr.indexOf(value) === index)
+
+const freeze = require('../util/freeze')
+
+// https://github.com/jonschlinkert/kind-of/blob/master/index.js
+const OBJECT_TO_STRING_TAGS = [
+ /* 0 */ '[object Undefined]',
+ /* 1 */ '[object Null]',
+ /* 2 */ '[object Map]',
+ /* 2 */ '[object WeakMap]',
+ /* 2 */ '[object Map Iterator]',
+ /* 2 */ '[object Set]',
+ /* 2 */ '[object WeakSet]',
+ /* 2 */ '[object Set Iterator]',
+ /* 3 */ '[object Arguments]',
+ /* 4 */ '[object Boolean]',
+ /* 4 */ '[object Number]',
+ /* 5 */ '[object String]',
+ /* 5 */ '[object Date]',
+ /* 5 */ '[object Error]',
+ /* 5 */ '[object Function]',
+ /* 5 */ '[object Object]',
+ /* 5 */ '[object Promise]',
+
+ // less common
+ /* 5 */ '[object Symbol]',
+ /* 5 */ '[object Array]',
+ /* 5 */ '[object AsyncFunction]',
+ /* 5 */ '[object GeneratorFunction]',
+
+ // typed arrays
+ /* 5 */ '[object Int8Array]',
+ /* 5 */ '[object Uint8Array]',
+ /* 5 */ '[object Uint8ClampedArray]',
+ /* 5 */ '[object Int16Array]',
+ /* 5 */ '[object Uint16Array]',
+ /* 5 */ '[object Int32Array]',
+ /* 5 */ '[object Uint32Array]',
+ /* 5 */ '[object Float32Array]',
+ /* 5 */ '[object Float64Array]',
+
+ // much less common
+ /* 5 */ '[object ArrayBuffer]',
+ /* 5 */ '[object DataView]',
+ /* 5 */ '[object Buffer]',
+
+ // '[object Reflect]',
+ // '[object Proxy]',
+ // '[object WebSocket]',
+ // '[object WebAssembly]',
+ // '[object JSON]',
+ // '[object JSON]',
+ // '[object Math]',
+]
+
+freeze(OBJECT_TO_STRING_TAGS)
diff --git a/src/deps/native/PRIMITIVES_LIST.js b/src/deps/native/PRIMITIVES_LIST.js
new file mode 100644
index 0000000..c1545d7
--- /dev/null
+++ b/src/deps/native/PRIMITIVES_LIST.js
@@ -0,0 +1,8 @@
+const freeze = require('../util/freeze')
+
+/**
+ * @desc Used to provide primitive values to methods.
+ * @type {Array}
+ * @frozen
+ */
+module.exports = freeze([null, undefined, false, true, 1, NaN, 'a'])
diff --git a/src/deps/native/arrayEntries.js b/src/deps/native/arrayEntries.js
new file mode 100644
index 0000000..20541ff
--- /dev/null
+++ b/src/deps/native/arrayEntries.js
@@ -0,0 +1 @@
+module.exports = Array.prototype.entries
diff --git a/src/deps/native/arraySlice.js b/src/deps/native/arraySlice.js
new file mode 100644
index 0000000..7fc3773
--- /dev/null
+++ b/src/deps/native/arraySlice.js
@@ -0,0 +1,5 @@
+/**
+ * @see https://github.com/ramda/ramda/blob/master/src/slice.js
+ * @type {Function}
+ */
+module.exports = Array.prototype.slice
diff --git a/src/deps/native/functionToString.js b/src/deps/native/functionToString.js
new file mode 100644
index 0000000..480a38c
--- /dev/null
+++ b/src/deps/native/functionToString.js
@@ -0,0 +1,6 @@
+/**
+ * Used to resolve the decompiled source of functions.
+ * @type {Function}
+ * @throws
+ */
+module.exports = Function.prototype.toString
diff --git a/src/deps/native/index.js b/src/deps/native/index.js
new file mode 100644
index 0000000..00b4ded
--- /dev/null
+++ b/src/deps/native/index.js
@@ -0,0 +1,9 @@
+/**
+ * @member native
+ * @since 5.0.0-beta.5
+ *
+ * https://github.com/the-grid/finitedomain/blob/master/src/helpers.js#L174
+ * https://github.com/the-grid/finitedomain/blob/master/src/helpers.js#L37
+ * {@link https://github.com/jashkenas/underscore/blob/master/underscore.js#L22 underscore-native}
+ * @see {@link underscore-native}
+ */
diff --git a/src/deps/native/keywords.js b/src/deps/native/keywords.js
new file mode 100644
index 0000000..f304e51
--- /dev/null
+++ b/src/deps/native/keywords.js
@@ -0,0 +1,10 @@
+// @memberOf native
+// @name keywords
+// @TODO freeze
+// https://github.com/facebook/immutable-js/blob/master/src/TrieUtils.js#L10
+// Used for setting prototype methods that IE8 chokes on.
+// module.exports = {
+// 'DELETE': 'delete',
+// 'DEFAULT': 'default',
+// 'RETURN'
+// }
diff --git a/src/deps/native/native.js b/src/deps/native/native.js
new file mode 100644
index 0000000..35a17b7
--- /dev/null
+++ b/src/deps/native/native.js
@@ -0,0 +1,4 @@
+/**
+ * @icon 🏎️
+ * @member native
+ */
diff --git a/src/deps/native/objectHasOwnProperty.js b/src/deps/native/objectHasOwnProperty.js
new file mode 100644
index 0000000..e3804d9
--- /dev/null
+++ b/src/deps/native/objectHasOwnProperty.js
@@ -0,0 +1,6 @@
+/**
+ * Used to check objects for own properties.
+ * @type {Function}
+ * @throws
+ */
+module.exports = Object.prototype.hasOwnProperty
diff --git a/src/deps/native/objectToString.js b/src/deps/native/objectToString.js
new file mode 100644
index 0000000..e9643b9
--- /dev/null
+++ b/src/deps/native/objectToString.js
@@ -0,0 +1 @@
+module.exports = Object.prototype.toString
diff --git a/src/deps/native/propertyIsEnumerable.js b/src/deps/native/propertyIsEnumerable.js
new file mode 100644
index 0000000..744a19b
--- /dev/null
+++ b/src/deps/native/propertyIsEnumerable.js
@@ -0,0 +1 @@
+module.exports = Object.prototype.propertyIsEnumerable
diff --git a/src/deps/reduce/clean.js b/src/deps/reduce/clean.js
index fc6d993..7aa6380 100644
--- a/src/deps/reduce/clean.js
+++ b/src/deps/reduce/clean.js
@@ -1,7 +1,12 @@
-const isNotEmptyArray = require('../is/notEmptyArray')
const isReal = require('../is/real')
-const isObjWithKeys = require('../is/objWithKeys')
+const isEmpty = require('../is/empty')
const ObjectKeys = require('../util/keys')
+const filterWhere = require('../loop/filter/filterWhere')
+const reduceToObj = require('./toObj')
+
+// const [isNotReal, isNotEmpty] = [isReal, isEmpty].map(not)
+// const isNotEmptyOrNotReal = or(isNotReal, isNotEmpty)
+const mapNotEmpty = filterWhere('_', x => isReal(x) && !isEmpty(x))
/**
* @desc goes through the maps,
@@ -16,10 +21,13 @@ const ObjectKeys = require('../util/keys')
* @param {Object} obj object to clean, usually .entries()
* @return {Object} reduced object, without `notReal` values
*
+ * @TODO seems to be overkill with reducing mapping just copy & ignore or delete?
+ *
* @see reduce
* @see isObjWithKeys
* @see isNotEmptyArray
* @see isReal
+ * @see http://underscorejs.org/#reduce
*
* @example
*
@@ -37,13 +45,9 @@ const ObjectKeys = require('../util/keys')
*
*/
module.exports = function clean(obj) {
- return ObjectKeys(obj).reduce(function(acc, key) {
- const val = obj[key]
-
- if (isReal(val) && (isNotEmptyArray(val) || isObjWithKeys(val))) {
- acc[key] = val
- }
+ const mapped = mapNotEmpty(obj)
+ const keys = ObjectKeys(mapped)
+ const iterator = (reduced, key) => (reduced[key] = mapped[key])
- return acc
- }, {})
+ return reduceToObj(keys, iterator)
}
diff --git a/src/deps/reduce/entries.js b/src/deps/reduce/entries.js
index 71d527e..2af96ae 100644
--- a/src/deps/reduce/entries.js
+++ b/src/deps/reduce/entries.js
@@ -1,5 +1,7 @@
const isFunction = require('../is/function')
-const ignored = require('../ignored')
+const isObj = require('../is/obj')
+const hasIn = require('../is/in')
+const ignored = require('../meta/ignored')
const ObjectKeys = require('../util/keys')
const ObjectAssign = require('../util/assign')
@@ -12,7 +14,9 @@ const ObjectAssign = require('../util/assign')
* @param {Object | any} reduced merged object and reduced
* @return {Function} Function(values: Object)
*
+ * @see https://www.airpair.com/javascript/javascript-array-reduce
* @see ChainedMap
+ * @NOTE could curry, but this is super hot function
*
* @example
*
@@ -31,7 +35,7 @@ const ObjectAssign = require('../util/assign')
* }
* const reduced = reduce(map)
* reduceEntries(reduced)({chain})
- * // => {
+ * //=> {
* eh: true,
* chain: {
* nested: {
@@ -63,6 +67,12 @@ const ObjectAssign = require('../util/assign')
module.exports = reduced => obj => {
const keys = ObjectKeys(obj)
+ // const filter = (value, key) =>
+ // !ignored(key) && hasIn(value, 'entries')
+ // const transform = (value, key) =>
+ // ObjectAssign(reduced, {[key]: value.entries(true) || {}})
+ // mapFilterWhere(obj, filter, transform)
+
for (let k = 0; k < keys.length; k++) {
const key = keys[k]
@@ -70,9 +80,11 @@ module.exports = reduced => obj => {
continue
}
- const val = obj[key]
- if (val && isFunction(val.entries)) {
- ObjectAssign(reduced, {[key]: val.entries(true) || {}})
+ const value = obj[key]
+ // @NOTE could use hasInMatching here
+ // isObj(value) && isFunction(value.entries)
+ if (hasIn(value, 'entries')) {
+ ObjectAssign(reduced, {[key]: value.entries(true) || {}})
}
}
diff --git a/src/deps/reduce/objects.js b/src/deps/reduce/objects.js
deleted file mode 100644
index 90890c7..0000000
--- a/src/deps/reduce/objects.js
+++ /dev/null
@@ -1,17 +0,0 @@
-// @TODO
-// const reduce = require('./entries')
-// const indexValueBy = property => x => {
-// const obj = {}
-// Object.keys(x).map(key => obj[property] = x)
-// }
-// const indexPropBy = key => {}
-// const pluckValues = keys => {}
-// const spreadValues = keys = {} // into arr in order?
-// const orderBy = keys => {} // order
-//
-// module.exports = (key, valueProp) => x => {
-// const reduced = reduce(x)
-// const indexed = indexPropBy(key)(reduced)
-// const mapped = indexValueBy(valueProp)(indexed)
-// return mapped
-// }
diff --git a/src/deps/reduce/reduce.js b/src/deps/reduce/reduce.js
index 00e3bed..b61c370 100644
--- a/src/deps/reduce/reduce.js
+++ b/src/deps/reduce/reduce.js
@@ -1,10 +1,11 @@
const ArrayFrom = require('../util/from')
+const castIteratorToArray = require('../cast/iteratorToArray')
/**
* @desc Map -> Object
* @since 4.0.0
*
- * @param {Map} map map to reduce, calls entries, turns into an array, then object
+ * @param {Map} map map to reduce, calls entries, turns into an array, then object
* @return {Object} reduced object
*
* @see ArrayFrom
@@ -13,14 +14,14 @@ const ArrayFrom = require('../util/from')
*
* var emptyMap = new Map()
* reduce(emptyMap)
- * // => {}
+ * //=> {}
*
* @example
*
* var map = new Map()
* map.set('eh', 1)
* reduce(map)
- * // => {eh: 1}
+ * //=> {eh: 1}
*
*/
module.exports = map => {
@@ -31,7 +32,7 @@ module.exports = map => {
reduced = ArrayFrom(map.entries()).reduce((acc, [key, value]) => {
acc[key] = value
return acc
- }, {})
+ }, reduced)
}
return reduced
diff --git a/src/deps/reduce/toObj.js b/src/deps/reduce/toObj.js
new file mode 100644
index 0000000..ce7b5ab
--- /dev/null
+++ b/src/deps/reduce/toObj.js
@@ -0,0 +1,23 @@
+/**
+ * @since 4.0.0
+ *
+ * @param {Array} array array to reduce to object
+ * @param {Function} iterator function to call on reduced, with `next`
+ * @return {Object} reduced array
+ *
+ *
+ * @name reduceObj
+ * @alias reduceObject
+ * @alias toObj
+ *
+ * @see Chainable
+ *
+ * @TODO example
+ * @TODO @curried 2
+ */
+module.exports = function reduceObj(array, iterator) {
+ return array.reduce(function(reduced, next) {
+ iterator(reduced, next)
+ return reduced
+ }, {})
+}
diff --git a/src/deps/regexp/index.js b/src/deps/regexp/index.js
new file mode 100644
index 0000000..a85de0d
--- /dev/null
+++ b/src/deps/regexp/index.js
@@ -0,0 +1,41 @@
+// const urlRegExp = new RegExp(/https?/)
+// const isUrlReg = {
+// test(value) {
+// return (/^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})).?)(?::\d{2,5})?(?:[/?#]\S*)?$/i).test(value)
+// },
+// }
+const url = require('./matchUrl')
+const matchDeepProp = require('./matchDeepProp')
+const matchRegExp = require('./regexpMatch')
+const matchPlainProp = require('./matchPlainProp')
+const matchUnsigned = require('./matchUnsigned')
+const matchInteger = require('./matchInteger')
+const matchNative = require('./matchNative')
+const matchRegExpEscapable = require('./matchRegExpEscapable')
+const matchTypedTag = require('./matchTypedTag')
+const matchUnicode = require('./matchUnicode')
+const matchHex = require('./matchHex')
+
+// dateString match m/d/yy and mm/dd/yyyy, allowing any combination of one or two digits for the day and month, and two or four digits for the year
+// eppPhone match extensible provisioning protocol format
+// nanpPhone match north american number plan format
+// time match hours, minutes, and seconds, 24-hour clock
+module.exports = {
+ affirmative: /^(?:1|t(?:rue)?|y(?:es)?|ok(?:ay)?)$/,
+ alphaNumeric: /^[A-Za-z0-9]+$/,
+ caPostalCode: /^(?!.*[DFIOQU])[A-VXY][0-9][A-Z]\s?[0-9][A-Z][0-9]$/,
+ creditCard: /^(?:(4[0-9]{12}(?:[0-9]{3})?)|(5[1-5][0-9]{14})|(6(?:011|5[0-9]{2})[0-9]{12})|(3[47][0-9]{13})|(3(?:0[0-5]|[68][0-9])[0-9]{11})|((?:2131|1800|35[0-9]{3})[0-9]{11}))$/,
+ dateString: /^(1[0-2]|0?[1-9])([\/-])(3[01]|[12][0-9]|0?[1-9])(?:\2)(?:[0-9]{2})?[0-9]{2}$/,
+ email: /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i, // eslint-disable-line no-control-regex
+ eppPhone: /^\+[0-9]{1,3}\.[0-9]{4,14}(?:x.+)?$/,
+ hexadecimal: /^(?:0x)?[0-9a-fA-F]+$/,
+ hexColor: /^#?([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/,
+ ipv4: /^(?:(?:\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])\.){3}(?:\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])$/,
+ ipv6: /^((?=.*::)(?!.*::.+::)(::)?([\dA-F]{1,4}:(:|\b)|){5}|([\dA-F]{1,4}:){6})((([\dA-F]{1,4}((?!\3)::|:\b|$))|(?!\2\3)){2}|(((2[0-4]|1\d|[1-9])?\d|25[0-5])\.?\b){4})$/i,
+ nanpPhone: /^\(?([0-9]{3})\)?[-. ]?([0-9]{3})[-. ]?([0-9]{4})$/,
+ socialSecurityNumber: /^(?!000|666)[0-8][0-9]{2}-?(?!00)[0-9]{2}-?(?!0000)[0-9]{4}$/,
+ timeString: /^(2[0-3]|[01]?[0-9]):([0-5]?[0-9]):([0-5]?[0-9])$/,
+ ukPostCode: /^[A-Z]{1,2}[0-9RCHNQ][0-9A-Z]?\s?[0-9][ABD-HJLNP-UW-Z]{2}$|^[A-Z]{2}-?[0-9]{4}$/,
+ url,
+ usZipCode: /^[0-9]{5}(?:-[0-9]{4})?$/,
+}
diff --git a/src/deps/regexp/matchBooleanIsh.js b/src/deps/regexp/matchBooleanIsh.js
new file mode 100644
index 0000000..320bb57
--- /dev/null
+++ b/src/deps/regexp/matchBooleanIsh.js
@@ -0,0 +1,15 @@
+const toTestable = require('../cast/toTestable')
+const isTrue = require('../is/true')
+const isFalse = require('../is/false')
+const or = require('../conditional/or')
+
+const quote = `("|')?`
+const begin = '^'
+const end = '$'
+const matchTrue = toTestable(begin + quote + '(true)' + quote + end)
+const matchFalse = toTestable(begin + quote + '(false)' + quote + end)
+const matchTrueOrFalse = or(matchTrue, matchFalse)
+const isTruish = or(isTrue, matchTrue)
+const isFalsish = or(isFalse, matchFalse)
+
+module.exports = {matchTrue, matchTrueOrFalse, isTruish, isFalsish}
diff --git a/src/deps/regexp/matchDeepProp.js b/src/deps/regexp/matchDeepProp.js
new file mode 100644
index 0000000..0fa620e
--- /dev/null
+++ b/src/deps/regexp/matchDeepProp.js
@@ -0,0 +1,2 @@
+/** Used to match property names within property paths. */
+module.exports = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/
diff --git a/src/deps/regexp/matchHex.js b/src/deps/regexp/matchHex.js
new file mode 100644
index 0000000..cee2bc7
--- /dev/null
+++ b/src/deps/regexp/matchHex.js
@@ -0,0 +1 @@
+module.exports = /^0x[0-9a-f]+$/i
diff --git a/src/deps/regexp/matchInteger.js b/src/deps/regexp/matchInteger.js
new file mode 100644
index 0000000..9292489
--- /dev/null
+++ b/src/deps/regexp/matchInteger.js
@@ -0,0 +1 @@
+module.exports = /^[-+]?(?:\d+(?:\.\d*)?|\.\d+)(e[-+]?\d+)?$/
diff --git a/src/deps/regexp/matchNative.js b/src/deps/regexp/matchNative.js
new file mode 100644
index 0000000..d5ac087
--- /dev/null
+++ b/src/deps/regexp/matchNative.js
@@ -0,0 +1,17 @@
+const funcToString = require('../native/functionToString')
+const hasOwnProperty = require('../native/objectHasOwnProperty')
+
+module.exports = RegExp(
+ '^' +
+ funcToString
+ // Take an example native function source for comparison
+ .call(hasOwnProperty)
+ // Strip regex characters so we can use it for regex
+ .replace(/[\\^$.*+?()[\]{}|]/g, '\\$&')
+ // Remove hasOwnProperty from the template to make it generic
+ .replace(
+ /hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,
+ '$1.*?'
+ ) +
+ '$'
+)
diff --git a/src/deps/regexp/matchPlainProp.js b/src/deps/regexp/matchPlainProp.js
new file mode 100644
index 0000000..01fdebd
--- /dev/null
+++ b/src/deps/regexp/matchPlainProp.js
@@ -0,0 +1 @@
+module.exports = /^\w*$/
diff --git a/src/deps/regexp/matchRegExpEscapable.js b/src/deps/regexp/matchRegExpEscapable.js
new file mode 100644
index 0000000..20659ac
--- /dev/null
+++ b/src/deps/regexp/matchRegExpEscapable.js
@@ -0,0 +1 @@
+module.exports = /[|\\{}()[\]^$+*?.]/g
diff --git a/src/deps/regexp/matchTypedTag.js b/src/deps/regexp/matchTypedTag.js
new file mode 100644
index 0000000..c2e9f25
--- /dev/null
+++ b/src/deps/regexp/matchTypedTag.js
@@ -0,0 +1,6 @@
+/**
+ * @desc Used to match `toStringTag` values of typed arrays.
+ * @name matchTypedTag
+ * @type {RegExp}
+ */
+module.exports = /^\[object (?:Float(?:32|64)|(?:Int|Uint)(?:8|16|32)|Uint8Clamped)\]$/
diff --git a/src/deps/regexp/matchUnicode.js b/src/deps/regexp/matchUnicode.js
new file mode 100644
index 0000000..36aa6ed
--- /dev/null
+++ b/src/deps/regexp/matchUnicode.js
@@ -0,0 +1,26 @@
+/**
+ * @desc Used to compose unicode character classes.
+ * {@link https://github.com/qfox/heatfiler/blob/master/lib/uni.js qfox-uni}
+ * @type {string}
+ */
+const rsAstralRange = '\\ud800-\\udfff'
+const rsComboMarksRange = '\\u0300-\\u036f'
+const reComboHalfMarksRange = '\\ufe20-\\ufe2f'
+const rsComboSymbolsRange = '\\u20d0-\\u20ff'
+const rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange
+const rsVarRange = '\\ufe0e\\ufe0f'
+
+/**
+ * @desc Used to compose unicode capture groups.
+ * @type {string}
+ */
+const rsZWJ = '\\u200d'
+
+/**
+ * @desc Used to detect strings
+ * with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/).
+ *
+ * @name matchUnicode
+ * @type {RegExp}
+ */
+module.exports = RegExp(`[${rsZWJ + rsAstralRange + rsComboRange + rsVarRange}]`)
diff --git a/src/deps/regexp/matchUnsigned.js b/src/deps/regexp/matchUnsigned.js
new file mode 100644
index 0000000..bc16da7
--- /dev/null
+++ b/src/deps/regexp/matchUnsigned.js
@@ -0,0 +1,2 @@
+/** Used to detect unsigned integer values. */
+module.exports = /^(?:0|[1-9]\d*)$/
diff --git a/src/deps/regexp/matchUrl.js b/src/deps/regexp/matchUrl.js
new file mode 100644
index 0000000..0e898e1
--- /dev/null
+++ b/src/deps/regexp/matchUrl.js
@@ -0,0 +1 @@
+module.exports = /^(?:(?:https?|ftp):\/\/)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})))(?::\d{2,5})?(?:\/\S*)?$/i
diff --git a/src/deps/regexp/regexpMatch.js b/src/deps/regexp/regexpMatch.js
new file mode 100644
index 0000000..2f0d76b
--- /dev/null
+++ b/src/deps/regexp/regexpMatch.js
@@ -0,0 +1,4 @@
+/**
+ * @member regexp
+ * @icon 🎯
+ */
diff --git a/src/deps/camel-case.js b/src/deps/string/camelCase.js
similarity index 94%
rename from src/deps/camel-case.js
rename to src/deps/string/camelCase.js
index ca235f5..75bb2fe 100644
--- a/src/deps/camel-case.js
+++ b/src/deps/string/camelCase.js
@@ -2,6 +2,7 @@
/**
* @desc camelCase
* @since 0.2.0
+ * @symb 🐫
*
* @param {string} str string to turn into camelCase
* @return {string} camelCased string
@@ -13,6 +14,9 @@
* @see https://stackoverflow.com/questions/1533131/what-useful-bitwise-operator-code-tricks-should-a-developer-know-about
* @TODO s.charAt(0).toLowerCase() + string.slice(1)
*
+ * @types deps
+ * @tests deps/camelCase
+ *
* @example
*
* camelCase('snake_case')
diff --git a/src/deps/string/charCodeAt.js b/src/deps/string/charCodeAt.js
new file mode 100644
index 0000000..8472fde
--- /dev/null
+++ b/src/deps/string/charCodeAt.js
@@ -0,0 +1,14 @@
+const curry = require('../fp/curry')
+
+/**
+ * @memberOf string
+ * @name charCodeAt
+ * @version 5.0.0 <- moved from util to string
+ * @since 4.0.0
+ *
+ * @param {string} str string to getCharCodeAt
+ * @return {number}
+ *
+ * @example charCodeAt('eh') //=> code for e
+ */
+module.exports = curry(2, (str, index) => str.charCodeAt(index))
diff --git a/src/deps/string/charCodeAtZero.js b/src/deps/string/charCodeAtZero.js
new file mode 100644
index 0000000..7d5df49
--- /dev/null
+++ b/src/deps/string/charCodeAtZero.js
@@ -0,0 +1,10 @@
+/**
+ * @memberOf string
+ * @name charCodeAtZero
+ * @version 5.0.0 <- moved from util to string
+ * @since 4.0.0
+ * @param {string} str
+ * @return {number}
+ * @example charCodeAt('eh') //=> code for e
+ */
+module.exports = str => str.charCodeAt(0)
diff --git a/src/deps/string/class-names.js b/src/deps/string/classNames.js
similarity index 94%
rename from src/deps/string/class-names.js
rename to src/deps/string/classNames.js
index 642de50..c1d9626 100644
--- a/src/deps/string/class-names.js
+++ b/src/deps/string/classNames.js
@@ -1,5 +1,6 @@
/**
* @example get className() {return classNames(this)}
+ * @memberOf string
* @param {Object} _c
* @return {string}
*/
diff --git a/src/deps/string/escapeRegExp.js b/src/deps/string/escapeRegExp.js
new file mode 100644
index 0000000..e3b4a55
--- /dev/null
+++ b/src/deps/string/escapeRegExp.js
@@ -0,0 +1,31 @@
+const matchRegExpEscapable = require('../regexp/matchRegExpEscapable')
+const replace = require('../fp/replace')
+
+/**
+ * @name escapeStringRegExp
+ * @alias escapeString
+ * @alias escapeStr
+ * @module escape-string-regexp 🍴
+ * @memberOf string
+ * @memberOf matcher
+ *
+ * @since 3.0.0
+ * @version 5.0.0 <- moved to string from matcher
+ *
+ * @param {string} str string to escape
+ * @return {string} escaped string
+ *
+ * @func
+ *
+ * {@link https://github.com/sindresorhus/escape-string-regexp escape-string-regexp}
+ * @see {@link escape-string-regexp}
+ * @see fp/replace
+ *
+ * @example
+ *
+ * const escaped = escapeStringRegexp('how much $ for a unicorn?');
+ * //=> 'how much \$ for a unicorn\?'
+ * new RegExp(escaped);
+ *
+ */
+module.exports = replace(matchRegExpEscapable, '\\$&')
diff --git a/src/deps/string/escapedToDotStar.js b/src/deps/string/escapedToDotStar.js
new file mode 100644
index 0000000..fbcd54d
--- /dev/null
+++ b/src/deps/string/escapedToDotStar.js
@@ -0,0 +1,4 @@
+const replace = require('../fp/replace')
+
+// replaceEscapedStar
+module.exports = replace(/\\\*/g, '.*')
diff --git a/src/deps/string/firstToLowerCase.js b/src/deps/string/firstToLowerCase.js
new file mode 100644
index 0000000..46e4c1a
--- /dev/null
+++ b/src/deps/string/firstToLowerCase.js
@@ -0,0 +1,9 @@
+/**
+ * @name firstToLowerCase
+ * @since 2.0.0
+ * @memberOf string
+ * @param {string} str take first char to uppercase
+ * @return {string} str with uc first
+ * @example firstToLowerCase('EH') //=> 'eH'
+ */
+module.exports = str => str.charAt(0).toLowerCase() + str.slice(1)
diff --git a/src/deps/string/firstToUpperCase.js b/src/deps/string/firstToUpperCase.js
new file mode 100644
index 0000000..39d43d6
--- /dev/null
+++ b/src/deps/string/firstToUpperCase.js
@@ -0,0 +1,9 @@
+/**
+ * @name firstToUpperCase
+ * @since 2.0.0
+ * @memberOf string
+ * @param {string} str take first char to uppercase
+ * @return {string} str with uc first
+ * @example firstToUpperCase('eh') //=> 'Eh'
+ */
+module.exports = str => str.charAt(0).toUpperCase() + str.slice(1)
diff --git a/src/deps/string/hasUnicode.js b/src/deps/string/hasUnicode.js
new file mode 100644
index 0000000..e709e32
--- /dev/null
+++ b/src/deps/string/hasUnicode.js
@@ -0,0 +1,30 @@
+const matchUnicode = require('../regexp/matchUnicode')
+
+/**
+ * Checks if `string` contains Unicode symbols.
+ * @memberOf string
+ * @since 5.0.0-beta.5
+ *
+ * {@link https://github.com/lodash/lodash/blob/master/.internal/hasUnicode.js lodash-has-unicode}
+ * @see {@link lodash-has-unicode}
+ *
+ * @param {string} string The string to inspect.
+ * @return {boolean} Returns `true` if a symbol is found, else `false`.
+ *
+ * @example
+ *
+ * var λ = '\u03BB'
+ * hasUnicode(λ)
+ * //=> true
+ *
+ * @example
+ *
+ * hasUnicode('nope')
+ * //=> false
+ *
+ */
+function hasUnicode(string) {
+ return matchUnicode.test(string)
+}
+
+module.exports = hasUnicode
diff --git a/src/deps/string/index.js b/src/deps/string/index.js
new file mode 100644
index 0000000..38a1371
--- /dev/null
+++ b/src/deps/string/index.js
@@ -0,0 +1,3 @@
+/* istanbul ignore next: @docblocks @exports */
+
+module.exports = require('./string')
diff --git a/src/deps/string/match.js b/src/deps/string/match.js
new file mode 100644
index 0000000..0b1dd6e
--- /dev/null
+++ b/src/deps/string/match.js
@@ -0,0 +1,69 @@
+const curry = require('../fp/curry')
+const isIn = require('../is/in')
+const ENV_PERF = require('../env/preferPerf')
+const FROZEN_ARRAY = require('../native/EMPTY_ARRAY')
+// const SymbolMatch = require('../symbols/match')
+// const hasOwnProperty = require('../is/nullOrUndefined')
+
+// could use `EMPTY_ARRAY` but being frozen may mess the matches...
+// pre-initialized, can cause side-effects
+const emptyArr = ENV_PERF ? FROZEN_ARRAY : []
+
+/**
+ * Tests a regular expression against a String. Note that this function will
+ * return an empty array when there are no matches. This differs from
+ * [`String.prototype.match`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/match)
+ * which returns `null` when there are no matches.
+ *
+ * @since 5.0.0-beta.1
+ * @memberOf string
+ * @curried 2
+ *
+ * @param {RegExp} matchable A regular expression.
+ * @param {String} str The string to match against
+ * @return {Array} The list of matches or empty array.
+ *
+ * @see match/test
+ * @func
+ * @fork v0.1.0
+ * @category String
+ * @sig RegExp -> String -> [String | Undefined]
+ *
+ * {@link https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/String/match mozilla-string-match}
+ * @see {@link mozilla-string-match}
+ *
+ * @NOTE returned value from `match` is an ARRAY LIKE OBJECT
+ *
+ * @NOTE previously would throw
+ * match(/a/, null)
+ * //=> TypeError: null does not have a method named "match"
+ * now returns empty array if nill
+ *
+ *
+ * @example
+ *
+ * match(/([a-z]a)/g, 'bananas')
+ * //=> ['ba', 'na', 'na']
+ *
+ * match(/a/, 'b')
+ * //=> []
+ *
+ * @example
+ *
+ * var re = /foo/
+ * re[Symbol.match] = false
+ *
+ * '/foo/'.startsWith(re)
+ * //=> true
+ *
+ * '/baz/'.endsWith(re)
+ * //=> false
+ *
+ */
+function match(matchable, str) {
+ return isIn(str, 'match')
+ ? str.match(matchable) || emptyArr
+ : emptyArr
+}
+
+module.exports = curry(2, match)
diff --git a/src/deps/string/prefix.js b/src/deps/string/prefix.js
index aab9079..bbc118a 100644
--- a/src/deps/string/prefix.js
+++ b/src/deps/string/prefix.js
@@ -1,6 +1,7 @@
-const firstToUpper = str => str.charAt(0).toUpperCase() + str.slice(1)
+const firstToUpperCase = require('./firstToUpperCase')
-const addPrefix = (string, prefix) => prefix + firstToUpper(string)
+// pretty much camel-case here
+const addPrefix = (string, prefix) => prefix + firstToUpperCase(string)
function removePrefix(string, prefix) {
if (string.indexOf(prefix) === 0) string = string.slice(prefix.length)
@@ -8,7 +9,7 @@ function removePrefix(string, prefix) {
}
module.exports = {
- firstToUpper,
+ firstToUpperCase,
addPrefix,
removePrefix,
}
diff --git a/src/deps/string/quote.js b/src/deps/string/quote.js
new file mode 100644
index 0000000..6531e39
--- /dev/null
+++ b/src/deps/string/quote.js
@@ -0,0 +1,9 @@
+// const isStringPrimitive = require('../is/stringPrimitive')
+//
+// /**
+// * Converts a value to a string, adding quotes if a string was provided.
+// * @see https://github.com/facebook/immutable-js/blob/master/src/utils/quoteString.js
+// */
+// module.exports = function quoteString(x) {
+// return isStringPrimitive(x) ? JSON.stringify(x) : String(x)
+// }
diff --git a/src/deps/string/split.js b/src/deps/string/split.js
new file mode 100644
index 0000000..8a0dee7
--- /dev/null
+++ b/src/deps/string/split.js
@@ -0,0 +1,62 @@
+const ENV_PERF = require('../env/preferPerf')
+const FROZEN_ARRAY = require('../native/EMPTY_ARRAY')
+const MAX_ARRAY_LENGTH = require('../native/MAX_ARRAY_LENGTH')
+const stringToArray = require('../cast/stringToArray')
+const castSlice = require('../fp/slice')
+const isString = require('../is/stringPrimitive')
+const isRegExp = require('../is/regexp')
+const isUndefined = require('../is/undefined')
+const isNill = require('../is/nullOrUndefined')
+const hasUnicode = require('./hasUnicode')
+
+/**
+ * Splits `string` by `separator`.
+ * @symb 🤸
+ *
+ * @NOTE This method is based on
+ * [`String#split`](https://mdn.io/String/split).
+ *
+ * @curried 2
+ * @since 4.0.0
+ * @category String
+ *
+ *
+ * @param {string} [string=''] The string to split.
+ * @param {RegExp|string} separator The separator pattern to split by.
+ * @param {number} [limitArg] The length to truncate results to.
+ * @return {Array} Returns the string segments.
+ *
+ * @see http://speakingjs.com/es5/ch24.html
+ *
+ * @example
+ *
+ * split('a-b-c', '-', 2)
+ * //=> ['a', 'b']
+ *
+ */
+function split(string, separator, limitArg) {
+ const limit = isUndefined(limitArg) ? MAX_ARRAY_LENGTH : limitArg >>> 0
+
+ // @TODO EMPTY_ARRAY?
+ if (!limit) {
+ return ENV_PERF ? FROZEN_ARRAY : []
+ }
+
+ // split the unicode string into an array, then slice it
+ if (string &&
+ // isString, or nill && !regexp
+ (
+ isString(separator) ||
+ (isNill(separator) && !isRegExp(separator))
+ )
+ ) {
+ if (!separator && hasUnicode(string)) {
+ return castSlice(stringToArray(string), 0, limit)
+ }
+ }
+
+ // normal...
+ return string.split(separator, limit)
+}
+
+module.exports = split
diff --git a/src/deps/string/string.js b/src/deps/string/string.js
new file mode 100644
index 0000000..967f1ad
--- /dev/null
+++ b/src/deps/string/string.js
@@ -0,0 +1,31 @@
+/* istanbul ignore next: @docblocks @exports */
+
+const camelCase = require('./camelCase')
+const classNames = require('./classNames')
+const firstToUpperCase = require('./firstToUpperCase')
+const firstToLowerCase = require('./firstToLowerCase')
+const match = require('./match')
+const trim = require('./trim')
+const split = require('./split')
+const charCodeAtZero = require('./charCodeAtZero')
+const charCodeAt = require('./charCodeAt')
+const hasUnicode = require('./hasUnicode')
+// const quote = require('./quote')
+
+/**
+ * @symb 🎀
+ * @member string
+ * @type {Object}
+ */
+module.exports = {
+ camelCase,
+ classNames,
+ firstToUpperCase,
+ firstToLowerCase,
+ match,
+ trim,
+ split,
+ charCodeAtZero,
+ charCodeAt,
+ hasUnicode,
+}
diff --git a/src/deps/string/trim.js b/src/deps/string/trim.js
new file mode 100644
index 0000000..347d872
--- /dev/null
+++ b/src/deps/string/trim.js
@@ -0,0 +1,51 @@
+/**
+ * Removes (strips) whitespace from both ends of the string.
+ * @since 5.0.0-beta.5
+ * @memberOf string
+ * @symb ✂️
+ *
+ * @param {String} str The string to trim.
+ * @return {String} Trimmed version of `str`.
+ *
+ * @func
+ * @fork v0.6.0
+ * @category String
+ * @sig String -> String
+ *
+ * {@link https://github.com/processing-js/processing-js/blob/master/src/P5Functions/commonFunctions.js#L18 processing-js-trim}
+ * {@link https://github.com/madrobby/zepto/blob/master/src/zepto.js#L357 zepto-trim}
+ * {@link https://github.com/ramda/ramda/blob/master/src/trim.js ramda-trim}
+ * {@link https://github.com/lodash/lodash/blob/master/trim.js lodash-trim}
+ * @see {@link processing-js-trim}
+ * @see {@link lodash-trim}
+ * @see {@link ramda-trim}
+ * @see {@link zepto-trim}
+ *
+ * @example
+ *
+ * trim(' xyz ')
+ * //=> 'xyz'
+ *
+ * map(trim, split(',', 'x, y, z'))
+ * //=> ['x', 'y', 'z']
+ *
+ */
+module.exports = function trim(str /*, characters */) {
+ return str.trim()
+}
+
+// polyfill
+// (function() {
+// var ws = '\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003' +
+// '\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028' +
+// '\u2029\uFEFF'
+// var zeroWidth = '\u200b'
+// var hasProtoTrim = (typeof String.prototype.trim === 'function')
+// if (!hasProtoTrim || (ws.trim() || !zeroWidth.trim())) {
+// return _curry1(function trim(str) {
+// var beginRx = new RegExp('^[' + ws + '][' + ws + ']*')
+// var endRx = new RegExp('[' + ws + '][' + ws + ']*$')
+// return str.replace(beginRx, '').replace(endRx, '')
+// })
+// }
+// })()
diff --git a/src/deps/symbols/index.js b/src/deps/symbols/index.js
index 858e1a7..ccb5087 100644
--- a/src/deps/symbols/index.js
+++ b/src/deps/symbols/index.js
@@ -2,6 +2,10 @@
// const hasSymbol = typeof Symbol !== 'undefined'
// hasSymbol ? Symbol.iterator : 'Symbol(iterator)'
+/**
+ * @member symbol
+ * @icon 🔣
+ */
module.exports = {
Iterator: Symbol.iterator,
Primitive: Symbol.toPrimitive,
diff --git a/src/deps/symbols/match.js b/src/deps/symbols/match.js
new file mode 100644
index 0000000..196ba7d
--- /dev/null
+++ b/src/deps/symbols/match.js
@@ -0,0 +1,5 @@
+/**
+ * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/match mozilla-symbol-match}
+ * @see {@link mozilla-symbol-match}
+ */
+module.exports = Symbol.match
diff --git a/src/deps/symbols/toString.js b/src/deps/symbols/toString.js
new file mode 100644
index 0000000..84b5ee4
--- /dev/null
+++ b/src/deps/symbols/toString.js
@@ -0,0 +1,6 @@
+const always = require('../fp/always')
+
+/** Used to convert symbols to primitives and strings. */
+const symbolProto = Symbol ? Symbol.prototype : undefined
+
+module.exports = symbolProto ? symbolProto.toString : always('')
diff --git a/src/deps/symbols/toStringTag.js b/src/deps/symbols/toStringTag.js
new file mode 100644
index 0000000..4da0545
--- /dev/null
+++ b/src/deps/symbols/toStringTag.js
@@ -0,0 +1 @@
+module.exports = Symbol.toStringTag
diff --git a/src/deps/to-arr.js b/src/deps/to-arr.js
index 85cd452..489b057 100644
--- a/src/deps/to-arr.js
+++ b/src/deps/to-arr.js
@@ -7,6 +7,10 @@ const ArrayFrom = require('./util/from')
/**
* @desc anything into an array
+ * @memberOf cast
+ * @name toArr
+ * @alias toArray
+ *
* @sig * => Array
* @since 0.0.1
*
@@ -16,47 +20,53 @@ const ArrayFrom = require('./util/from')
* @tests deps/to-arr
* @types deps
*
+ * {@link https://github.com/jashkenas/underscore/blob/master/underscore.js#L465 underscore-to-arr}
+ * @see {@link underscore-to-arr}
+ *
* @example
*
* toarr([])
- * // => []
+ * //=> []
*
* toarr('')
- * // => ['']
+ * //=> ['']
*
* toarr('1,2')
- * // => ['1', '2']
+ * //=> ['1', '2']
*
* toarr('1,2')
- * // => ['1', '2']
+ * //=> ['1', '2']
*
* const map = new Map()
* map.set('eh', true)
* const arr = toarr(map.entries())
- * // => ['eh', true]
+ * //=> ['eh', true]
*
* const set = new Set()
* set.add('eh')
* set.add(true)
* const arr = toarr(map.entries())
- * // => ['eh', true]
+ * //=> ['eh', true]
*
* toarr('').concat(toarr(false)).concat(toarr(null))
- * // => ['', false, null]
+ * //=> ['', false, null]
*
*/
-module.exports = function(ar) {
+const toArray = function(ar) {
// @NOTE: !'' === true
if (isStringPrimitive(ar)) return ar.includes(',') ? ar.split(',') : [ar]
else if (!ar) return [ar]
else if (isArray(ar)) return ar
+ // hasIn(ar, 'values')
else if (isSet(ar) || isMap(ar) || ar.values) {
/**
* @desc when using `new Set().values`... no forEach o.o
- * .values is also on `Object`...
+ * @NOTE .values is also on `Object`...
*/
return ArrayFrom(ar.values(ar))
}
else if (isIterator(ar)) return ArrayFrom(ar)
else return [ar]
}
+
+module.exports = toArray
diff --git a/src/deps/traverse.js b/src/deps/traverse.js
index d161f0b..0be6a31 100644
--- a/src/deps/traverse.js
+++ b/src/deps/traverse.js
@@ -10,95 +10,40 @@
// debug conditionals
/* eslint max-depth: "OFF" */
-const isObjNotNull = require('./is/objNotNull')
-const isRegExp = require('./is/regexp')
-const isError = require('./is/error')
+const isEmpty = require('./is/empty')
const isTrue = require('./is/true')
-const isBoolean = require('./is/boolean')
-const isNumber = require('./is/number')
-const isString = require('./is/string')
-const isDate = require('./is/date')
+const isIteratable = require('./is/iteratable')
const isUndefined = require('./is/undefined')
-const isNullOrUndefined = require('./is/nullOrUndefined')
const isArray = require('./is/array')
const isMap = require('./is/map')
const isSet = require('./is/set')
-const isSymbol = require('./is/symbol')
-const isAsyncish = require('./is/asyncish')
-const isFunction = require('./is/function')
const isObj = require('./is/obj')
+const isPrimitive = require('./is/primitive')
+const isNull = require('./is/null')
const ObjectKeys = require('./util/keys')
-const hasOwnProperty = require('./util/hasOwnProperty')
-const toS = require('./is/toS')
const reduce = require('./reduce')
const toarr = require('./to-arr')
-const dot = require('./dot')
+const dotSet = require('./dot/set')
+const emptyTarget = require('./dopemerge/emptyTarget')
+const copy = require('./traversers/copy')
+const eq = require('./traversers/_eq')
+const addPoolingTo = require('./cache/pooler')
// const props = require('./util/props')
-// const emptyTarget = require('./dopemerge/emptyTarget')
+// const ENV_DEBUG = require('./env/debug')
// const ENV_DEBUG = true
+// const TRUTH = true
const ENV_DEBUG = false
-function isPrimitive(node) {
- return (
- isNullOrUndefined(node) ||
- isString(node) ||
- isNumber(node) ||
- isBoolean(node)
- )
-}
-function isIteratable(node) {
- // ez ones
- if (isObj(node) || isArray(node)) return true
-
- const notIteratable =
- isPrimitive(node) ||
- isRegExp(node) ||
- isDate(node) ||
- isSymbol(node) ||
- isAsyncish(node) ||
- // isNative(node) ||
- isError(node)
-
- if (notIteratable) return false
- else return true
-
- // if (isNullOrUndefined(node)) {
- // }
- // else if (isString(node)) {
- // }
- // else if (isNumber(node)) {
- // }
- // else if (isBoolean(node)) {
- // }
- // else if (isRegExp(node)) {
- // }
- // else if (isDate(node)) {
- // }
- // else if (isSymbol(node) || isAsyncish(node)) {
- // }
- // else if (isNative(node)) {
- // }
- // else {
- // return true
- // }
- // return false
-}
-
-// function isSpecial(x) {
-// // isPromise(x) ||
-// return isSymbol(x) || isError(x) ||
-// // || isGenerator(x)
-// }
-
/**
- * {@link https://github.com/wmira/object-traverse/blob/master/index.js }
- * {@link https://www.npmjs.com/browse/keyword/traverse }
- * {@link https://www.npmjs.com/package/tree-walk }
- * {@link https://www.npmjs.com/package/1tree }
- * {@link https://www.npmjs.com/package/pathway }
- * {@link https://www.npmjs.com/package/@mojule/tree }
- *
+ * {@link https://github.com/wmira/object-traverse/blob/master/index.js object-traverse}
+ * {@link https://www.npmjs.com/browse/keyword/traverse traverse-js}
+ * {@link https://www.npmjs.com/package/tree-walk tree-walk}
+ * {@link https://www.npmjs.com/package/1tree 1tree}
+ * {@link https://www.npmjs.com/package/pathway pathway}
+ * {@link https://www.npmjs.com/package/@mojule/tree tree}
+ * {@link http://web.archive.org/web/20160930054101/http://substack.net/tree_traversal tree-traversal-article}
+ * {@link https://medium.com/@alexanderv/tries-javascript-simple-implementation-e2a4e54e4330 js-trie-medium}
* --------------------
*
* if needed, clone
@@ -142,1110 +87,806 @@ function isIteratable(node) {
* @emits after
*/
-const isObjOrArr = x => isObj(x) || isArray(x)
-
-// need some thin wrapper around values to go up and down path
-//
-//
-// const ValueObject = {
-// node: value,
-// kind: typeof,
-// isRoot: false,
-// isLeaf: false,
-// isPrimitive: false,
-// branches: [],
-// isFirst: false,
-// isLast: false,
-// parent: {},
-// }
-//
-// class It {
-// constructor(x) {
-// // this.tree = {
-// // parent: {},
-// // }
-//
-// // this.root = x
-//
-// // this.previous = x
-// this.current = x
-//
-// this.depth = 0
-// this.all = new Set()
-// // this.path
-// // this.key
-// }
-//
-// get node() {
-// return this.current
-// }
-//
-// addBranch() {}
-//
-// // for updating
-// branchHead() {}
-//
-// goUp() {
-// this.depth--
-// }
-// goDown(current) {
-// this.parent = this.current
-// this.depth++
-// this.current = current
-// }
-// // not needed but conceptually
-// // goNext() {}
-//
-// find() {}
-// path() {}
-// }
-// const it = x => new It(x)
-
-// @TODO make this a trie OR a linked-list
-const makeIterator = () => {
+/**
+ * @desc Traverse class, pooled
+ * @modifies this.node
+ * @modifies this.parent
+ * @modifies this.root
+ * @since 5.0.0
+ *
+ * @member Traverse
+ * @class
+ * @constructor
+ * @alias IterAteOr
+ * @extends pooler
+ *
+ * @param {Traversable} iteratee value to iterate, clone, copy, check for eq
+ * @param {Object | undefined} [config] wip config for things such as events or configs
+ *
+ * @see {@link tree-traversal-article}
+ * @see traverse
+ * @TODO make this a trie OR a linked-list
+ *
+ * @tests traverse
+ * @types traverse
+ *
+ * @example
+ *
+ * new Traverse([1])
+ * new Traverse([], {})
+ *
+ */
+function Traverse(iteratee, config) {
// always cleared when done anyway
- // const parents = new Map()
- const parents = new Set()
- // const parentKeys = []
- const hasParent = (depth, value) => {
- if (!isObjOrArr(value)) return false
-
- // return Array.from(parents.values()).indexOf(value) !== -1
- // const keys = Array.from(parents.keys())
- // console.log('___pk', {keys})
- // for (let k = 0; k < keys.length; k++) {
- // const key = keys[k]
- // const matches =
- // depth.includes(key) || (key.includes && key.includes(depth))
- // console.log({key, matches, depth})
- // // .has(value)
- // if (matches) {
- // let has = false
- // parents.get(key).forEach(haz => {
- // if (value === haz) has = true
- // })
- // return has
- // }
- // }
-
- // for (let i = depth; i >= depth; i--) {
- // if (parents.get(i).has(value)) return true
- // }
-
- // return false
- return parents.has(value)
- }
- const addParent = (depth, value) => {
- if (!isObjOrArr(value)) return
- if (parents.size >= 100) parents.clear()
-
- // if (!parents.has(depth)) parents.set(depth, new Set())
- // parents.get(depth).add(value)
-
- parents.add(value)
- }
- // (isObjOrArr(value) ? parents.add(value) : parents.add(value))
- // const removeLastParent = () => parents.delete(lastParent)
- const clearParents = (depth, value) => parents.clear()
-
- // parents.forEach(parent => (parent.has(value) ? parent.delete(value) : null))
- // parents.delete(value)
- const removeParent = (depth, value) => parents.delete(value)
-
- // const pps = []
- // const ppHas = value => {
- // for (let i = 0; i < pps.length; i++) {
- // if (pps[i] === value) {
- // return true
- // }
- // }
- // }
- // const ppAdd = value => pps.push(value)
- // const ppPop = () => pps.pop()
-
- /**
- * @param {Traversable} iteratee
- * @param {Object | undefined} [config] wip config for things such as events or configs
- * @constructor
- */
- function ItOrAteOr(iteratee, config) {
- this.iteratee = iteratee
- this.parent = iteratee
- this.root = iteratee
- // this.tree = it(iteratee)
-
- this.path = []
-
- // @HACK @FIXME @TODO remove, not needed, compat
- // this.path = this.path
-
- this.key = undefined
+ if (isUndefined(this.parents)) this.parents = new Set()
- this.isAlive = true
- this.isCircular = false
- this.isLeaf = false
- this.isRoot = true
+ this.node = iteratee
+ this.parent = iteratee
+ this.root = iteratee
+ this.reset()
- // iterates +1 so start at 0
- this.depth = -1
-
- // to pass in the events (as commented below) without messing up scope?
- // if (config.on) this.on = config.on
- return this
- }
-
- ItOrAteOr.prototype.forEach = function iterateForEach(cb) {
- /* istanbul ignore next: dev */
- if (ENV_DEBUG) {
- console.log('\n forEach \n')
- }
+ // to pass in the events (as commented below) without messing up scope?
+ // if (config.on) this.on = config.on
+ return this
+}
- const result = this.iterate(cb)
+/**
+ * @desc reset the properties when finished pooling or instantiating
+ * @since 5.0.0
+ * @method
+ *
+ * @memberOf Traverse
+ * @modifies Traverse.path
+ * @modifies Traverse.key
+ * @modifies Traverse.isAlive
+ * @modifies Traverse.isCircular
+ * @modifies Traverse.isLeaf
+ * @modifies Traverse.isRoot
+ * @modifies Traverse.depth
+ * @return {void}
+ *
+ * @example
+ * traverse([]).reset()
+ */
+Traverse.prototype.reset = function() {
+ this.path = []
+ this.key = undefined
+ this.isAlive = true
+ this.isCircular = false
+ this.isLeaf = false
+ this.isRoot = true
+
+ // iterates +1 so start at 0
+ this.depth = -1
+}
- // TODO: HERE, WHEN THIS IS ADDED, CAN BREAK SOME TESTS? SCOPED PARENTS MAP?
- this.done()
+/**
+ * @desc find parent,
+ * is there a parent
+ * above the current depth
+ * with the same value,
+ * making it circular?
+ *
+ * @memberOf Traverse
+ * @since 5.0.0
+ * @private
+ * @method
+ *
+ * @param {number} depth current depth, to find parent >=
+ * @param {parent} value parent value to find
+ * @return {boolean} hasParent
+ *
+ * @example
+ *
+ * var obj = {eh: ['eh']}
+ * traverse(obj).addParent(0, obj)
+ *
+ */
+Traverse.prototype.hasParent = function(depth, value) {
+ // or array
+ return isObj(value) ? this.parents.has(value) : false
+}
- return result
- }
+/**
+ * @desc add parent, to prevent circular iterations
+ * @memberOf Traverse
+ * @since 5.0.0
+ * @private
+ * @method
+ *
+ * @param {number} depth current depth, to add parent to >=
+ * @param {parent} value parent value to add
+ * @return {void}
+ *
+ * @example
+ *
+ * var obj = {eh: ['eh']}
+ * traverse(obj).addParent(0, obj)
+ *
+ */
+Traverse.prototype.addParent = function(depth, value) {
+ // && this.hasParent(value) === false
+ if (isObj(value)) this.parents.add(value)
+}
- /**
- * @modifies this.isAlive = false
- *
- * @return {void}
- *
- * @example
- *
- * traverse({eh: true, arr: []}).forEach((key, val, t) => {
- * if (isArray(val)) this.stop()
- * })
- *
- */
- ItOrAteOr.prototype.stop = function stop() {
- this.isAlive = false
- // this.done()
- }
+/**
+ * @desc remove all parents, reset the map
+ *
+ * @memberOf Traverse
+ * @since 5.0.0
+ * @private
+ * @method
+ *
+ * @return {void}
+ *
+ * @example
+ *
+ * var obj = {eh: ['eh']}
+ * traverse(obj).forEach((key, value, t) => {
+ * t.parents
+ * //=> Set([obj])
+ * t.clear()
+ * t.parents
+ * //=> Set[]
+ * })
+ *
+ */
+Traverse.prototype.clear = function() {
+ // if (!isUndefined(this.parents))
+ this.parents.clear()
+}
- /**
- * @TODO skip 1 branch
- * @return {void}
- */
- ItOrAteOr.prototype.skip = function skip() {
- this.skipBranch = true
- }
+/**
+ * @memberOf Traverse
+ * @since 5.0.0
+ * @private
+ * @method
+ *
+ * @param {number} depth current depth, to find parents >=
+ * @param {parent} value parent value to remove
+ * @return {void}
+ *
+ * @example
+ *
+ * var obj = {eh: ['eh']}
+ * traverse(obj).removeParent(0, obj)
+ *
+ */
+Traverse.prototype.removeParent = function(depth, value) {
+ this.parents.delete(value)
+}
- /* prettier-ignore */
- /**
- * @TODO move into the wrapper? if perf allows?
- *
- * @desc checks whether a node is iteratable
- * @modifies this.isIteratable
- * @modifies this.isLeaf
- * @modifies this.isCircular
- *
- * @protected
- *
- * @param {*} node value to check
- * @return {void}
- *
- * @example
- *
- * .checkIteratable({eh: true})
- * //=> this.isLeaf = false
- * //=> this.isCircular = false
- * //=> this.isIteratable = true
- *
- * .checkIteratable({} || [])
- * //=> this.isLeaf = true
- * //=> this.isCircular = false
- * //=> this.isIteratable = false
- *
- * var circular = {}
- * circular.circular = circular
- * .checkIteratable(circular)
- * //=> this.isLeaf = false
- * //=> this.isCircular = true
- * //=> this.isIteratable = true
- *
- */
- ItOrAteOr.prototype.checkIteratable = function check(node) {
- this.isIteratable = isIteratable(node)
- // just put these as an array?
- if (isTrue(this.isIteratable)) {
- // native = leaf if not root
- this.isLeaf = false
-
- if (hasParent(this.path.join('.'), node)) {
- /* istanbul ignore next: dev */
- if (ENV_DEBUG) {
- console.log('circular___________', {node, path: this.path})
- }
- this.isCircular = true
- }
- // else if (ppHas(node)) {
- // if (ENV_DEBUG) {
- // console.log('PPHAS!!!!!!!!!!!', {node, path: this.path})
- // }
- // this.isCircular = true
- // }
- else {
- addParent(this.path.join('.'), node)
- this.isCircular = false
- }
- }
- else {
- // ---
- this.isLeaf = true
- this.isCircular = false
- }
+/**
+ * @desc this is the main usage of Traverse
+ * @memberOf Traverse
+ * @since 3.0.0
+ * @version 5.0.0
+ * @method
+ *
+ * @param {Function} cb callback for each iteration
+ * @return {*} mapped result or original value, depends how it is used
+ *
+ * @example
+ *
+ * traverse([1, 2, 3]).forEach((key, value) => console.log({[key]: value}))
+ * //=> {'0': 1}
+ * //=> {'1': 2}
+ * //=> {'2': 3}
+ *
+ */
+Traverse.prototype.forEach = function iterateForEach(cb) {
+ /* istanbul ignore next: dev */
+ if (ENV_DEBUG) {
+ console.log('\n forEach \n')
}
- /* prettier-ignore */
- /**
- * Remove the current element from the output.
- * If the node is in an Array it will be spliced off.
- * Otherwise it will be deleted from its parent.
- *
- * @since 2.0.0
- * @param {undefined | Object} [arg] optional obj to use, defaults to this.iteratee
- * @return {void}
- *
- * @example
- *
- * traverse([0]).forEach((key, val, it) => it.remove())
- * //=> []
- *
- */
- ItOrAteOr.prototype.remove = function removes(arg) {
- let obj = arg || this.iteratee
-
- /* istanbul ignore next: dev */
- if (ENV_DEBUG) {
- console.log({parent: this.parent})
- }
+ const result = this.iterate(cb)
- removeParent(obj)
+ // TODO: HERE, WHEN THIS IS ADDED, CAN BREAK SOME TESTS? SCOPED PARENTS MAP?
+ Traverse.release(this)
- if (isUndefined(obj)) {
- // throw new Error('why?')
- }
- else if (isArray(obj)) {
- /* istanbul ignore next: dev */
- if (ENV_DEBUG) {
- console.log('traverse:remove:array', obj, this.key)
- }
+ return result
+}
- obj.splice(this.key, 1)
- }
- else if (isObjNotNull(obj)) {
- /* istanbul ignore next: dev */
- if (ENV_DEBUG) {
- console.log('traverse:remove:obj', this.key)
- }
+/**
+ * @desc stop the iteration
+ * @modifies this.isAlive = false
+ * @memberOf Traverse
+ * @method
+ *
+ * @return {void}
+ *
+ * @example
+ *
+ * traverse({eh: true, arr: []}).forEach((key, val, t) => {
+ * if (isArray(val)) this.stop()
+ * })
+ *
+ */
+Traverse.prototype.stop = function stop() {
+ this.isAlive = false
+ // this.release()
+}
- delete obj[this.key]
- }
+/**
+ * @TODO skip 1 branch
+ * @version 5.0.0
+ * @since 3.0.0
+ * @memberOf Traverse
+ * @method
+ *
+ * @return {void}
+ *
+ * @example
+ *
+ * traverse([1, 2, 3, [4]]).forEach((key, val, t) => {
+ * if (isArray(val)) t.skip()
+ * })
+ *
+ */
+Traverse.prototype.skip = function skip() {
+ this.skipBranch = true
+}
- if (isObjNotNull(this.parent)) {
- delete this.parent[this.key]
+/* prettier-ignore */
+/**
+ * @desc checks whether a node is iteratable
+ * @modifies Traverse.isIteratable
+ * @modifies Traverse.isLeaf
+ * @modifies Traverse.isCircular
+ *
+ * @memberOf Traverse
+ * @protected
+ * @method
+ *
+ * @param {*} node value to check
+ * @return {void}
+ *
+ * @TODO move into the wrapper? if perf allows?
+ *
+ * @example
+ *
+ * .checkIteratable({eh: true})
+ * //=> this.isLeaf = false
+ * //=> this.isCircular = false
+ * //=> this.isIteratable = true
+ *
+ * .checkIteratable({} || [])
+ * //=> this.isLeaf = true
+ * //=> this.isCircular = false
+ * //=> this.isIteratable = false
+ *
+ * var circular = {}
+ * circular.circular = circular
+ * .checkIteratable(circular)
+ * //=> this.isLeaf = false
+ * //=> this.isCircular = true
+ * //=> this.isIteratable = true
+ *
+ */
+Traverse.prototype.checkIteratable = function check(node) {
+ this.isIteratable = isIteratable(node)
+ // just put these as an array?
+ if (isTrue(this.isIteratable)) {
+ // native = leaf if not root
+ this.isLeaf = false
+ const path = this.path.join('.')
+ if (this.hasParent(path, node)) {
/* istanbul ignore next: dev */
if (ENV_DEBUG) {
- console.log('traverse:remove:parent', this.key)
+ console.log('circular___________', {node, path: this.path})
}
+ this.isCircular = true
}
- if (isObjNotNull(this.iteratee)) {
- delete this.iteratee[this.key]
-
- /* istanbul ignore next: dev */
- if (ENV_DEBUG) {
- console.log('traverse:remove:iteratee', this.key)
- }
+ else {
+ this.addParent(path, node)
+ this.isCircular = false
}
/* istanbul ignore next: dev */
if (ENV_DEBUG) {
- console.log('traverse:remove:', this.key, {obj, iteratee: this.iteratee})
+ // console.log('IS_CIRCULAR_JSON', isCircular(node), this.isCircular, node)
}
}
-
- /**
- * @desc update the value for the current key
- * @since 2.0.0
- *
- * @param {*} value this.iteratee[this.key] = value
- * @return {void}
- *
- * @example
- *
- * traverse({eh: true})
- * .forEach((key, val, traverser) => {
- * if (this.isRoot) return
- * traverser.update(false)
- * })
- * //=> {eh: false}
- *
- */
- ItOrAteOr.prototype.update = function update(value) {
- // if (!isUndefined(this.iteratee)) {
- // this.iteratee[this.key] = value
- // }
- // // dot.set(this.iteratee, this.key, value)
- dot.set(this.root, this.path, value)
- // dot.set(this.iteratee, this.path, value)
-
- // dot.set(this.iteratee, this.key, value)
- // console.log({traverser: this})
-
- // @NOTE think about this more, but updating can change structure
- // if (isTrue(clear)) clearParents()
+ else {
+ this.isLeaf = true
+ this.isCircular = false
}
+}
- ItOrAteOr.prototype.clear = clearParents
-
- ItOrAteOr.prototype.done = function done() {
- // throw new Error('how')
- // this.iteratee = undefined
- // this.key = undefined
- // this.isCircular = undefined
- // this.isLeaf = undefined
- // this.isAlive = undefined
- // this.path = undefined
+/* prettier-ignore */
+/**
+ * Remove the current element from the output.
+ * If the node is in an Array it will be spliced off.
+ * Otherwise it will be deleted from its parent.
+ *
+ * @memberOf Traverse
+ * @version 5.0.0
+ * @since 2.0.0
+ * @method
+ *
+ * @param {undefined | Object} [arg] optional obj to use, defaults to this.node
+ * @return {void}
+ *
+ * @example
+ *
+ * traverse([0]).forEach((key, val, it) => it.remove())
+ * //=> []
+ *
+ * traverse({eh: true}).forEach((key, val, it) => it.remove())
+ * //=> {}
+ *
+ * traverse({eh: true, str: 'stringy'}).forEach((key, val, it) => {
+ * if (!isString(val)) it.remove()
+ * })
+ * //=> {str: 'stringy'}
+ *
+ */
+Traverse.prototype.remove = function removes(arg) {
+ // ignore undefined & non-object/arrays
+ if (isUndefined(this.key)) return
+ let obj = arg || this.node
+ if (!isObj(obj)) return
- clearParents()
+ /* istanbul ignore next: dev */
+ if (ENV_DEBUG) {
+ console.log('remove')
+ console.log({parent: this.parent, key: this.key, obj})
}
- /* prettier-ignore */
- /**
- * @TODO handler for Set & Map so they can be skipped or traversed, for example when cloning...
- * @TODO add hook to add custom checking if isIteratable
- * @TODO deal with .isRoot if needed
- * @TODO examples with clone and stop
- *
- * @sig on(key: null | Primitive, val: any, instance: Traverse): any
- *
- * @param {Function} on callback fn for each iteration
- * @return {*} this.iteratee
- *
- * @example
- *
- * iterate([])
- * //=> []
- * //=> on(null, [])
- *
- * @example
- *
- * iterate([1])
- * //=> [1]
- * //=> on(null, [1])
- * //=> on('1', 1)
- *
- * @example
- * //primitive - same for any number, string, symbol, null, undefined
- * iterate(Symbol('eh'))
- * //=> Symbol('eh')
- * //=> on(Symbol('eh'))
- *
- * @example
- *
- * var deeper = {eh: 'canada', arr: [{moose: true}, 0]}
- * iterate(deeper)
- * //=> deeper // returns
- * //=> on(null, deeper, this) // root
- *
- * //=> on('eh', 'canada', this) // 1st branch
- *
- * //=> on('arr', [{moose: true}, 0], this)
- * //=> on('arr.0', [{moose: true}], this)
- * //=> on('arr.0.moose', true, this)
- * //=> on('arr.1', [0], this)
- *
- *
- */
- ItOrAteOr.prototype.iterate = function iterate(on) {
- // require('fliplog').bold(this.path.join('.')).data(parents).echo()
- // require('fliplog').bold(this.path.join('.')).data(parents.keys()).echo()
-
- /* istanbul ignore next : dev */
- if (ENV_DEBUG) {
- console.log('\n...iterate...\n')
- }
-
- if (parents.size >= 100) {
- clearParents()
- }
-
- if (this.isAlive === false) {
- /* istanbul ignore next : dev */
- if (ENV_DEBUG) {
- console.log('DEAD')
- }
+ this.removeParent(obj)
+ this.skip()
- return this.done()
- }
+ delete obj[this.key]
+ delete this.parent[this.key]
- let node = this.iteratee
-
- // convert to iteratable
- if (isMap(node)) {
- node = reduce(node)
- }
- else if (isSet(node)) {
- node = toarr(node)
- }
+ /* istanbul ignore next: dev */
+ if (ENV_DEBUG) {
+ console.log('traverse:remove:', this.key, {obj, iteratee: this.node})
+ }
+}
- // @TODO: maybe only right before sub-loop
- addParent(this.depth, node)
- // ppAdd(node)
+/**
+ * @desc update the value for the current key
+ * @version 5.0.0
+ * @since 2.0.0
+ * @memberOf Traverse
+ *
+ * @param {*} value this.node[this.key] = value
+ * @return {void}
+ *
+ * @example
+ *
+ * traverse({eh: true})
+ * .forEach((key, val, traverser) => {
+ * if (this.isRoot) return
+ * traverser.update(false)
+ * })
+ * //=> {eh: false}
+ *
+ */
+Traverse.prototype.update = function update(value) {
+ dotSet(this.root, this.path, value)
+}
- const nodeIsArray = isArray(node)
- const nodeIsObj = nodeIsArray || isObj(node)
+/**
+ * @desc mark the iteration as done, clear the map
+ * @NOTE this recycles the instance in the pooler to re-use allocated objects
+ * @memberOf Traverse
+ * @private
+ * @since 5.0.0
+ *
+ * @return {void}
+ *
+ * @see Traverse.iterate
+ *
+ * @example
+ *
+ * traverse([]).destructor()
+ *
+ */
+Traverse.prototype.destructor = function destructor() {
+ this.node = undefined
+ this.parent = undefined
+ this.reset()
- // ---
+ this.clear()
+}
- // @event
- if (!isUndefined(this.onBefore)) {
- // eslint-disable-next-line no-useless-call
- this.onBefore(this)
- }
+/* prettier-ignore */
+/**
+ * @TODO handler for Set & Map so they can be skipped or traversed, for example when cloning...
+ * @TODO add hook to add custom checking if isIteratable
+ * @TODO deal with .isRoot if needed
+ * @TODO examples with clone and stop
+ *
+ * @memberOf Traverse
+ * @protected
+ * @sig on(key: null | Primitive, val: any, instance: Traverse): any
+ *
+ * @param {Function} on callback fn for each iteration
+ * @return {*} this.node
+ *
+ * @example
+ *
+ * iterate([])
+ * //=> []
+ * //=> on(null, [])
+ *
+ * @example
+ *
+ * iterate([1])
+ * //=> [1]
+ * //=> on(null, [1])
+ * //=> on('1', 1)
+ *
+ * @example
+ *
+ * //primitive - same for any number, string, symbol, null, undefined
+ * iterate(Symbol('eh'))
+ * //=> Symbol('eh')
+ * //=> on(Symbol('eh'))
+ *
+ * @example
+ *
+ * var deeper = {eh: 'canada', arr: [{moose: true}, 0]}
+ * iterate(deeper)
+ * //=> deeper // returns
+ * //=> on(null, deeper, this) // root
+ *
+ * //=> on('eh', 'canada', this) // 1st branch
+ *
+ * //=> on('arr', [{moose: true}, 0], this)
+ * //=> on('arr.0', [{moose: true}], this)
+ * //=> on('arr.0.moose', true, this)
+ * //=> on('arr.1', [0], this)
+ *
+ *
+ */
+Traverse.prototype.iterate = function iterate(on) {
+ /* istanbul ignore next : dev */
+ if (ENV_DEBUG) {
+ // require('fliplog')
+ // .bold(this.path.join('.'))
+ // .data(parents.keys())
+ // .echo()
+ console.log('\n...iterate...\n')
+ }
+ if (this.isAlive === false) {
/* istanbul ignore next : dev */
if (ENV_DEBUG) {
- // const str = require('pretty-format')({nodeIsObj, nodeIsArray, node})
- // require('fliplog').verbose(1).data({nodeIsObj, nodeIsArray, node}).echo()
- // console.log(node, parents)
- // console.log(str)
- console.log({nodeIsObj, nodeIsArray, node})
- }
-
- /**
- * call as root, helpful when we
- * - iterate something with no keys
- * - iterate a non-iteratable (symbol, error, native, promise, etc)
- */
- if (isTrue(this.isRoot)) {
- on.call(this, null, node, this)
- this.isRoot = false
- }
-
-
- // --------------------
- // IF OBJWITHOUTKEYS, IF ARRAY WITHOUT LENGTH...
- if (nodeIsArray && node.length === 0) {
- on.call(this, this.key, node, this)
- this.iteratee = node
- }
- else if (nodeIsObj && ObjectKeys(node).length === 0) {
- // eqValue(node, )
- on.call(this, this.key, node, this)
- this.iteratee = node
+ console.log('DEAD')
}
- // --------------------
-
- else if (nodeIsObj || nodeIsArray) {
- this.depth = this.path.length
-
- // if (isTrue(this.isRoot)) this.isRoot = false
-
- // @TODO SAFETY WITH `props(node)` <- fixes Error
- let keys = nodeIsArray ? node : ObjectKeys(node)
-
- /* istanbul ignore next : dev */
- if (ENV_DEBUG) {
- console.log({keys})
- // require('fliplog').verbose(1).data(this).echo()
- }
-
- // @event
- // if (!isUndefined(this.onBefore)) this.onBefore()
-
- // @NOTE: safety here
- // this.checkIteratable(node)
- // const last = keys[keys.length - 1]
-
- // @loop
- for (let key = 0; key < keys.length; key++) {
- // --- safety ---
- if (this.isAlive === false) {
- /* istanbul ignore next : dev */
- if (ENV_DEBUG) {
- console.log('DEAD')
- }
+ return Traverse.release(this)
+ }
- return this.done()
- }
+ let node = this.node
- // @NOTE: look above add prev add parent
- // addParent(this.depth, node)
- // ppAdd(node)
+ // convert to iteratable
+ if (isMap(node)) {
+ node = reduce(node)
+ }
+ else if (isSet(node)) {
+ node = toarr(node)
+ }
+ // @TODO: maybe only right before sub-loop
+ this.addParent(this.depth, node)
- // ----- setup our data ----
+ const nodeIsArray = isArray(node)
+ const nodeIsObj = nodeIsArray || isObj(node)
- // to make it deletable
- if (node !== this.iteratee) this.parent = node
+ // ---
- this.key = nodeIsArray ? key : keys[key]
- // this.isLast = key === last
+ // @event
+ if (!isUndefined(this.onBefore)) {
+ // eslint-disable-next-line no-useless-call
+ this.onBefore(this)
+ }
- /* istanbul ignore next: dev */
- if (ENV_DEBUG) {
- console.log('alive', this.key)
- }
+ /* istanbul ignore next : dev */
+ if (ENV_DEBUG) {
+ // const str = require('pretty-format')({nodeIsObj, nodeIsArray, node})
+ // require('fliplog').verbose(1).data({nodeIsObj, nodeIsArray, node}).echo()
+ // console.log(node, parents)
+ // console.log(str)
+ console.log({nodeIsObj, nodeIsArray, node})
+ }
- // @event
- if (!isUndefined(this.onPre)) {
- // eslint-disable-next-line no-useless-call
- this.onPre(this)
- }
+ /**
+ * call as root, helpful when we
+ * - iterate something with no keys
+ * - iterate a non-iteratable (symbol, error, native, promise, etc)
+ */
+ if (isTrue(this.isRoot)) {
+ on.call(this, null, node, this)
+ this.isRoot = false
+ }
+ const isObjOrArray = nodeIsArray || nodeIsObj
- const value = node[this.key]
+ // if (isObjOrArray) {
+ // // @event
+ // if (!isUndefined(this.onBefore)) {
+ // // eslint-disable-next-line no-useless-call
+ // this.onBefore(this)
+ // }
+ // }
- this.checkIteratable(value)
- // addParent(value)
- const pathBeforeNesting = this.path.slice(0)
+ // --------------------
+ // IF OBJWITHOUTKEYS, IF ARRAY WITHOUT LENGTH...
+ if (isObjOrArray && isEmpty(node)) {
+ on.call(this, this.key, node, this)
+ this.node = node
+ }
- // @NOTE: can go forward-backwards if this is after the nested iterating
- this.path.push(this.key)
- this.depth = this.path.length
+ // --------------------
- // ----- continue events, loop deeper when needed ----
+ else if (isObjOrArray) {
+ this.depth = this.path.length
- on.call(this, this.key, value, this)
+ // @TODO SAFETY WITH `props(node)` <- fixes Error
+ let keys = nodeIsArray ? node : ObjectKeys(node)
- /* istanbul ignore next: dev */
- if (ENV_DEBUG) {
- // require('fliplog').data(parents).echo()
- // require('fliplog').data(this).echo()
- }
+ /* istanbul ignore next : dev */
+ if (ENV_DEBUG) {
+ console.log({keys})
+ // require('fliplog').verbose(1).data(this).echo()
+ }
- // handle data
- if (isTrue(this.isCircular)) {
- /* istanbul ignore next: dev */
- if (ENV_DEBUG) {
- console.log('(((circular)))', this.key)
- }
-
- // on.call(this, this.key, value, this)
- // this.path.pop()
- this.path = pathBeforeNesting
-
- // this.isCircular = false
- // break
- continue
- // return
- }
+ // @event
+ // if (!isUndefined(this.onBefore)) this.onBefore()
+ // @NOTE: safety here
+ // this.checkIteratable(node)
- // &&
- if (isTrue(this.isIteratable)) {
- /* istanbul ignore next: dev */
- if (ENV_DEBUG) {
- console.log('(((iteratable)))', this.key)
- }
+ // const last = keys[keys.length - 1]
- this.iteratee = value
- this.iterate(on)
- this.path = pathBeforeNesting
- }
+ // @loop
+ for (let key = 0; key < keys.length; key++) {
+ // if (ENV_DEBUG)
+ // console.log('iterating:', {key})
- /* istanbul ignore next: dev */
+ // --- safety ---
+ if (this.isAlive === false) {
+ /* istanbul ignore next : dev */
if (ENV_DEBUG) {
- if (this.isIteratable === false) {
- console.log('not iteratable', this.key)
- }
+ console.log('DEAD')
}
-
- // console.log('----------------- post ----------', node)
-
-
- // @event
- if (!isUndefined(this.onPost)) {
- // eslint-disable-next-line no-useless-call
- this.onPost(this)
- }
-
- // cleanup, backup 1 level
- this.path.pop()
-
- // ppPop()
- removeParent(node)
+ return Traverse.release(this)
}
- // this.path.pop()
- this.depth = this.path.length
- }
- else {
- // this.isLast = false
- on.call(this, this.depth, node, this)
- }
+ // @NOTE: look above add prev add parent
+ // addParent(this.depth, node)
- // @NOTE: careful
- // removeParent(node)
- // @NOTE: just for .after ?
- this.iteratee = node
+ // ----- setup our data ----
- // @event
- if (!isUndefined(this.onAfter)) {
- // eslint-disable-next-line no-useless-call
- this.onAfter(this)
- }
+ // to make it deletable
+ if (node !== this.node) this.parent = node
- this.path.pop()
+ this.key = nodeIsArray ? key : keys[key]
+ // this.isLast = key === last
- return this.iteratee
- }
-
- // is smaller
- // function onEvent(property) {
- // return function(fn) {
- // this[property] = function
- // }
- // }
- // when it's some sort of itertable object, loop it further
- // @TODO: need to handle these better without totally messing with bad scope
- ItOrAteOr.prototype.pre = function(fn) {
- this.onPre = fn
- }
- ItOrAteOr.prototype.post = function(fn) {
- this.onPost = fn
- }
- ItOrAteOr.prototype.before = function(fn) {
- this.onBefore = fn
- }
- ItOrAteOr.prototype.after = function(fn) {
- this.onAfter = fn
- }
-
- // -----------------------
-
- /**
- * @TODO merge with dopemerge?
- * @TODO needs tests converted back for this (observe tests do cover somewhat)
- *
- * @param {*} arg defaults to this.iteratee
- * @return {*} cloned
- *
- * @example
- *
- * var obj = {}
- * var cloned = traverse().clone(obj)
- * obj.eh = true
- * eq(obj, cloned)
- * //=> false
- *
- */
- ItOrAteOr.prototype.clone = clone
-
- /**
- * @todo ugh, how to clone better with *recursive* objects?
- * @param {any} src wip
- * @return {any} wip
- */
- ItOrAteOr.prototype.copy = copy
-
- // end factory
- return ItOrAteOr
-}
-
-/* prettier-ignore */
-function copy(src) {
- if (isObjNotNull(src)) {
- let dst
-
- // if (isPrimitive(src)) {
- // if (isNullOrUndefined(src)) {
- // dst = src
- // }
-
- // @TODO @IMPORTANT @FIXME @!IMPORTANT - COVER THIS OR NOT?
- // for string value number boolean objects...
- // if (isString(src)) {
- // dst = src + ''
- // }
- // else if (isNumber(src)) {
- // dst = src + 0
- // }
- // else if (isBoolean(src)) {
- // dst = !!src
- // }
- // else
-
- // lists... <- needs to have dot-prop support on Map/Set
- // if (isMap(src)) {
- // dst = new Map()
- // const obj = reduce(src)
- // // src.clear()
- // ObjectKeys(obj).forEach(key => dst.set(key, obj[key]))
- // return dst
- // }
- // else if (isSet(src)) {
- // dst = new Set()
- // // could clone here too
- // const obj = toarr(src)
- // // src.clear()
- // obj.forEach(value => dst.add(value))
- // return dst
- // }
-
- // ------
- if (isArray(src)) {
- dst = []
- }
- else if (isDate(src)) {
- dst = new Date(src.getTime ? src.getTime() : src)
- }
- else if (isRegExp(src)) {
- dst = new RegExp(src)
- }
- else if (isError(src)) {
- dst = new Error(src.message)
- dst.stack = src.stack
- }
- else {
- dst = Object.create(Object.getPrototypeOf(src))
- }
-
- // @TODO: copy descriptor
- // eslint-disable-next-line
- for (var prop in src) {
- dst[prop] = src
- // const desc = Object.getOwnPropertyDescriptor(src, prop)
- // Object.defineProperty(dst, prop, desc)
- }
- return dst
- }
- else {
- // require('fliplog').red('is NOT OBJ').echo()
- return src
- }
-}
-
-function clone(arg) {
- const obj = isUndefined(arg) ? this.iteratee : arg
- if (isPrimitive(obj)) return obj
- let cloned = isArray(obj) ? [] : {}
- let current = cloned
+ /* istanbul ignore next: dev */
+ if (ENV_DEBUG) {
+ console.log('alive', this.key)
+ }
- traverse(obj).forEach((key, value, traverser) => {
- // t.isRoot
- if (key === null) return
- // require('fliplog').bold(key).data({value, traverser, current}).echo()
- // if (isSet(value)) {
- // const copied = copy(value)
- // dot.set(current, traverser.path, copied)
- //
- // // require('fliplog')
- // // .red('copy:')
- // // .data({value, path: traverser.path, current, copied})
- // // .exit()
- // }
+ // @event
+ if (!isUndefined(this.onPre)) {
+ // eslint-disable-next-line no-useless-call
+ this.onPre(this)
+ }
- let copied = copy(value)
- if (traverser.isCircular && isArray(value)) copied = value.slice(0)
- dot.set(current, traverser.path, copied)
- // current[key] = traverser.copy(value)
- // if (isObj(value)) current = current[key]
- })
+ const value = node[this.key]
- return cloned
-}
+ this.checkIteratable(value)
+ // addParent(value)
+ const pathBeforeNesting = this.path.slice(0)
-/* prettier-ignore */
-/**
- * @since 4.1.0
- *
- * @protected
- * @TODO !!!!!! USE ENUM FLAGS ON LOOSE TO ALLOW MORE CONFIG FOR ==, COMPARATOR, VALUEOF, walk proto (check ownProps...)...
- *
- * @param {*} x compare to y
- * @param {*} y compare to x
- * @param {boolean | number} [loose=false] use == checks when typof !=
- * @return {boolean}
- *
- * @example
- * eqValue(1, 1) //=> true
- * eqValue('1', 1) //=> false
- * eqValue('1', 1, true) //=> true
- * eqValue({}, {}) //=> true
- */
-function eqValue(x, y, loose) {
- /* istanbul ignore next: dev */
- if (ENV_DEBUG) {
- console.log('eqValue', {x, y, loose})
- }
-
- // if (x === y) {
- // if (ENV_DEBUG) {
- // console.log('===', {x, y})
- // }
- // // noop
- // }
- // else
+ // @NOTE: can go forward-backwards if this is after the nested iterating
+ this.path.push(this.key)
+ this.depth = this.path.length
- if (isNullOrUndefined(x) || isNullOrUndefined(y)) {
- /* istanbul ignore next: dev */
- if (ENV_DEBUG) {
- console.log('null or undef !=', {x, y})
- }
+ // ----- continue events, loop deeper when needed ----
- if (x !== y) {
- return false
- }
- }
- else if (typeof x !== typeof y) {
- // eslint-disable-next-line
- if (isTrue(loose) && x == y) {
- // ignore
- }
- else {
- /* istanbul ignore next: dev */
- if (ENV_DEBUG) {
- console.log('typeof !=', {x, y})
+ // @NOTE since we check isAlive at the beginning of each loop
+ // could use .skip alongisde .stop
+ // @TODO @IMPORTANT @HACK @FIXME right here it should also handle the .stop
+ on.call(this, this.key, value, this)
+ if (isTrue(this.skipBranch)) {
+ this.skipBranch = false
+ continue
}
- return false
- }
- }
- else if (isObjNotNull(x)) {
- /* istanbul ignore next: dev */
- if (ENV_DEBUG) {
- console.log('isObjNotNull', {x})
- }
-
- // if (isArray(x)) {
- // if (x.length !== y.length) {
- // return false
- // }
- // }
-
- // @NOTE .toString will be covered for functions and regexes in objStrict
- if (isRegExp(x) || isRegExp(y)) {
/* istanbul ignore next: dev */
if (ENV_DEBUG) {
- console.log('regexp', {x, y})
+ // require('fliplog').data(parents).echo()
+ // require('fliplog').data(this).echo()
}
- if (!x || !y || x.toString() !== y.toString()) {
+ // handle data
+ if (isTrue(this.isCircular)) {
/* istanbul ignore next: dev */
if (ENV_DEBUG) {
- console.log('regexp !=', {x, y})
+ console.log('(((circular)))', this.key)
}
- return false
- }
- }
- else if (isDate(x) || isDate(y)) {
- /* istanbul ignore next: dev */
- if (ENV_DEBUG) {
- console.log('dates', {x, y})
- }
-
- if (!isDate(x) || !isDate(y) || x.getTime() !== y.getTime()) {
- /* istanbul ignore next: dev */
- if (ENV_DEBUG) {
- console.log('!= dates', {x, y})
- }
+ // on.call(this, this.key, value, this)
+ // this.path.pop()
+ this.path = pathBeforeNesting
- return false
- }
- }
- else if (isError(x) || isError(y)) {
- /* istanbul ignore next: dev */
- if (ENV_DEBUG) {
- console.log('isError', {x, y})
+ // this.isCircular = false
+ // break
+ continue
+ // return
}
- if (!isError(x) || !isError(y) || x.stack !== y.stack) {
+
+ // &&
+ if (isTrue(this.isIteratable)) {
/* istanbul ignore next: dev */
if (ENV_DEBUG) {
- console.log('!= errors', {x, y})
+ console.log('(((iteratable)))', this.key)
}
- return false
- }
- }
- else if (isArray(x) && !isArray(y)) {
- /* istanbul ignore next: dev */
- if (ENV_DEBUG) {
- console.log('isArray(x) || isArray(y)!')
+ this.node = value
+ this.iterate(on)
+ this.path = pathBeforeNesting
}
- return false
- }
- else if (!isArray(x) && isArray(y)) {
/* istanbul ignore next: dev */
if (ENV_DEBUG) {
- console.log('!isArray(x) && isArray(y):')
- }
-
- return false
- }
- else {
- // @NOTE it will traverse through values if they are == here
- const xKeys = ObjectKeys(x)
- const yKeys = ObjectKeys(y).length
-
- if (xKeys.length !== yKeys) {
- /* istanbul ignore next: dev */
- if (ENV_DEBUG) {
- console.log('!= obj key length', {xKeys, yKeys})
+ if (this.isIteratable === false) {
+ console.log('not iteratable', this.key)
}
- return false
+ console.log('----------------- post ----------', node)
}
- for (let k = 0; k < xKeys.length; k++) {
- if (!hasOwnProperty(y, xKeys[k])) {
- /* istanbul ignore next: dev */
- if (ENV_DEBUG) {
- console.log('!= obj property', {y, val: xKeys[k]})
- }
-
- return false
- }
+ // @event
+ if (!isUndefined(this.onPost)) {
+ // eslint-disable-next-line no-useless-call
+ this.onPost(this)
}
- }
- }
- else if (toS(x) === toS(y) && x !== y) {
- // isString(x) || isBoolean(x) || isNumber(x) || isIterator(x)
- /* istanbul ignore next: dev */
- if (ENV_DEBUG) {
- console.log('same str types - diff values', {s: toS(x), x, y})
- }
- return false
- }
- else if (toS(x) !== toS(y)) {
- /* istanbul ignore next: dev */
- if (ENV_DEBUG) {
- console.log('diff str types', {x: toS(x), y: toS(y)})
- }
-
- return false
- }
+ // cleanup, backup 1 level
+ this.path.pop()
- // go deeper
- else if (isFunction(x) || isFunction(y)) {
- /* istanbul ignore next: dev */
- if (ENV_DEBUG) {
- console.log('isFunction(x) && isFunction(y):')
- console.log(x.toString())
- console.log(y.toString())
+ this.removeParent(node)
}
- if (!x || !y || x.toString() !== y.toString()) {
- /* istanbul ignore next: dev */
- if (ENV_DEBUG) {
- console.log('x.toString() !== y.toString()', x.toString() !== y.toString())
- }
- return false
- }
- else {
- return true
- }
+ // this.path.pop()
+ this.depth = this.path.length
}
-
- else if (isObj(x) && isObj(y)) {
- /* istanbul ignore next: dev */
- if (ENV_DEBUG) {
- console.log('isObj(x) && isObj(y):')
- }
-
- return false
- }
- // else {
- /* istanbul ignore next: dev */
- if (ENV_DEBUG) {
- console.log('eqeqeq:', {[toS(x) + 'X']: x, [toS(y) + 'Y']: y})
- }
- return true
- // }
-}
-
-/* prettier-ignore */
-function eq(a, b, loose, scoped) {
- /* istanbul ignore next: dev */
- if (ENV_DEBUG) {
- console.log('\n')
+ else {
+ // this.isLast = false
+ on.call(this, this.depth, node, this)
}
- let equal = true
- let node = b
+ // @NOTE: careful
+ // removeParent(node)
- // @TODO can be helpful? for left to right in 1 traverse for faster eq?
- // let _node = b
+ // @NOTE: just for .after ?
+ this.node = node
- const instance = traverse(a)
- const notEqual = () => {
- // throw new Error()
- equal = false
- instance.stop()
+ // @event
+ if (!isUndefined(this.onAfter)) {
+ // eslint-disable-next-line no-useless-call
+ this.onAfter(this)
}
- /* istanbul ignore next: dev */
- if (ENV_DEBUG) {
- console.log('eq?')
- }
+ this.path.pop()
- instance.forEach(function(key, y, traverser) {
- /* istanbul ignore next: dev */
- if (ENV_DEBUG) {
- console.log('eq: iterating:')
- }
+ return this.node
+}
- // BREAKS ANY BUT OBJ
- // if (!isObjLoose(node)) {
- // node = _node
- // return notEqual()
- // }
- // else {
- // _node = node
- // }
-
- if (isObjNotNull(node)) {
- // _node = node
- node = node[traverser.key]
- }
+// is smaller, but probably slower
+// function onEvent(property) {
+// return function(fn) {
+// this[property] = function
+// }
+// }
- // node = node ? node[traverser.key] : node
+// when it's some sort of itertable object, loop it further
+// @TODO: need to handle these better without totally messing with bad scope
+Traverse.prototype.pre = function(fn) {
+ this.onPre = fn
+}
+Traverse.prototype.post = function(fn) {
+ this.onPost = fn
+}
+Traverse.prototype.before = function(fn) {
+ this.onBefore = fn
+}
+Traverse.prototype.after = function(fn) {
+ this.onAfter = fn
+}
- let x = node
- x = dot.get(b, traverser.path.join('.'), b)
+// -----------------------
- /* istanbul ignore next: dev */
- if (ENV_DEBUG) {
- console.log({key, y, x, a, b})
- }
+/**
+ * @TODO merge with dopemerge?
+ * @TODO needs tests converted back for this (observe tests do cover somewhat)
+ *
+ * @param {*} arg defaults to this.node
+ * @return {*} cloned
+ *
+ * @example
+ *
+ * var obj = {}
+ * var cloned = traverse().clone(obj)
+ * obj.eh = true
+ * eq(obj, cloned)
+ * //=> false
+ *
+ */
+Traverse.prototype.clone = clone
- const eqv = eqValue(x, y, loose)
+/**
+ * @todo ugh, how to clone better with *recursive* objects?
+ * @param {any} src wip
+ * @return {any} wip
+ */
+Traverse.prototype.copy = copy
- /* istanbul ignore next: dev */
- if (ENV_DEBUG) {
- console.log({eqv})
- }
+/**
+ * @desc clone any value
+ * @version 5.0.0
+ * @since 4.0.0
+ * @memberOf Traverse
+ * @extends copy
+ * @extends Traverse
+ *
+ * @param {*} arg argument to clone
+ * @return {*} cloned value
+ *
+ * {@link http://underscorejs.org/#clone underscore-clone}
+ * @see {@link underscore-clone}
+ * @see dopemerge
+ *
+ * @example
+ *
+ * var obj = {eh: true}
+ * clone(obj) === obj //=> false
+ *
+ * var obj = {eh: true}
+ * var obj2 = clone(obj)
+ * obj.eh = false
+ * console.log(obj2.eh) //=> true
+ *
+ */
+function clone(arg) {
+ const obj = isUndefined(arg) ? this.node : arg
+ if (isPrimitive(obj)) return obj
+ let cloned = emptyTarget(obj)
+ let current = cloned
- if (eqv === false) {
- // equal
- notEqual()
- }
- // }
+ traverse(obj).forEach((key, value, traverser) => {
+ // t.isRoot
+ if (isNull(key)) return
+
+ let copied = copy(value)
+ if (traverser.isCircular && isArray(value)) copied = value.slice(0)
+ dotSet(current, traverser.path, copied)
})
- if (equal === false && scoped === false) return eq(b, a, loose, true)
- else return equal
+ return cloned
}
+// @TODO could just have traverse = Traverse.getPooled ?
+addPoolingTo(Traverse)
function traverse(value) {
- const ItOrAteOr = makeIterator()
- return new ItOrAteOr(value)
+ return Traverse.getPooled(value)
}
+traverse.eq = eq(traverse)
+traverse.clone = clone
+traverse.copy = copy
module.exports = traverse
-module.exports.eq = eq
-module.exports.clone = clone
-module.exports.copy = copy
diff --git a/src/deps/traversers/_eq.js b/src/deps/traversers/_eq.js
new file mode 100644
index 0000000..0bf71c3
--- /dev/null
+++ b/src/deps/traversers/_eq.js
@@ -0,0 +1,160 @@
+// conditionals
+/* eslint complexity: "OFF" */
+
+// not iterating on empty root
+/* eslint consistent-return: "OFF" */
+
+// const traverse = require('../traverse')
+// const get = require('../dot/get')
+const isObjNotNull = require('../is/objNotNull')
+const isNull = require('../is/null')
+const isEmpty = require('../is/empty')
+const ENV_DEBUG = require('../env/debug')
+const eqValue = require('./eqValue')
+
+/* prettier-ignore */
+/**
+ * @name eq
+ * @alias equals
+ * @since 3.0.0
+ * @version 5.0.0
+ * @memberOf Traverse
+ *
+ * {@link https://github.com/andrewplummer/Sugar/blob/master/lib/common.js#L668 sugar-equal}
+ * {@link https://github.com/the-grid/finitedomain/blob/master/src/propagator.js#L160 eq-qfox}
+ * {@link https://github.com/jasmine/jasmine.github.io/blob/master/lib/jasmine-1.3.1/jasmine.js#L940 jasmine-equals}
+ * {@link https://github.com/mobxjs/mobx/blob/master/src/utils/utils.ts#L145 mobx-deepequal}
+ * {@link https://github.com/js-data/js-data/blob/v2/src/utils.js#L571 js-data-circular}
+ * {@link https://github.com/js-data/js-data/blob/v2/src/utils.js#L300 js-data-equals}
+ * {@link http://dorey.github.io/JavaScript-Equality-Table/ js-equality-table}
+ * {@link https://github.com/facebook/react/blob/master/src/__mocks__/deepDiffer.js react-deep-differ}
+ * {@link https://github.com/substack/js-traverse/blob/master/test/lib/deep_equal.js traverse-deep-equal}
+ * {@link https://github.com/jashkenas/underscore/blob/master/underscore.js#L1183 underscore-equal}
+ * {@link https://github.com/angular/angular.js/blob/master/src/Angular.js angular-is-equal}
+ * {@link https://lodash.com/docs/4.17.4#isEqual lodash-is-equal}
+ * {@link http://ramdajs.com/docs/#equals ramda-equals}
+ * {@link https://github.com/substack/node-deep-equal node-deep-equal}
+ * {@link https://github.com/facebook/immutable-js/blob/master/src/utils/deepEqual.js immutable-js-deep-equal}
+ * @see {@link mobx-deepequal}
+ * @see {@link js-equality-table}
+ * @see {@link immutable-js-deep-equal}
+ * @see {@link node-deep-equal}
+ * @see {@link ramda-equals}
+ * @see {@link lodash-is-equal}
+ * @see {@link angular-is-equal}
+ * @see {@link underscore-equal}
+ * @see {@link traverse-deep-equal}
+ * @see {@link react-deep-differ}
+ * @see {@link js-data-equals}
+ * @see {@link jasmine-equals}
+ * @see {@link eq-qfox}
+ * @see {@link sugar-equal}
+ *
+ * @param {Traverse} traverse traversejs (scoped, @FIXME @HACK)
+ * @param {*} a compare to b
+ * @param {*} b compare to a
+ * @param {boolean} [loose] compare loosely
+ * @return {boolean} isEqual: a === b
+ *
+ * @extends eqValue
+ *
+ * @example
+ *
+ * eq(1, 1) //=> true
+ * eq(1, '1') //=> false
+ * eq(1, '1', true) //=> true
+ * eq([1], [1]) //=> true
+ *
+ */
+module.exports = traverse => function eq(a, b, loose) {
+ /* istanbul ignore next: dev */
+ if (ENV_DEBUG) {
+ console.log('\n')
+ }
+
+ let equal = true
+ let node = b
+ let nodes = [node]
+
+ const instance = traverse(a)
+
+ const notEqual = () => {
+ equal = false
+ instance.stop()
+ }
+
+ /* istanbul ignore next: dev */
+ if (ENV_DEBUG) {
+ console.log('eq?')
+ }
+
+ instance.forEach(function(key, y, traverser) {
+ // @NOTE do base comparisons on values that are not actually iteratable
+ // aka, .isRoot
+ if (isNull(key)) {
+ // always-valid state opionion vs always-invalid
+ // so it only returns false when it is !== fosho
+ if (eqValue(node, y, loose) === false) return notEqual()
+ else return
+ }
+
+ /* istanbul ignore next: dev */
+ if (ENV_DEBUG) {
+ console.log('eq: iterating:')
+ }
+
+ // could use it as a fallback if undefined && y !== undefined
+ // const xyz = get(b, traverser.path.join('.'), b)
+
+ let x = node
+
+ // isNotLeafAndIsObj
+ if (isObjNotNull(node) && !isEmpty(node)) {
+ /* istanbul ignore next: dev */
+ if (ENV_DEBUG) {
+ console.log('is leaf, is not empty node, going deeper')
+ }
+
+ // so x is our current one,
+ // if node is not empty, use the key, push the value
+ // and when it is empty, and it is not a leaf but has nodes, pop back up
+ x = node[key]
+ nodes.push(x)
+ }
+
+ // ENV_DEBUG
+ // console.log({[key]: {x, xyz, y, nodes, path: traverser.path.join('.')}})
+
+ // for next loop!!!
+ if (!traverser.isLeaf && !isEmpty(nodes)) {
+ /* istanbul ignore next: dev */
+ if (ENV_DEBUG) {
+ console.log('is not leaf, has nodes stack, pop')
+ }
+ node = nodes.pop()
+ }
+
+ /* istanbul ignore next: dev */
+ if (ENV_DEBUG) {
+ console.log({key, y, x, a, b})
+ }
+
+ const eqv = eqValue(x, y, loose)
+
+ /* istanbul ignore next: dev */
+ if (ENV_DEBUG) {
+ console.log({eqv})
+ }
+
+ if (eqv === false) {
+ // equal
+ notEqual()
+ }
+ })
+
+ // cleanup
+ nodes = undefined
+ node = undefined
+
+ return equal
+}
diff --git a/src/deps/traversers/copy.js b/src/deps/traversers/copy.js
new file mode 100644
index 0000000..7b11044
--- /dev/null
+++ b/src/deps/traversers/copy.js
@@ -0,0 +1,111 @@
+const isObjNotNull = require('../is/objNotNull')
+const isRegExp = require('../is/regexp')
+const isError = require('../is/error')
+const isDate = require('../is/date')
+const isArray = require('../is/array')
+const newRegExp = require('../construct/regexp')
+const ENV_DEBUG = require('../env/debug')
+
+/* prettier-ignore */
+/**
+ * @desc copy any primitive value, part of clone
+ * @version 5.0.0
+ * @since 3.0.0
+ * @name copy
+ * @see clone
+ * @memberOf Traverse
+ *
+ * {@link https://github.com/the-grid/finitedomain/blob/master/src/solver.js#L750 qfox-clone}
+ * {@link https://github.com/lodash/lodash/blob/master/.internal/cloneRegExp.js lodash-clone-regexp}
+ *
+ * @param {*} src value to copy
+ * @return {*} copied
+ *
+ * @example
+ *
+ * copy(/eh/gmi) //=> new RegExp('eh', 'gmi')
+ * copy(new Error('eh')) //=> new Error with copied stack + msg
+ * copy([1]) //=> [1]
+ * copy({}) //=> {}
+ *
+ */
+module.exports = function copy(src) {
+ if (isObjNotNull(src)) {
+ let dst
+
+ // if (isPrimitive(src)) {
+ // if (isNullOrUndefined(src)) {
+ // dst = src
+ // }
+
+ // @TODO @IMPORTANT @FIXME @!IMPORTANT - COVER THIS OR NOT?
+ // for string value number boolean objects...
+ // if (isString(src)) {
+ // dst = src + ''
+ // }
+ // else if (isNumber(src)) {
+ // dst = src + 0
+ // }
+ // else if (isBoolean(src)) {
+ // dst = !!src
+ // }
+ // else
+
+ // lists... <- needs to have dot-prop support on Map/Set
+ // if (isMap(src)) {
+ // dst = new Map()
+ // const obj = reduce(src)
+ // // src.clear()
+ // ObjectKeys(obj).forEach(key => dst.set(key, obj[key]))
+ // return dst
+ // }
+ // else if (isSet(src)) {
+ // dst = new Set()
+ // // could clone here too
+ // const obj = toarr(src)
+ // // src.clear()
+ // obj.forEach(value => dst.add(value))
+ // return dst
+ // }
+
+ // ------
+ if (isArray(src)) {
+ dst = []
+ }
+ // @TODO also would just be isPrimitive
+ // was new date(src.getTime())
+ // || isBoolean(src) || isNumber(src) || isString(src)
+ else if (isDate(src)) {
+ dst = new src.constructor(src.valueOf())
+ }
+ else if (isRegExp(src)) {
+ // dst = new RegExp(src)
+ dst = newRegExp(src.src, src.toString().match(/[^/]*$/)[0])
+ // dst = new RegExp(src.src, src.toString().match(/[^/]*$/)[0])
+ dst.lastIndex = src.lastIndex
+ }
+ // @TODO this should just be handled by the next condition...
+ // else if (isError(src)) {
+ // dst = new Error(src.message)
+ // dst.stack = src.stack
+ // }
+ else {
+ dst = Object.create(Object.getPrototypeOf(src))
+ }
+
+ // @TODO: copy descriptor
+ // eslint-disable-next-line
+ for (var prop in src) {
+ dst[prop] = src
+ // const desc = Object.getOwnPropertyDescriptor(src, prop)
+ // Object.defineProperty(dst, prop, desc)
+ }
+ return dst
+ }
+ else {
+ if (ENV_DEBUG) {
+ console.log('is not obj', src)
+ }
+ return src
+ }
+}
diff --git a/src/deps/traversers/eq.js b/src/deps/traversers/eq.js
index 4127f10..75f3a4b 100644
--- a/src/deps/traversers/eq.js
+++ b/src/deps/traversers/eq.js
@@ -1 +1,3 @@
-module.exports = require('../traverse').eq
+const traverser = require('../traverse')
+
+module.exports = traverser.eq
diff --git a/src/deps/traversers/eqValue.js b/src/deps/traversers/eqValue.js
new file mode 100644
index 0000000..836951c
--- /dev/null
+++ b/src/deps/traversers/eqValue.js
@@ -0,0 +1,266 @@
+// conditionals
+/* eslint complexity: "OFF" */
+// debugging
+/* eslint max-depth: "OFF" */
+
+const isObjNotNull = require('../is/objNotNull')
+const isNullOrUndefined = require('../is/nullOrUndefined')
+const isFunction = require('../is/function')
+const isRegExp = require('../is/regexp')
+const isError = require('../is/error')
+const isTrue = require('../is/true')
+const isDate = require('../is/date')
+const isArray = require('../is/array')
+const isObj = require('../is/obj')
+const toS = require('../is/toS')
+const hasOwnProperty = require('../util/hasOwnProperty')
+const ObjectKeys = require('../util/keys')
+const ObjectOrArrayKeys = require('../util/keysObjOrArray')
+const ENV_DEBUG = require('../env/debug')
+
+// const ENV_DEBUG = true
+
+const isNotRealOrNotEqToString = (x, y) =>
+ !x || !y || x.toString() !== y.toString()
+
+/* prettier-ignore */
+/**
+ * @desc checks value equality, used by eq which compares all types
+ * @since 4.1.0
+ * @memberOf Traverse
+ * @protected
+ *
+ * @TODO !!!!!! USE ENUM FLAGS ON LOOSE TO ALLOW MORE CONFIG FOR ==, COMPARATOR, VALUEOF, walk proto (check ownProps...)...
+ *
+ * @param {*} x compare to y
+ * @param {*} y compare to x
+ * @param {boolean | number} [loose=false] use == checks when typof !=
+ * @return {boolean}
+ *
+ * @example
+ *
+ * eqValue(1, 1) //=> true
+ * eqValue('1', 1) //=> false
+ * eqValue('1', 1, true) //=> true
+ * eqValue({}, {}) //=> true
+ *
+ */
+module.exports = function eqValue(x, y, loose) {
+ /* istanbul ignore next: dev */
+ if (ENV_DEBUG) {
+ console.log('eqValue', {x, y, loose})
+ }
+
+ // if (x === y) {
+ // if (ENV_DEBUG) {
+ // console.log('===', {x, y})
+ // }
+ // // noop
+ // }
+ // else
+
+ if (isNullOrUndefined(x) || isNullOrUndefined(y)) {
+ /* istanbul ignore next: dev */
+ if (ENV_DEBUG) {
+ console.log('null or undef !=', {x, y})
+ }
+
+ if (x !== y) {
+ return false
+ }
+ }
+ else if (typeof x !== typeof y) {
+ // eslint-disable-next-line
+ if (isTrue(loose) && x == y) {
+ // ignore
+ }
+ else {
+ /* istanbul ignore next: dev */
+ if (ENV_DEBUG) {
+ console.log('typeof !=', {x, y})
+ }
+
+ return false
+ }
+ }
+ // @TODO put this up first?
+ else if (toS(x) !== toS(y)) {
+ /* istanbul ignore next: dev */
+ if (ENV_DEBUG) {
+ console.log('diff str types', {x: toS(x), y: toS(y)})
+ }
+
+ return false
+ }
+ else if (isObjNotNull(x)) {
+ // use .equals if the method exists
+ if (hasOwnProperty(x, 'equals')) {
+ return x.equals(y)
+ }
+
+ /* istanbul ignore next: dev */
+ if (ENV_DEBUG) {
+ console.log('isObjNotNull', {x})
+ }
+
+ // if (isArray(x)) {
+ // if (x.length !== y.length) {
+ // return false
+ // }
+ // }
+
+ // @NOTE .toString will be covered for functions and regexes in objStrict
+ if (isRegExp(x) || isRegExp(y)) {
+ /* istanbul ignore next: dev */
+ if (ENV_DEBUG) {
+ console.log('regexp', {x, y})
+ }
+
+ if (isNotRealOrNotEqToString(x, y)) {
+ /* istanbul ignore next: dev */
+ if (ENV_DEBUG) {
+ console.log('regexp !=', {x, y})
+ }
+
+ return false
+ }
+ }
+ else if (isDate(x) || isDate(y)) {
+ /* istanbul ignore next: dev */
+ if (ENV_DEBUG) {
+ console.log('dates', {x, y})
+ }
+
+ if (!isDate(x) || !isDate(y) || x.getTime() !== y.getTime()) {
+ /* istanbul ignore next: dev */
+ if (ENV_DEBUG) {
+ console.log('!= dates', {x, y})
+ }
+
+ return false
+ }
+ }
+ else if (isError(x) || isError(y)) {
+ /* istanbul ignore next: dev */
+ if (ENV_DEBUG) {
+ console.log('isError', {x, y})
+ }
+
+ if (!isError(x) || !isError(y) || x.stack !== y.stack) {
+ /* istanbul ignore next: dev */
+ if (ENV_DEBUG) {
+ console.log('!= errors', {x, y})
+ }
+
+ return false
+ }
+ }
+
+ // @NOTE this is covered by toString != toString
+ // else if (isArray(x) && !isArray(y)) {
+ // /* istanbul ignore next: dev */
+ // if (ENV_DEBUG) {
+ // console.log('isArray(x) || isArray(y)!')
+ // }
+ //
+ // return false
+ // }
+ // else if (!isArray(x) && isArray(y)) {
+ // /* istanbul ignore next: dev */
+ // if (ENV_DEBUG) {
+ // console.log('!isArray(x) && isArray(y):')
+ // }
+ //
+ // return false
+ // }
+
+ // @TODO considering, we already know it is not null & undefined
+ // if (isPrimitive(x) || isPrimitive(y)) {
+ // return x.valueOf() === y.valueOf()
+ // }
+
+ else {
+ // @TODO ObjectOrArrayKeys, but have to have else where they are both array
+ //
+ // @NOTE it will traverse through values if they are == here
+ const xKeys = ObjectKeys(x)
+ const yKeys = ObjectKeys(y).length
+
+ // diff length
+ if (xKeys.length !== yKeys) {
+ /* istanbul ignore next: dev */
+ if (ENV_DEBUG) {
+ console.log('!= obj key length', {xKeys, yKeys})
+ }
+
+ return false
+ }
+
+ for (let k = 0; k < xKeys.length; k++) {
+ if (!hasOwnProperty(y, xKeys[k])) {
+ /* istanbul ignore next: dev */
+ if (ENV_DEBUG) {
+ console.log('!= obj property', {y, val: xKeys[k]})
+ }
+
+ return false
+ }
+ }
+ }
+ }
+ else if (toS(x) === toS(y) && x !== y) {
+ // isString(x) || isBoolean(x) || isNumber(x) || isIterator(x)
+ /* istanbul ignore next: dev */
+ if (ENV_DEBUG) {
+ console.log('same str types - diff values', {s: toS(x), x, y})
+ }
+
+ return false
+ }
+ // // @TODO put this up first?
+ // else if (toS(x) !== toS(y)) {
+ // /* istanbul ignore next: dev */
+ // if (ENV_DEBUG) {
+ // console.log('diff str types', {x: toS(x), y: toS(y)})
+ // }
+ //
+ // return false
+ // }
+
+ // go deeper
+ else if (isFunction(x) || isFunction(y)) {
+ /* istanbul ignore next: dev */
+ if (ENV_DEBUG) {
+ console.log('isFunction(x) && isFunction(y):')
+ console.log(x.toString())
+ console.log(y.toString())
+ }
+
+ if (isNotRealOrNotEqToString(x, y)) {
+ /* istanbul ignore next: dev */
+ if (ENV_DEBUG) {
+ console.log('x.toString() !== y.toString()', x.toString() !== y.toString())
+ }
+ return false
+ }
+ else {
+ return true
+ }
+ }
+ // @TODO why?
+ else if (isObj(x) && isObj(y)) {
+ /* istanbul ignore next: dev */
+ if (ENV_DEBUG) {
+ console.log('isObj(x) && isObj(y):')
+ }
+
+ return false
+ }
+ // else {
+ /* istanbul ignore next: dev */
+ if (ENV_DEBUG) {
+ console.log('eqeqeq:', {[toS(x) + 'X']: x, [toS(y) + 'Y']: y})
+ }
+ return true
+ // }
+}
diff --git a/src/deps/traversers/traverse-comments.js b/src/deps/traversers/traverse-comments.js
new file mode 100644
index 0000000..3d51758
--- /dev/null
+++ b/src/deps/traversers/traverse-comments.js
@@ -0,0 +1,225 @@
+// need some thin wrapper around values to go up and down path
+//
+//
+// const ValueObject = {
+// node: value,
+// kind: typeof,
+// isRoot: false,
+// isLeaf: false,
+// isPrimitive: false,
+// branches: [],
+// isFirst: false,
+// isLast: false,
+// parent: {},
+// }
+//
+// class It {
+// constructor(x) {
+// // this.tree = {
+// // parent: {},
+// // }
+//
+// // this.root = x
+//
+// // this.previous = x
+// this.current = x
+//
+// this.depth = 0
+// this.all = new Set()
+// // this.path
+// // this.key
+// }
+//
+// get node() {
+// return this.current
+// }
+//
+// addBranch() {}
+//
+// // for updating
+// branchHead() {}
+//
+// goUp() {
+// this.depth--
+// }
+// goDown(current) {
+// this.parent = this.current
+// this.depth++
+// this.current = current
+// }
+// // not needed but conceptually
+// // goNext() {}
+//
+// find() {}
+// path() {}
+// }
+// const it = x => new It(x)
+
+
+// return Array.from(parents.values()).indexOf(value) !== -1
+// const keys = Array.from(parents.keys())
+// console.log('___pk', {keys})
+// for (let k = 0; k < keys.length; k++) {
+// const key = keys[k]
+// const matches =
+// depth.includes(key) || (key.includes && key.includes(depth))
+// console.log({key, matches, depth})
+// // .has(value)
+// if (matches) {
+// let has = false
+// parents.get(key).forEach(haz => {
+// if (value === haz) has = true
+// })
+// return has
+// }
+// }
+
+// for (let i = depth; i >= depth; i--) {
+// if (parents.get(i).has(value)) return true
+// }
+
+// return false
+
+
+// const pps = []
+// const ppHas = value => {
+// for (let i = 0; i < pps.length; i++) {
+// if (pps[i] === value) {
+// return true
+// }
+// }
+// }
+// const ppAdd = value => pps.push(value)
+// const ppPop = () => pps.pop()
+
+// else if (ppHas(node)) {
+// if (ENV_DEBUG) {
+// console.log('PPHAS!!!!!!!!!!!', {node, path: this.path})
+// }
+// this.isCircular = true
+// }
+
+
+// ----- clear/update ----
+// if (!isUndefined(this.iteratee)) {
+// this.iteratee[this.key] = value
+// }
+// // dot.set(this.iteratee, this.key, value)
+
+// dot.set(this.iteratee, this.path, value)
+
+// dot.set(this.iteratee, this.key, value)
+// console.log({traverser: this})
+
+// @NOTE think about this more, but updating can change structure
+// if (isTrue(clear)) clearParents()
+
+// ----- parents
+// if (!this.parents.has(depth)) this.parents.set(depth, new Set())
+// this.parents.get(depth).add(value)
+
+// (isObj(value) ? parents.add(value) : parents.add(value))
+// const removeLastParent = () => parents.delete(lastParent)
+
+// parents.forEach(parent => (parent.has(value) ? parent.delete(value) : null))
+// parents.delete(value)
+
+
+// ---- eq ----
+
+// from underscore.js & ramda
+//
+// Assume equality for cyclic structures. The algorithm for detecting cyclic
+// structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
+//
+// Initializing stack of traversed objects.
+// It's done here since we only need them for objects and arrays comparison.
+// let length = stackA.length
+// while (length--) {
+// // Linear search. Performance is inversely proportional to the number of
+// // unique nested structures.
+// if (stackA[length] === a) return stackB[length] === b
+// }
+//
+// // Add the first object to the stack of traversed objects.
+// stackA.push(a)
+// stackB.push(b)
+
+// BREAKS ANY BUT OBJ
+// if (!isObjLoose(node)) {
+// node = _node
+// return notEqual()
+// }
+// else {
+// _node = node
+// }
+
+// if (isObjNotNull(node)) {
+// // _node = node
+// // nodes.push(node)
+// // node = node[key]
+// }
+// else {
+// // node = nodes.pop()
+// }
+
+// node = node ? node[traverser.key] : node
+// instance.before(traverser => {
+// // node = traverser.iteratee
+// // if (!isObjNotNull(x)) return
+// // // nodes.push(x)
+// // x = x[key]
+// // nodes.push(x)
+// })
+// instance.after(() => {
+// // x = node
+// // console.log('x before pop', {x})
+// // node =
+// // nodes.pop()
+// // x = node
+// // console.log('x after pop, nodes', {x})
+// })
+
+
+// ----- remove -----
+// if (isObj(obj)) deleteFromObjOrArray(obj, this.key)
+// else deleteFromObjOrArray(this.parent, this.key)
+// deleteFromObjOrArray(this.parent, this.key)
+// deleteFromObjOrArray(this.iteratee, this.key)
+
+// if (isUndefined(obj)) {
+// // throw new Error('why?')
+// }
+// else if (isArray(obj)) {
+// /* istanbul ignore next: dev */
+// if (ENV_DEBUG) {
+// console.log('traverse:remove:array', obj, this.key)
+// }
+//
+// obj.splice(this.key, 1)
+// }
+// else if (isObjNotNull(obj)) {
+// /* istanbul ignore next: dev */
+// if (ENV_DEBUG) {
+// console.log('traverse:remove:obj', this.key)
+// }
+//
+// delete obj[this.key]
+// }
+//
+// if (isObjNotNull(this.parent)) {
+// delete this.parent[this.key]
+//
+// /* istanbul ignore next: dev */
+// if (ENV_DEBUG) {
+// console.log('traverse:remove:parent', this.key)
+// }
+// }
+// if (isObjNotNull(this.iteratee)) {
+// delete this.iteratee[this.key]
+//
+// /* istanbul ignore next: dev */
+// if (ENV_DEBUG) {
+// console.log('traverse:remove:iteratee', this.key)
+// }
+// }
diff --git a/src/deps/util/assign.js b/src/deps/util/assign.js
index d0fa64c..3bb06ca 100644
--- a/src/deps/util/assign.js
+++ b/src/deps/util/assign.js
@@ -1 +1,111 @@
-module.exports = Object.assign
\ No newline at end of file
+/**
+ * @memberOf util
+ * @since 4.0.0
+ *
+ * {@link https://github.com/mobxjs/mobx/blob/master/src/utils/utils.ts#L86 mobx-object-assign}
+ * {@link https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/assign mozilla-object-assign}
+ * {@link https://esdiscuss.org/topic/object-assign-with-several-source-objects esdiscuss-object-assign}
+ * {@link https://github.com/facebook/react/blob/4b2eac3de7e1dbf5c2dd742fd9989974a83972cb/scripts/babel/transform-object-assign-require.js react-object-assign}
+ * {@link https://github.com/lodash/lodash/blob/master/.internal/assignValue.js lodash-assign}
+ * {@link https://github.com/ramda/ramda/blob/master/src/internal/_objectAssign.js ramda-assign}
+ * @see {@link react-object-assign}
+ * @see {@link ramda-assign}
+ * @see {@link lodash-assign}
+ * @see {@link mobx-object-assign}
+ * @see {@link esdiscuss-object-assign}
+ * @see {@link mozilla-object-assign}
+ *
+ * @type {Function}
+ */
+module.exports = Object.assign
+
+// const ENV_COMPAT = require('../env/compat')
+// @TODO if (ENV_COMPAT) polyfill
+
+// --- check
+// function shouldUseNative() {
+// try {
+// if (!Object.assign) {
+// return false
+// }
+//
+// // Detect buggy property enumeration order in older V8 versions.
+//
+// // https://bugs.chromium.org/p/v8/issues/detail?id=4118
+// var test1 = new String('abc') // eslint-disable-line no-new-wrappers
+// test1[5] = 'de'
+// if (Object.getOwnPropertyNames(test1)[0] === '5') {
+// return false
+// }
+//
+// // https://bugs.chromium.org/p/v8/issues/detail?id=3056
+// var test2 = {}
+// for (var i = 0; i < 10; i++) {
+// test2['_' + String.fromCharCode(i)] = i
+// }
+// var order2 = Object.getOwnPropertyNames(test2).map(function(n) {
+// return test2[n]
+// })
+// if (order2.join('') !== '0123456789') {
+// return false
+// }
+//
+// // https://bugs.chromium.org/p/v8/issues/detail?id=3056
+// var test3 = {}
+// 'abcdefghijklmnopqrst'.split('').forEach(function(letter) {
+// test3[letter] = letter
+// })
+// if (
+// Object.keys(Object.assign({}, test3)).join('') !== 'abcdefghijklmnopqrst'
+// ) {
+// return false
+// }
+//
+// return true
+// }
+// catch (err) {
+// // We don't expect any of the above to throw, but better to be safe.
+// return false
+// }
+// }
+
+// --- handle
+// function ObjectAssign(target, source) {
+// var from
+// var to = toObject(target)
+// var symbols
+//
+// for (var s = 1; s < arguments.length; s++) {
+// from = Object(arguments[s])
+//
+// for (var key in from) {
+// if (hasOwnProperty.call(from, key)) {
+// to[key] = from[key]
+// }
+// }
+//
+// if (getOwnPropertySymbols) {
+// symbols = getOwnPropertySymbols(from)
+// for (var i = 0; i < symbols.length; i++) {
+// if (propIsEnumerable.call(from, symbols[i])) {
+// to[symbols[i]] = from[symbols[i]]
+// }
+// }
+// }
+// }
+//
+// return to
+// }
+
+// babel
+// function(target) {
+// for (var i = 1; i < arguments.length; i++) {
+// var source = arguments[i]
+// for (var key in source) {
+// if (Object.prototype.hasOwnProperty.call(source, key)) {
+// target[key] = source[key]
+// }
+// }
+// }
+// return target
+// }
diff --git a/src/deps/util/charCodeAtZero.js b/src/deps/util/charCodeAtZero.js
deleted file mode 100644
index 8c728e9..0000000
--- a/src/deps/util/charCodeAtZero.js
+++ /dev/null
@@ -1 +0,0 @@
-module.exports = str => str.charCodeAt(0)
diff --git a/src/deps/util/concat.js b/src/deps/util/concat.js
new file mode 100644
index 0000000..cc32a71
--- /dev/null
+++ b/src/deps/util/concat.js
@@ -0,0 +1,32 @@
+const curry = require('../fp/curry')
+const toString = require('../cast/toString')
+const concatArray = require('../array/concat')
+const isString = require('../is/stringPrimitive')
+
+/**
+ * @name concat
+ * @alias concatAny
+ * @since 5.0.0-beta.6
+ *
+ * @curried 2
+ * @see array/concat
+ *
+ * @param {string|Array} a
+ * @param {string|Array} b
+ * @return {string|Array} y
+ */
+function concat(a, b) {
+ if (isString(a)) {
+ if (isString(b)) {
+ return a + b
+ }
+ else {
+ return a + toString(b)
+ }
+ }
+ else {
+ return concatArray(a, b)
+ }
+}
+
+module.exports = curry(2, concat)
diff --git a/src/deps/define.js b/src/deps/util/define.js
similarity index 73%
rename from src/deps/define.js
rename to src/deps/util/define.js
index 089efc0..24e3c04 100644
--- a/src/deps/define.js
+++ b/src/deps/util/define.js
@@ -1,12 +1,13 @@
-const ObjectAssign = require('./util/assign')
+const ObjectAssign = require('./assign')
/**
* @desc default to configurable and enumerable, unless configured otherwise
* @since 4.0.0
+ * @memberOf util
*
- * @param {Object} obj object to define on
- * @param {Primitive} name property name to define
- * @param {Object} descriptor object descriptor
+ * @param {Object} obj object to define on
+ * @param {Primitive} name property name to define
+ * @param {Object} descriptor object descriptor
* @return {void}
*
* @tutorial https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty
diff --git a/src/deps/util/defineFinal.js b/src/deps/util/defineFinal.js
new file mode 100644
index 0000000..4e6cbc8
--- /dev/null
+++ b/src/deps/util/defineFinal.js
@@ -0,0 +1,39 @@
+const ObjectDefine = require('./define')
+
+/**
+ * @desc define a hidden property that is not writable, extremely internal hidden last resort
+ * @since 5.0.0-beta.5
+ * @memberOf util
+ * @symb 🔚
+ *
+ * @extends util/define
+ * @variation value is a value for the property, not a descriptor
+ *
+ * @param {Object} obj object to define on
+ * @param {Primitive} name property name to define
+ * @param {Object} descriptor object descriptor
+ * @return {void}
+ *
+ * {@link https://github.com/mobxjs/mobx/blob/master/src/utils/utils.ts#L117 mobx-definefinal}
+ * @see {@link mobx-definefinal}
+ *
+ * @example
+ *
+ * const obj = {}
+ * defineFinal(obj, 'eh', 0)
+ *
+ * obj.eh
+ * //=> 0
+ *
+ * Object.keys(obj)
+ * //=> []
+ *
+ */
+module.exports = function addHiddenFinalProp(obj, name, value) {
+ ObjectDefine(obj, name, {
+ enumerable: false,
+ writable: false,
+ configurable: true,
+ value,
+ })
+}
diff --git a/src/deps/util/flatten.js b/src/deps/util/flatten.js
deleted file mode 100644
index 5201630..0000000
--- a/src/deps/util/flatten.js
+++ /dev/null
@@ -1,21 +0,0 @@
-/**
- * @desc flatten multi-dimensional arrays in 1 line
- * @see https://stackoverflow.com/questions/10865025/merge-flatten-an-array-of-arrays-in-javascript
- * @param {Array} arr array(s) to flatten
- * @return {Array} flattened arrays
- * @example
- *
- * flatten([[1], [2]])
- * //=> [1, 2]
- * flatten([[1], 2])
- * //=> [1, 2]
- * flatten(1)
- * //=> [1]
- *
- */
-module.exports = x => [].concat.apply(x)
-
-// function flatten(arr) {
-// const flat = [].concat(...arr)
-// return flat.some(Array.isArray) ? flatten(flat) : flat
-// }
diff --git a/src/deps/util/freeze.js b/src/deps/util/freeze.js
new file mode 100644
index 0000000..e29ffc0
--- /dev/null
+++ b/src/deps/util/freeze.js
@@ -0,0 +1,16 @@
+const identity = require('../fp/identity')
+
+/**
+ * @symb ❄️
+ * @desc use Object.freeze or identity identity
+ * @memberOf util
+ * @since 5.0.0-beta.1
+ * @name freeze
+ * @type {Function}
+ *
+ * {@link https://stackoverflow.com/questions/8435080/any-performance-benefit-to-locking-down-javascript-objects perf-freeze}
+ * @see {@link perf-freeze}
+ *
+ * @see fp/identity
+ */
+module.exports = Object.freeze || identity
diff --git a/src/deps/util/from.js b/src/deps/util/from.js
index 6b810b4..bdc9d7c 100644
--- a/src/deps/util/from.js
+++ b/src/deps/util/from.js
@@ -1,6 +1,6 @@
/**
+ * @memberOf util
* @tutorial https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/from
- * @see https://github.com/lodash/lodash/blob/master/.internal/setToArray.js
- * ^ could use if needed
+ * @see cast/toArray
*/
module.exports = Array.from
diff --git a/src/deps/util/hasOwnProperty.js b/src/deps/util/hasOwnProperty.js
index d608a53..91f8b21 100644
--- a/src/deps/util/hasOwnProperty.js
+++ b/src/deps/util/hasOwnProperty.js
@@ -1,6 +1,30 @@
-module.exports = (haystack, needle) =>
- Object.prototype.hasOwnProperty.call(haystack, needle)
+const curry = require('../fp/curry')
+const isNill = require('../is/nullOrUndefined')
+const hasOwnProperty = require('../native/objectHasOwnProperty')
+/**
+ * @desc hasOwnProperty, first checking !nill
+ * @since 3.0.0
+ * @memberOf util
+ * @alias has
+ *
+ * @param {Object | *} haystack object
+ * @param {string | *} needle property
+ * @return {boolean} haystack != null & haystack[needle]
+ *
+ * {@link https://github.com/ramda/ramda/blob/v0.24.1/src/internal/_has.js ramda-has}
+ * @see {@link ramda-has}
+ *
+ * @example
+ *
+ * hasOwnPropertyNotNill({eh: true}, 'eh') //=> true
+ * hasOwnPropertyNotNill({eh: true}, 'nope') //=> false
+ *
+ */
+const hasOwnPropertyNotNill = (haystack, needle) =>
+ !isNill(haystack) && hasOwnProperty.call(haystack, needle)
+
+module.exports = curry(2, hasOwnPropertyNotNill)
// function(obj, key) {
// return key in obj
// }
diff --git a/src/deps/util/index.js b/src/deps/util/index.js
new file mode 100644
index 0000000..37007fa
--- /dev/null
+++ b/src/deps/util/index.js
@@ -0,0 +1 @@
+module.exports = require('./util')
diff --git a/src/deps/util/indexOf.js b/src/deps/util/indexOf.js
new file mode 100644
index 0000000..27c0d3f
--- /dev/null
+++ b/src/deps/util/indexOf.js
@@ -0,0 +1,91 @@
+const curry = require('../fp/curry')
+
+/**
+ * Returns the position of the first occurrence of an item in an array, or -1
+ * if the item is not included in the array. [`R.equals`](#equals) is used to
+ * determine equality.
+ * @memberOf util
+ * @since 5.0.0-beta.7
+ * @curried 2
+ *
+ * @param {*} target The item to find.
+ * @param {Array} xs The array to search in.
+ * @return {Number} the index of the target, or -1 if the target is not found.
+ *
+ * @func
+ * @fork v0.1.0
+ * @category List
+ * @sig a -> [a] -> Number
+ *
+ * @see fp/lastIndexOf
+ * @see Ramda/indexOf
+ *
+ * @example
+ *
+ * indexOf(3, [1,2,3,4]); //=> 2
+ * indexOf(10, [1,2,3,4]); //=> -1
+ *
+ */
+const indexOf = function(needle, haystack) {
+ return haystack.indexOf(needle)
+}
+module.exports = curry(2, indexOf)
+
+
+// @NOTE ramda polyfil
+// var equals = require('../equals');
+// module.exports = function _indexOf(list, a, idx) {
+// var inf, item;
+// // Array.prototype.indexOf doesn't exist below IE9
+// if (typeof list.indexOf === 'function') {
+// switch (typeof a) {
+// case 'number':
+// if (a === 0) {
+// // manually crawl the list to distinguish between +0 and -0
+// inf = 1 / a;
+// while (idx < list.length) {
+// item = list[idx];
+// if (item === 0 && 1 / item === inf) {
+// return idx;
+// }
+// idx += 1;
+// }
+// return -1;
+// } else if (a !== a) {
+// // NaN
+// while (idx < list.length) {
+// item = list[idx];
+// if (typeof item === 'number' && item !== item) {
+// return idx;
+// }
+// idx += 1;
+// }
+// return -1;
+// }
+// // non-zero numbers can utilise Set
+// return list.indexOf(a, idx);
+//
+// // all these types can utilise Set
+// case 'string':
+// case 'boolean':
+// case 'function':
+// case 'undefined':
+// return list.indexOf(a, idx);
+//
+// case 'object':
+// if (a === null) {
+// // null can utilise Set
+// return list.indexOf(a, idx);
+// }
+// }
+// }
+// // anything else not covered above, defer to equals
+// while (idx < list.length) {
+// if (equals(list[idx], a)) {
+// return idx;
+// }
+// idx += 1;
+// }
+// return -1;
+// };
+//
diff --git a/src/deps/util/keys.js b/src/deps/util/keys.js
index fe1a190..d2a5b54 100644
--- a/src/deps/util/keys.js
+++ b/src/deps/util/keys.js
@@ -1,6 +1,3 @@
module.exports = Object.keys
-// function keys(obj) {
-// var res = []
-// for (var key in obj)
-// { res.push(key) }
-// return res
+
+// ENV_COMPAT: // https://github.com/ramda/ramda/blob/master/src/keys.js
diff --git a/src/deps/util/keysIn.js b/src/deps/util/keysIn.js
new file mode 100644
index 0000000..3ce4f67
--- /dev/null
+++ b/src/deps/util/keysIn.js
@@ -0,0 +1,52 @@
+const isTrue = require('../is/true')
+const preAllocate = require('../array/preAllocate')
+const hasOwnProperty = require('./hasOwnProperty')
+
+/**
+ * @name keysIn
+ * @version 1.0.0 uncommented, used preAllocate
+ * @version 0.0.1 just comment
+ * @since 5.0.0
+ *
+ * @param {Object|Array} obj object to call `for in` on
+ * @param {boolean} [guard=false] only accept `hasOwnProperty`
+ * @return {Array} keys from obj
+ *
+ * {@link https://github.com/ramda/ramda/blob/master/src/keysIn.js ramda-keys-in}
+ * @see {@link ramda-keys-in}
+ * @see array/preAllocate
+ * @see util/hasOwnProperty
+ *
+ * @tests keys
+ *
+ * @example
+ *
+ * keysIn([1, 2]) //=> [0, 1]
+ * keysIn({one: 1, two: 2}) //=> ['one', 'two']
+ *
+ */
+module.exports = function keysIn(obj, guard) {
+ const result = preAllocate(obj)
+ let index = 0
+
+ // eslint-disable-next-line
+ // for (const key in obj) hasOwnProperty(obj, key) && (result[index++] = key)
+
+ for (const key in obj) {
+ /**
+ * when we have a guard, check ownProperty, otherwise just assign
+ *
+ * also written as pseudo:
+ * ```
+ * if (guard)
+ * if (hasOwnProperty) assign
+ * else result[index++] = key
+ * ```
+ */
+ if (!isTrue(guard) || hasOwnProperty(obj, key)) {
+ result[index++] = key
+ }
+ }
+
+ return result
+}
diff --git a/src/deps/util/keysObjOrArray.js b/src/deps/util/keysObjOrArray.js
new file mode 100644
index 0000000..73746b2
--- /dev/null
+++ b/src/deps/util/keysObjOrArray.js
@@ -0,0 +1,66 @@
+const ENV_PERF = require('../env/preferPerf')
+const EMPTY_OBJ = require('../native/EMPTY_OBJ')
+const preAllocate = require('../array/preAllocate')
+const isObj = require('../is/obj')
+const isArray = require('../is/array')
+const ObjectKeys = require('./keys')
+
+/**
+ * Creates an array of the own enumerable property names of `object`.
+ * **Note:** Non-object values are coerced to objects. See the
+ * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
+ * for more details.
+ *
+ * @since 0.1.0
+ * @category Object
+ * @name keysObjOrArray
+ *
+ * @param {Object|Array|Map|Set} obj The object to query, or value to pre-allocate with
+ * @return {Array} Returns the array of property names, or preallocated array
+ *
+ * @see deps/util/lengthFromZero
+ * @see deps/util/props
+ * @see util/values
+ * @see util/valuesIn
+ *
+ * {@link https://github.com/jashkenas/underscore/blob/master/underscore.js#L988 underscore-all-keys}
+ * {@link https://github.com/ramda/ramda/blob/master/src/keys.js ramda-keys}
+ * {@link https://github.com/lodash/lodash/blob/master/keys.js lodash-keys}
+ * {@link https://github.com/lodash/lodash/blob/master/.internal/getAllKeys.js lodash-get-all-keys}
+ * @see {@link lodash-keys}
+ * @see {@link lodash-get-all-keys}
+ * @see {@link ramda-keys}
+ * @see {@link underscore-all-keys}
+ *
+ * @TODO https://github.com/lodash/lodash/blob/master/.internal/arrayLikeKeys.js
+ *
+ * @example
+ *
+ * function Foo() {
+ * this.a = 1
+ * this.b = 2
+ * }
+ *
+ * Foo.prototype.c = 3
+ *
+ * keys(new Foo)
+ * //=> ['a', 'b'] (iteration order is not guaranteed)
+ *
+ * keys('hi')
+ * //=> ['0', '1']
+ *
+ */
+module.exports = function keys(obj) {
+ return isArray(obj)
+ // preAllocate(obj)
+ ? obj
+ : isObj(obj)
+ ? ObjectKeys(obj)
+ // @TODO
+ // ? hasOwnProperty(obj, 'keys')
+ // ? castIteratorToArray(obj.keys())
+ // : ObjectKeys(obj)
+ : ENV_PERF
+ ? EMPTY_OBJ
+ : []
+}
diff --git a/src/deps/util/kindOf.js b/src/deps/util/kindOf.js
new file mode 100644
index 0000000..03e94e7
--- /dev/null
+++ b/src/deps/util/kindOf.js
@@ -0,0 +1,20 @@
+const toS = require('../is/toS')
+
+/**
+ * split at space, replace brackets and space, lowercase
+ * @since 5.0.0-beta.5
+ * @memberOf util
+ *
+ * @param {*} x any value, checks Object.toString
+ * @return {string} kind-of
+ *
+ * @see util/simpleKindOf
+ *
+ * @example
+ *
+ * kindOf(new Map) //=> 'map'
+ *
+ */
+module.exports = function kindOf(x) {
+ return toS(x).split(' ').pop().replace(/\s\[|\]/g, '').toLowerCase()
+}
diff --git a/src/deps/util/length.js b/src/deps/util/length.js
index d7d9907..fb605e4 100644
--- a/src/deps/util/length.js
+++ b/src/deps/util/length.js
@@ -1,2 +1,13 @@
-// reduces size by hundreds of bytes gzipped...
-module.exports = x => x.length
+const prop = require('../fp/prop')
+
+/**
+ * @desc reduces size by 100s of gzip bytes
+ * @NOTE `length` is a global property of `this` which is `global` or `window`
+ * @name length
+ * @alias getLength
+ * @type {Functon}
+ * @see fp/prop
+ * {@link https://developer.mozilla.org/en-US/docs/Web/API/Window/length window.length}
+ * @see {@link window.length}
+ */
+module.exports = prop('length')
diff --git a/src/deps/util/lengthFromZero.js b/src/deps/util/lengthFromZero.js
new file mode 100644
index 0000000..279bf4f
--- /dev/null
+++ b/src/deps/util/lengthFromZero.js
@@ -0,0 +1,34 @@
+const pipeTwo = require('../fp/pipeTwo')
+const numberFromZero = require('./numberFromZero')
+const length = require('./length')
+
+/**
+ * @desc when length > 1, use length-1
+ * otherwise, when length == 1, use 0
+ * default, use length
+ *
+ * @memberOf util
+ * @since 5.0.0-beta.2
+ * @name lengthFromZero
+ *
+ * @param {Array | Object | number} obj with length
+ * @return {number} obj length from 0
+ *
+ * @see util/length
+ * @see util/lengthMinusOne
+ * @see util/numberFromZero
+ *
+ * @example
+ *
+ * lengthFromZero([1]) //=> 1
+ * lengthFromZero([]) //=> 0
+ * lengthFromZero([1, 2, 3]) //=> 2
+ * lengthFromZero({length: -1}) //=> 0
+ *
+ */
+module.exports = pipeTwo(length, numberFromZero)
+
+// * @TODO lense to use an object, or transform it to one with .length?
+// * const len = prop('length')
+// * // when isObj, use len, otherwise, value
+// * const coerceLength = lense([isObj, len])
diff --git a/src/deps/util/lengthMinusOne.js b/src/deps/util/lengthMinusOne.js
index b0a8d7b..2f0dffc 100644
--- a/src/deps/util/lengthMinusOne.js
+++ b/src/deps/util/lengthMinusOne.js
@@ -1,4 +1,34 @@
+const pipe = require('../fp/pipe')
+const decrement = require('../math/decrement')
const length = require('./length')
-// lengthMinusOne
-module.exports = x => length(x) - 1
+/**
+ * @name lengthMinusOne
+ * @version 2.0.0 <- was going to ensure number stays above 0
+ * @since 5.0.0-beta.1
+ * @memberOf util
+ *
+ * @param {Array | Object} x object with property length
+ * @return {number}
+ *
+ * @example
+ *
+ * lengthMinusOne(['eh']) //=> 1
+ * lengthMinusOne({}) //=> 0
+ * lengthMinusOne({length: -1}) //=> 0
+ * lengthMinusOne({length: 10} ) //=> 10
+ *
+ */
+module.exports = x => decrement(length(x))
+
+// module.exports = pipe(length, decrement)
+// module.exports = x => {
+// const len = length(x)
+//
+// // keep above 0
+// return len <= 0 ? 0 : decrement(length(x))
+// }
+// @TODO
+// module.exports = pipe(length, decrement)
+// module.exports = x => length(x) - 1
+// module.exports = x => decrement(length(x)) || 0
diff --git a/src/deps/util/localGlobal.js b/src/deps/util/localGlobal.js
new file mode 100644
index 0000000..bea9a20
--- /dev/null
+++ b/src/deps/util/localGlobal.js
@@ -0,0 +1,34 @@
+/* eslint no-confusing-arrow: "OFF" */
+/* globals WorkerGlobalScope */
+const isBrowser = require('../is/browser')
+const isNode = require('../is/nodejs')
+const isWebWorker = require('../is/webWorker')
+
+/**
+ * @TODO make function to better ensure we get the right global when we use it
+ * @since 5.0.0-beta.4
+ *
+ * @name localGlobal
+ * @memberOf util
+ *
+ * @return {Global}
+ *
+ * {@link https://github.com/jashkenas/underscore/blob/master/underscore.js#L11 underscore-root}
+ * {@link https://github.com/lodash/lodash/blob/master/.internal/root.js}
+ * @see {@link underscore-root}
+ * @see {@link lodash-root}
+ * @see is/browser
+ * @see is/webWorker
+ * @see is/nodejs
+ *
+ * @example localGlobal() //=> global
+ *
+ */
+module.exports = () =>
+ (
+ isBrowser()
+ ? window
+ : isWebWorker()
+ ? WorkerGlobalScope
+ : global
+ ) || this
diff --git a/src/deps/util/nonEnumerableTypes.js b/src/deps/util/nonEnumerableTypes.js
deleted file mode 100644
index fad6f90..0000000
--- a/src/deps/util/nonEnumerableTypes.js
+++ /dev/null
@@ -1,9 +0,0 @@
-module.exports = [
- 'constructor',
- 'valueOf',
- 'isPrototypeOf',
- 'toString',
- 'propertyIsEnumerable',
- 'hasOwnProperty',
- 'toLocaleString',
-]
diff --git a/src/deps/util/noop.js b/src/deps/util/noop.js
new file mode 100644
index 0000000..28823b8
--- /dev/null
+++ b/src/deps/util/noop.js
@@ -0,0 +1,21 @@
+/**
+ * @name noop
+ *
+ * @memberOf util
+ * @func
+ * @since 5.0.0
+ * @return {void}
+ *
+ * {@link https://github.com/sindresorhus/noop3 noop3}
+ * @see {@link noop3}
+ *
+ * @example
+ *
+ * noop
+ *
+ * @example
+ *
+ * noop()
+ *
+ */
+module.exports = function noop() { /* noop */ }
diff --git a/src/deps/util/numberFromZero.js b/src/deps/util/numberFromZero.js
new file mode 100644
index 0000000..4c39daa
--- /dev/null
+++ b/src/deps/util/numberFromZero.js
@@ -0,0 +1,34 @@
+/* eslint no-confusing-arrow: "OFF" */
+
+/**
+ * @desc when number > 1, use number -1
+ * otherwise, when number == 1, use 0
+ * default, use number
+ *
+ * @memberOf util
+ * @since 5.0.0-beta.6
+ * @name numberFromZero
+ *
+ * @param {number} x number to start from 0 if over 1
+ * @return {number} number from 0
+ *
+ * @see util/length
+ * @see util/lengthMinusOne
+ * @see util/lengthFromZero
+ *
+ * @example
+ *
+ * lengthFromZero([1]) //=> 1
+ * lengthFromZero([]) //=> 0
+ * lengthFromZero([1, 2, 3]) //=> 2
+ * lengthFromZero({length: -1}) //=> 0
+ *
+ */
+module.exports = x =>
+ // over 1, subtract 1
+ x > 1
+ ? x - 1
+ // is 1, use 1, else 0
+ : x === 1
+ ? 1
+ : 0
diff --git a/src/deps/util/props.js b/src/deps/util/props.js
index e9dbfa6..ffd4945 100644
--- a/src/deps/util/props.js
+++ b/src/deps/util/props.js
@@ -7,10 +7,19 @@ const getOwnPropertySymbols = Object.getOwnPropertySymbols
/**
* @desc properties, property symbols, object keys
* ^ all again for prototype
+ * @memberOf util
+ * @since 3.0.0
+ * @version 5.0.0-beta.4 only used in gc (as of 5.0.0-beta.4)
*
* @param {Object} obj object to get properties & symbols from
* @return {Array} properties
*
+ * @see deps/gc
+ * @see deps/utils/nonEnumerableTypes
+ * @see http://2ality.com/2011/07/js-properties.html
+ * @TODO https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptors
+ * `const getOwnPropertyDescriptors = Object.getOwnPropertyDescriptors`
+ *
* @example
* var obj = {key: true}
* allProperties(obj)
@@ -28,13 +37,20 @@ const getOwnPropertySymbols = Object.getOwnPropertySymbols
*
*/
function allProperties(obj) {
- const proto = getPrototypeOf(obj)
- return [].concat(
- getOwnPropertyNames(obj),
- getOwnPropertySymbols(obj),
- ObjectKeys(obj),
- proto ? allProperties(proto) : []
- )
+ return getOwnPropertyNames(obj).concat(getOwnPropertySymbols(obj))
+
+ // const result = []
+ // for (const prop in obj) result.push(prop)
+ // return result
+
+ // flatten(getOwnPropertyNames, getOwnPropertySymbols)
+ // const proto = getPrototypeOf(obj)
+ // return [].concat(
+ // getOwnPropertyNames(obj),
+ // getOwnPropertySymbols(obj)
+ // // ObjectKeys(obj),
+ // // proto ? allProperties(proto) : []
+ // )
}
module.exports = allProperties
diff --git a/src/deps/util/seal.js b/src/deps/util/seal.js
new file mode 100644
index 0000000..150a671
--- /dev/null
+++ b/src/deps/util/seal.js
@@ -0,0 +1,10 @@
+const identity = require('../fp/identity')
+
+/**
+ * {@link https://stackoverflow.com/questions/21402108/difference-between-freeze-and-seal-in-javascript stack-overflow-freeze-vs-seal}
+ * {@link https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/seal mozilla-object-seal}
+ * @see {@link mozilla-object-seal}
+ * @see {@link stack-overflow-freeze-vs-seal}
+ * @name object.Seal
+ */
+module.exports = Object.seal || identity
diff --git a/src/deps/util/simpleKindOf.js b/src/deps/util/simpleKindOf.js
index 9cc70f0..fd1c2ac 100644
--- a/src/deps/util/simpleKindOf.js
+++ b/src/deps/util/simpleKindOf.js
@@ -6,8 +6,19 @@ const isNull = require('../is/null')
* @desc when Array -> 'array'
* when null -> 'null'
* else `typeof x`
- * @param {any} x
+ *
+ * @memberOf util
+ * @since 4.0.0
+ *
+ * @param {any} x value for type
* @return {string} type
+ *
+ * @example
+ *
+ * simpleKindOf([]) //=> 'array'
+ * simpleKindOf(null) //=> 'null'
+ * simpleKindOf({}) //=> 'object'
+ *
*/
module.exports = x => {
return isArray(x)
diff --git a/src/deps/util/size.js b/src/deps/util/size.js
new file mode 100644
index 0000000..731a87b
--- /dev/null
+++ b/src/deps/util/size.js
@@ -0,0 +1,73 @@
+/* eslint guard-for-in: "OFF" */
+/* eslint no-unused-expressions: "OFF" */
+const isNil = require('../is/nullOrUndefined')
+const isNumberPrimitive = require('../is/numberPrimitive')
+const toLength = require('../cast/toLength')
+const hasOwnProperty = require('../util/hasOwnProperty')
+const hasIn = require('../is/hasIn')
+
+/**
+ * @desc returns .length, .size, or a number with the length from `for in` hasOwn
+ * @name size
+ * @memberOf util
+ * @since 5.0.0-beta.6
+ *
+ * @param {Object|Array|Map|*} x value to check length | size
+ * @return {number} size
+ *
+ * {@link http://whereswalden.com/2010/04/06/more-changes-coming-to-spidermonkey-the-magical-__count__-property-of-objects-is-being-removed/ spidermonkey__count__}
+ * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/size mozilla-map-size}
+ * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/size mozilla-set-size}
+ * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/length mozilla-function-length}
+ * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/length mozilla-array-length}
+ * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments/length mozilla-arguments-length}
+ * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/length mozilla-string-length}
+ * {@link https://github.com/jashkenas/underscore/blob/master/underscore.js#L476 underscore-size}
+ * {@link https://github.com/lodash/lodash/blob/master/size.js lodash-size}
+ * {@link https://stackoverflow.com/questions/31014793/is-lodash-size-faster-than-js-length-property stack-overflow-size}
+ * @see {@link spidermonkey__count__}
+ * @see {@link underscore-size}
+ * @see {@link stack-overflow-size}
+ * @see {@link lodash-size}
+ * @see {@link mozilla-string-length}
+ * @see {@link mozilla-array-length}
+ * @see {@link mozilla-arguments-length}
+ * @see {@link mozilla-function-length}
+ * @see {@link mozilla-set-size}
+ * @see {@link mozilla-map-size}
+ *
+ * @example
+ * size(new Set([0, 1])) //=> 2
+ * size(new Map(Object.entries({eh: true}))) //=> 1
+ * size({eh: 0}) //=> 1
+ * size({}) //=> 0
+ * size([]) //=> 0
+ * size([0, 1, 2]) //=> 3
+ * size(($1, $2) => {}) //=> 2
+ * size(() => {}) //=> 0
+ * size(null) //=> 0
+ */
+module.exports = function size(x) {
+ // --- safety all around
+ // decision tree, but sadly, bigger size :,-(
+ if (isNil(x)) {
+ return 0
+ }
+ // @NOTE could put `isPrimitive` after the length and size checks...
+ // but not really needed because look at `toNumber` & +false = 0 etc so
+ else if (isNumberPrimitive(x)) {
+ return toLength(x)
+ }
+ // --- main checks .length, .size, or for-in
+ else if (hasIn(x, 'length')) {
+ return x.length
+ }
+ else if (hasIn(x, 'size')) {
+ return x.size
+ }
+ else {
+ let count = 0
+ for (let property in x) hasOwnProperty(x, property) && ++count
+ return count
+ }
+}
diff --git a/src/deps/util/sleepPromise.js b/src/deps/util/sleepPromise.js
new file mode 100644
index 0000000..e4ade83
--- /dev/null
+++ b/src/deps/util/sleepPromise.js
@@ -0,0 +1,3 @@
+const sleep = (ms = 0) => new Promise(r => setTimeout(r, ms))
+
+module.exports = sleep
diff --git a/src/deps/util/util.js b/src/deps/util/util.js
new file mode 100644
index 0000000..cd0b1b7
--- /dev/null
+++ b/src/deps/util/util.js
@@ -0,0 +1,66 @@
+const assign = require('./assign')
+const from = require('./from')
+const getDescriptor = require('./getDescriptor')
+const getPrototypeOf = require('./getPrototypeOf')
+const hasOwnProperty = require('./hasOwnProperty')
+const keys = require('./keys')
+const keysIn = require('./keysIn')
+const props = require('./props')
+const keysObjOrArray = require('./keysObjOrArray')
+const length = require('./length')
+const lengthFromZero = require('./lengthFromZero')
+const lengthMinusOne = require('./lengthMinusOne')
+const localGlobal = require('./localGlobal')
+const noop = require('./noop')
+const define = require('./define')
+const defineFinal = require('./defineFinal')
+const freeze = require('./freeze')
+const seal = require('./seal')
+const values = require('./values')
+const valuesIn = require('./valuesIn')
+const concat = require('./concat')
+const size = require('./size')
+const type = require('./kindOf')
+const simpleKindOf = require('./simpleKindOf')
+const _typeof = require('./typeof')
+
+const kindOf = type
+
+/**
+ * @member util
+ * @type {Object}
+ */
+module.exports = {
+ // size
+ len: length,
+ lengthFromZero,
+ lengthMinusOne,
+ // preset
+ localGlobal,
+ noop,
+ // types
+ simpleKindOf,
+ typeof: _typeof,
+ type,
+ kindOf,
+ // obj
+ assign,
+ define,
+ defineFinal,
+ freeze,
+ seal,
+ // getters
+ getDescriptor,
+ getPrototypeOf,
+ hasOwnProperty,
+ keysObjOrArray,
+ props,
+ // keyval
+ values,
+ valuesIn,
+ keys,
+ keysIn,
+ // arr
+ concat,
+ from,
+}
diff --git a/src/deps/util/values.js b/src/deps/util/values.js
new file mode 100644
index 0000000..d2254ee
--- /dev/null
+++ b/src/deps/util/values.js
@@ -0,0 +1,7 @@
+const ENV_COMPAT = require('../env/compat')
+
+/**
+ * @TODO need to add build step for env_compat to replace with valuesIn
+ * @type {Function}
+ */
+module.exports = Object.values
diff --git a/src/deps/util/valuesCompat.js b/src/deps/util/valuesCompat.js
new file mode 100644
index 0000000..bc61c88
--- /dev/null
+++ b/src/deps/util/valuesCompat.js
@@ -0,0 +1,38 @@
+// const keys = require('./keys')
+
+/**
+ * Returns a list of all the enumerable own properties of the supplied object.
+ * Note that the order of the output array is not guaranteed across different
+ * JS platforms.
+ * @since 5.0.0-beta.6
+ * @memberOf util
+ *
+ * @param {Object} obj The object to extract values from
+ * @return {Array} An array of the values of the object's own properties.
+ *
+ * @tests keys
+ *
+ * @func
+ * @fork v0.1.0
+ * @category Object
+ * @sig {k: v} -> [v]
+ *
+ * @see valuesIn, keys
+ *
+ * @example
+ *
+ * valuesWhile({a: 1, b: 2, c: 3})
+ * //=> [1, 2, 3]
+ *
+ */
+// module.exports = function values(obj) {
+// const props = keys(obj)
+// let len = props.length
+// const vals = preAllocate(len)
+// let idx = 0
+// while (idx < len) {
+// vals[idx] = obj[props[idx]]
+// idx += 1
+// }
+// return vals
+// }
diff --git a/src/deps/util/valuesIn.js b/src/deps/util/valuesIn.js
new file mode 100644
index 0000000..f82841f
--- /dev/null
+++ b/src/deps/util/valuesIn.js
@@ -0,0 +1,55 @@
+const preAllocated = require('../array/preAllocate')
+const size = require('../util/size')
+
+/**
+ * Returns a list of all the properties, including prototype properties, of the
+ * supplied object.
+ * Note that the order of the output array is not guaranteed to be consistent
+ * across different JS platforms.
+ * @since 5.0.0-beta.1
+ *
+ * @memberOf util
+ *
+ * @param {Object} obj The object to extract values from
+ * @param {boolean} [guard=false] only include own properties @TODO
+ * @return {Array} An array of the values of the object's own and prototype properties.
+ *
+ * @tests keys
+ *
+ * @func
+ * @fork v0.2.0
+ * @category Object
+ * @sig {k: v} -> [v]
+ *
+ * @TODO use loop/
+ * @TODO add `guard`
+ *
+ * {@link https://github.com/jashkenas/underscore/blob/master/underscore.js#L1010 underscore-values}
+ * {@link https://github.com/ramda/ramda/blob/master/src/valuesIn.js ramda-vals-in}
+ * {@link https://github.com/lodash/lodash/blob/master/values.js lodash-values}
+ * @see {@link underscore-values}
+ * @see {@link lodash-values}
+ * @see {@link ramda-vals-in}
+ * @see values, keysIn
+ *
+ * @example
+ *
+ * var F = function() { this.x = 'X'; };
+ * F.prototype.y = 'Y';
+ * var f = new F();
+ * valuesIn(f); //=> ['X', 'Y']
+ *
+ */
+module.exports = function valuesIn(obj, guard) {
+ // @TODO requires an index...
+ // const result = preAllocated(obj)
+ const result = []
+
+ // eslint-disable-next-line
+ for (const prop in obj) {
+ // [result.length]
+ result[result.length] = obj[prop]
+ }
+
+ return result
+}
diff --git a/src/deps/validators/README.md b/src/deps/validators/README.md
index 29a6e23..e9b61d9 100644
--- a/src/deps/validators/README.md
+++ b/src/deps/validators/README.md
@@ -1,3 +1,6 @@
+https://github.com/kensho-technologies/check-more-types
+https://github.com/jquery-validation/jquery-validation/blob/master/src/core.js
+
problem:
- naming and file count for validator + schema was becoming bad
- too many 'factories'
diff --git a/src/deps/validators/schemaBuilder.js b/src/deps/validators/schemaBuilder.js
index 95e095e..2fb55ff 100644
--- a/src/deps/validators/schemaBuilder.js
+++ b/src/deps/validators/schemaBuilder.js
@@ -1,20 +1,9 @@
const ENV_DEVELOPMENT = require('../env/dev')
const dotPropPaths = require('../dot/paths')
const dotGet = require('../dot/get')
-const isStringOrNumber = require('../is/stringOrNumber')
-const isReal = require('../is/real')
-const isBoolean = require('../is/boolean')
-const isRegExp = require('../is/regexp')
-const isError = require('../is/error')
+const isNotNested = require('../is/notNested')
const validationBuilder = require('./validatorBuilder')
-const isNotNested = x =>
- isStringOrNumber(x) ||
- isBoolean(x) ||
- !isReal(x) ||
- isError(x) ||
- isRegExp(x)
-
const validateType = (type, value, nestedSchema) => {
const validator = nestedSchema || validationBuilder(type)
return validator(value)
diff --git a/src/deps/validators/validatorBuilder.js b/src/deps/validators/validatorBuilder.js
index 345a8ae..86f5e85 100644
--- a/src/deps/validators/validatorBuilder.js
+++ b/src/deps/validators/validatorBuilder.js
@@ -7,22 +7,21 @@
*/
const ChainedMap = require('../../ChainedMapBase')
const ENV_DEBUG = require('../env/debug')
-const is = require('../is')
-const isArray = require('../is/array')
-const isReal = require('../is/real')
+const is = require('../is/_core')
const isString = require('../is/string')
const isFunction = require('../is/function')
const dopemerge = require('../dopemerge')
-const camelCase = require('../camel-case')
+const camelCase = require('../string/camelCase')
const not = require('../conditional/not')
-const and = require('../conditional/and')
const or = require('../conditional/or')
-const all = require('../conditional/all')
+const isArrayOf = require('../is/arrayOf')
+const isNotRealOrIsEmpty = require('../is/notRealOrIsEmpty')
+const replace = require('../fp/replace')
let validators = new ChainedMap()
// eslint-disable-next-line
-const stripArithmeticSymbols = x => x.replace(/[?\[\]!\|]/g, '')
+const stripArithmeticSymbols = replace(/[?\[\]!\|]/g, '')
const escapedKey = x => camelCase('is-' + x)
const enummy = enums => x => enums === x || enums.includes(x)
@@ -77,15 +76,6 @@ const addTypes = types =>
addTypes(is)
-// ----
-// @NOTE: putting these as functions increased size 20 bytes: worth it
-// ----
-
-// @SIZE: another 10bytes for these fns
-const isNotRealOrIsEmptyString = and(not(isReal), x => x === '')
-
-// const isArrayOf = predicate => x => isArray(x) && x.every(predicate)
-const isArrayOf = predicate => and(isArray, all(predicate))
const includesAndOr = x => x.includes('|') || x.includes('&')
/**
@@ -186,7 +176,7 @@ function arithmeticTypeFactory(fullKey) {
const typeOrArrayOrType = `${key}[]`
const notType = `!${key}`
- const isValidOrNotRealOrEmptyStr = or(fn, isNotRealOrIsEmptyString)
+ const isValidOrNotRealOrEmptyStr = or(fn, isNotRealOrIsEmpty)
const isValidOrArrayOfValid = or(fn, isArrayOf(fn))
if (doesNotHave(optionalType)) {
set(optionalType, isValidOrNotRealOrEmptyStr)
@@ -226,22 +216,22 @@ function arithmeticTypeFactory(fullKey) {
* // functionType
* const isString = x => typeof x === 'string'
* builder(isString)
- * // => isString
+ * //=> isString
*
* @example
*
* // stringType (built in, or custom-keyed validator, or eqeqeq)
* builder('string')
- * // => isString
+ * //=> isString
*
* const enummy = builder('enum')
- * // => x => ['enum'].includes(x)
+ * //=> x => ['enum'].includes(x)
*
* @example
*
* // arithmeticType
* builder('string|string[]')
- * // => isString || isArrayOf(isString)
+ * //=> isString || isArrayOf(isString)
*
*/
function builder(fullKey) {
diff --git a/src/index.js b/src/index.js
index d5df80e..d4c1882 100644
--- a/src/index.js
+++ b/src/index.js
@@ -13,11 +13,12 @@ const FactoryChain = require('./FactoryChain')
const MethodChain = require('./MethodChain')
// composer
const compose = require('./compose')
+const construct = require('./deps/fp/construct')
// export
const exp = compose()
-exp.chainable = parent => new exp(parent)
-exp.builder = obj => new MethodChain(obj)
+exp.chainable = construct(0, exp)
+exp.builder = construct(0, MethodChain)
exp.Chain = exp
exp.compose = compose
@@ -26,7 +27,7 @@ exp.traverse = traverse
exp.addMethodFactories = MethodChain.add
exp.toArr = require('./deps/to-arr') // exp.toarr =
-exp.camelCase = require('./deps/camel-case')
+exp.camelCase = require('./deps/string/camelCase')
exp.dot = require('./deps/dot')
exp.matcher = require('./deps/matcher')
exp.reduce = require('./deps/reduce')
@@ -34,6 +35,9 @@ exp.clean = require('./deps/reduce/clean')
exp.meta = require('./deps/meta')
exp.eq = require('./deps/traversers/eq')
exp.types = require('./deps/validators')
+exp.encase = require('./deps/encase')
+exp.curry = require('./deps/fp/curry')
+exp.replace = require('./deps/fp/replace')
exp.addTypes = exp.types.addTypes
@@ -48,7 +52,7 @@ exp.MethodChain = MethodChain
exp.MergeChain = MergeChain
exp.merge = dopemerge
-exp.is = require('./deps/is')
+exp.is = require('./deps/is/_core')
ObjectAssign(exp, exp.is)
diff --git a/src/plugins/decorate.js b/src/plugins/decorate.js
index 022bad3..6364040 100644
--- a/src/plugins/decorate.js
+++ b/src/plugins/decorate.js
@@ -1,4 +1,4 @@
-const DECORATED_KEY = require('../deps/meta/decorated')
+const DECORATED_KEY = require('../deps/meta/DECORATED_KEY')
const meta = require('../deps/meta')
/**
diff --git a/src/plugins/schema.js b/src/plugins/schema.js
index 6a7b985..ff9d73c 100644
--- a/src/plugins/schema.js
+++ b/src/plugins/schema.js
@@ -43,10 +43,7 @@ module.exports = function schema(obj) {
const key = keys[k]
const value = obj[key]
- // parent.method
- // ? parent.method(key)
- // :
- //
+ // parent.method ? parent.method(key) :
let builder = this.newThis().name(key) // MethodChain
// @TODO: PLUCK METHOD FOR USING VALID KEYS
diff --git a/test/ChainedMap.js b/test/ChainedMap.js
index 7e7bac5..a9ea457 100644
--- a/test/ChainedMap.js
+++ b/test/ChainedMap.js
@@ -164,6 +164,7 @@ test('when(has)', () => {
expect.assertions(6)
const map = new ChainedMap()
map.set('truth', true).set('lies', false)
+
const right = instance => {
expect(instance).toBe(map)
instance.set('alpha', 'a')
diff --git a/test/ChainedSet.js b/test/ChainedSet.js
index 9b81645..bb6a30a 100644
--- a/test/ChainedSet.js
+++ b/test/ChainedSet.js
@@ -132,6 +132,7 @@ test('prepend', () => {
expect(set.prepend('beta')).toBe(set)
expect(set.store.has('beta')).toBe(true)
expect([...set.store]).toEqual(['beta', 'alpha'])
+ expect([...set.store]).toEqual(set.values())
})
test('clear', () => {
diff --git a/test/MethodChain.js b/test/MethodChain.js
index ed9b03d..38370d0 100644
--- a/test/MethodChain.js
+++ b/test/MethodChain.js
@@ -1,5 +1,5 @@
const log = require('fliplog')
-const {Chain, MethodChain} = require('../src')
+const {Chain, MethodChain, merge} = require('../src')
const {isUndefined, isObj, isFunction} = Chain.is
@@ -29,9 +29,16 @@ test('.decorate(obj)', () => {
const chain = new Chain()
const obj = {}
chain.method('ehOh').decorate(obj).build()
- expect(typeof obj.ehOh).toBe('function')
+ expect(isFunction(obj.ehOh)).toBe(true)
obj.ehOh(1)
expect(chain.get('ehOh')).toBe(1)
+
+ // const chain2 = new Chain()
+ // const obj2 = {}
+ // chain2.method('ehOh').decorate(obj2).build()
+ // expect(isFunction(obj2.ehOh)).toBe(true)
+ // obj2.ehOh(1)
+ // expect(chain2.get('ehOh')).toBe(1)
})
test('.method(object) .call() & .get().set()', () => {
@@ -83,6 +90,37 @@ test('.plugin', () => {
expect(chain.eh()).toBe(1)
})
+test.only('factory method - automerge !!!!', () => {
+ // also add this merge plugin factory
+ function autoMergeMethodFactory(name, parent) {
+ function autoMerge(arg) {
+ if (isUndefined(arg)) {
+ return this.get(name)
+ }
+ else if (this.has(name)) {
+ return this.set(name, merge(this.get(name), arg))
+ }
+ else {
+ return this.set(name, arg)
+ }
+ }
+
+ // so we know if we defaulted them
+ autoMerge.mergeFactory = true
+
+ return this.onSet(autoMerge).onGet(autoMerge).onCall(autoMerge)
+ }
+
+ // @TODO: extend with `mergeName` to merge in
+ // @example
+ // .methods('eh')
+ // .eh([])
+ // .mergeEh(1)
+ MethodChain.add({
+ autoMerge: autoMergeMethodFactory,
+ })
+})
+
test('addFactoryMethods', () => {
const {addMethodFactories} = require('../src')
diff --git a/test/TransformObserve.js b/test/TransformObserve.js
new file mode 100644
index 0000000..d2689f7
--- /dev/null
+++ b/test/TransformObserve.js
@@ -0,0 +1,480 @@
+const log = require('fliplog')
+const isUrl = require('../src/deps/is/url')
+const replace = require('../src/deps/fp/replace')
+const pipe = require('../src/deps/fp/pipe')
+const curry = require('../src/deps/fp/curry')
+const bind = require('../src/deps/fp/bind')
+const includesCount = require('../src/deps/fp/includesCount')
+const toArr = require('../src/deps/to-arr')
+const camelCase = require('../src/deps/string/camelCase')
+const not = require('../src/deps/conditional/not')
+const eq = require('../src/deps/traversers/eq')
+const isEmpty = require('../src/deps/is/empty')
+const isFunction = require('../src/deps/is/function')
+const isString = require('../src/deps/is/stringPrimitive')
+const isMap = require('../src/deps/is/map')
+const debounce = require('../src/deps/_/debounce')
+const throttle = require('../src/deps/_/throttle')
+const objToMap = require('../src/deps/cast/objToMap')
+const {Chain, escapeDot, trim} = require('../exports')
+const getMeta = require('../src/deps/meta')
+const chainPlus = require('../src/chainPlus')
+
+const notEmpty = not(isEmpty)
+
+const isNotFile = x =>
+ !isUrl(x) &&
+ x.includes('.') &&
+ !x.includes('.js') &&
+ !x.includes('.ts') &&
+ includesCount(x, '.') >= 2
+
+const hrefStripTransform = href => {
+ if (!href) return ''
+ return href.replace(/\n/, '')
+}
+const hrefDotToAnchorTransform = href => {
+ if (!href) return href || ''
+ else if (isNotFile(href)) return replace(href, href.lastIndexOf('.'), '#')
+ else return href
+}
+
+const getEntryLinks = (block, find) =>
+ block
+ .split('*')
+ .filter(line => line.includes(find))
+ .filter(line => (find === '@link' ? !line.includes('@see') : line))
+ .map(trim)
+ // .map(replace('*', ''))
+ .map(link => {
+ const pieces = link
+ .replace('{@link', '')
+ .replace('}\n', '')
+ .replace(/\}\s?/, '')
+ .split(' ')
+ .filter(notEmpty)
+ .map(trim)
+
+ // @link vs @see vs @see {@link}
+ if (pieces.length === 2) {
+ return {href: pieces[0], label: pieces[1]}
+ }
+ else if (pieces.length === 1) {
+ return {label: pieces[0]}
+ }
+ else {
+ // const e = new Error('@link tag with 0 parts ' + block)
+ // console.error(e)
+ return {}
+ }
+ })
+
+let links = new Map()
+
+// we should only ever parse 2x?
+// let partsMap = new Map()
+
+
+const getChain = () => {
+ const chain = new Chain().methods(['label', 'href']).autoGetSet().build()
+ return chainPlus(chain)
+}
+
+const cacheLinks = parts =>
+ parts
+ .filter(link => link.href !== '@see' && link.label !== '@see')
+ .forEach(link => links.set(link.label, link.href))
+
+const toRepoSearch = x =>
+ `https://github.com/fluents/chain-able/search?utf8=%E2%9C%93&q=${x}&type=`
+
+// @TODO abstract to render anything referencing any other files to links
+/* prettier-ignore */
+function remapSee(entry) {
+ const linesWithLinkTag = getEntryLinks(entry, '@link')
+ cacheLinks(linesWithLinkTag)
+
+ const linesWithSeeTag = getEntryLinks(entry, '@see')
+
+ // require('fliplog').quick({linesWithSeeTag, entry})
+
+ // mock `find`
+ const find = x => (x.includes('is/eh') ? [x] : [])
+
+
+ const remappedSee = linesWithSeeTag
+ .map(link => {
+ const chain = getChain()
+ // chain.clear()
+
+ // chain.dot(false)
+
+ // let label = link.label
+ // let href = link.href
+
+ // find -----
+ let found = find(link.label)
+ let foundRel
+ if (link.label && found.length) {
+ link.href = found
+ // foundRel = found.map(files.toRel)
+ // const extractedLink = foundRel.shift()
+ // href = files.toRepoPath(extractedLink)
+ }
+
+ // transform -----
+
+ // chain.transform('label', [
+ // label => links.has(label) ?
+ // ])
+
+ // const labelIs = chain.propIs('label')
+ // const hrefIs = chain.propIs('href')
+ // const setLabel = chain.set('label')
+ // const setHref = chain.set('href')
+ // const getLabel = chain.view('label')
+ // const setHref = chain.view('href')
+ const {
+ labelIs,
+ labelNot,
+ setLabel,
+ getLabel,
+ labelEq,
+ transformLabel,
+ labelTransforms,
+ observeLabel,
+ } = chain.lense('label')
+
+ const hrefLense = chain.lense('href')
+ const {
+ hrefIs,
+ hrefEq,
+ hrefNot,
+ setHref,
+ getHref,
+ transformHref,
+ escapeDotHref,
+ freezeHref,
+ } = hrefLense
+
+ // escapeDotHref()
+ // require('fliplog').bold('lense').quick(chain.lense('href'))
+ // require('fliplog').bold('lense').quick(Object.keys(chain.lense('href')))
+ // require('fliplog').bold('lense').quick(chain.lense('href').setHref)
+
+ // we have both label, and href...
+
+ // const setHrefToRepoSearch = () => pipe(toRepoSearch, setHref)
+ const setHrefToRepoSearch = () => setHref(toRepoSearch(getHref()))
+ const labelToHref = pipe(setHref, getLabel)
+ const hrefToLabel = pipe(setLabel, getHref)
+
+ observeLabel(data => {
+ const label = data.label
+ if (links.has(label)) {
+ setHref(links.get(label))
+ freezeHref()
+ }
+ })
+
+ // const {
+ // // query
+ // hrefIs,
+ // hrefEq,
+ // hrefNot,
+ // // getset
+ // setHref,
+ // getHref,
+ // // transform
+ // transformHref,
+ // observeTransform,
+ // // aliasable for better naming
+ // transformObserve,
+ // // presets
+ // escapeDotHref,
+ // freezeHref,
+ // } = chain.lense('href')
+ //
+ // const setLinkAsLabel = pipe(getLink, setHref)
+ //
+ // observeLabel(({label}) => {
+ // if (hasLinkFor(label)) {
+ // setLinkAsLabel(label)
+ // freezeHref()
+ // }
+ // })
+
+
+ chain
+ .ifElse(c => labelIs('@see') && getHref())
+ .then(c => hrefToLabel())
+
+ chain
+ .ifElse(c => {
+ // console.log('HREF', getHref(), getLabel(), chain.get('href'), chain.get('label'), chain)
+ return hrefEq('@see') && getLabel()
+ })
+ .then(c => {
+ console.log('not see...')
+ return labelToHref()
+ })
+
+ chain
+ .ifElse(c =>
+ // chain.propIs('label', isUrl) &&
+ // chain.propIsNot('href', isUrl)
+ labelIs(isUrl) &&
+ hrefNot(isUrl)
+ )
+ .then(c => labelToHref())
+ .elseIf(c => hrefNot(isUrl))
+ .then(c => setHrefToRepoSearch())
+
+ // github.com/Class.method //=> github.com/Class#method
+ // transformHref(hrefDotToAnchorTransform)
+
+ observeLabel(data => {
+ const {label} = data
+ console.log({label, 'has': links.has(label)})
+ console.log({[label]: links.get(label)})
+
+ if (links.has(label)) {
+ setHref(links.get(label))
+ // chain.set('href', links.get(label))
+ freezeHref()
+ }
+ })
+
+ // grab it from the nameMap
+ // labelTransforms([
+ // label => {
+ // const href = getHref()
+ // if (labelEq('@see') && href) return href
+ // return label
+ // }]
+ // )
+ transformLabel(label => {
+ const href = getHref()
+ if (labelEq('@see') && href) return href
+ return label
+ })
+ // toRepoSearch()
+
+ chain.setSilent('label', link.label).setSilent('href', link.href)
+ chain.label(link.label).href(link.href)
+
+ // @TODO
+ // chain.meta.delete('transformers')
+ // require('fliplog').quick({chain, links, meta: chain.meta})
+
+ const {href, label} = chain.entries()
+ return {href, label}
+ })
+ // .filter(filterNotReal)
+
+ // log.data({remappedSee}).echo()
+
+ return remappedSee
+}
+
+
+const docblock = `
+ /**
+ * @desc spreads the entries from ChainedMap.store.values
+ * allocates a new array, adds the values from the iterator
+ *
+ * @memberOf Chainable
+ * @since 0.4.0
+ *
+ * @return {Array} toArr(this.store.values())
+ *
+ * {@link https://kangax.github.io/compat-table/es6/#test-Array_static_methods compat-array-static-methods}
+ * {@link https://stackoverflow.com/questions/20069828/how-to-convert-set-to-array set-to-array}
+ * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/values mozilla-map-values}
+ * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/values mozilla-set-values}
+ *
+ * @see {@link mozilla-map-values}
+ * @see {@link mozilla-set-values}
+ * @see {@link compat-array-static-methods}
+ * @see {@link set-to-array}
+ * @see is/eh
+ * @see not/found
+ *
+ * @example
+ *
+ * const chain = new Chain()
+ * chain.set('eh', 1)
+ * chain.values()
+ * //=> [1]
+ *
+ */
+`
+
+const _expectedLinks = {
+ 'compat-array-static-methods': 'https://kangax.github.io/compat-table/es6/#test-Array_static_methods',
+ 'set-to-array': 'https://stackoverflow.com/questions/20069828/how-to-convert-set-to-array',
+ 'mozilla-map-values': 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/values',
+ 'mozilla-set-values': 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/values',
+}
+
+const expectedLinks = objToMap(_expectedLinks)
+// _expectedLinks
+
+// throttle, merge all logs into 1
+const todo = x => console.log('@TODO: ', x)
+
+todo('lense.set')
+todo('lense.freeze')
+todo('lense.destructure')
+todo('lense.get')
+todo('lense.has')
+todo('lense.escape')
+todo('lense.eq')
+todo('lense.is')
+todo('lense.not')
+todo('lense.silent')
+todo('lense.observe')
+todo('lense.transform')
+todo('ifElse')
+todo('unobserve')
+todo('untransform')
+todo('propIs')
+todo('boundMethods')
+todo('bind')
+
+test('cast objToMap', () => {
+ const linkNames = Object.keys(_expectedLinks)
+ expect(isMap(expectedLinks)).toBe(true)
+ expect(expectedLinks.size).toBe(linkNames.length)
+
+ const expectEqual = (x, y) => expect(x).toEqual(y)
+ linkNames.forEach(name =>
+ expectEqual(expectedLinks.get(name), _expectedLinks[name]))
+})
+
+test.skip('remapsee', () => {
+ const remapped = remapSee(docblock)
+ log.quick({remapped})
+})
+
+
+// -----
+
+// href = hrefDotToAnchorTransform(href)
+// transform
+// if (links.has(label)) {
+// href = links.get(label)
+// }
+// if (label === '@see' && href) {
+// label = href
+// }
+// if (href === '@see' && label) {
+// href = label
+// }
+// if (isUrl(label) && !isUrl(href)) {
+// href = label
+// }
+// not a url, cannot find it, add search
+// else if (!isUrl(href) && href) {
+// href = toRepoSearch(href)
+// }
+
+// const transformed = presets(href, label)
+// href = transformed.href
+// label = transformed.label
+
+// -------
+
+// // .methods(['label', 'href'])
+// // .onInvalid(invalidError => {
+// // // ignore invalid links
+// // })
+// // .type('string')
+// // .build()
+//
+//
+// // @TODO need `bestMatch`
+// // const foundMatching = found
+// // .filter(file => file && isMatch(file, link.label))
+//
+// if (found.length > 1) {
+// // found = found
+// // .filter(file => file && isMatch(getFileName(file), link.label))
+// }
+// log.magenta('found').data(found).echo()
+//
+// const whenFound = _see => {
+// found = found.map(files.toRel)
+//
+// if (found.length) {
+// // .filter(isMatch(link.label))
+// const extractedLink = found.shift() || ''
+//
+// // when it's a property
+// if (extractedLink.includes('.')) {
+// // @TODO
+// }
+//
+// see.set('href', files.toRepoPath(extractedLink))
+// }
+// }
+// const whenNotFound = _see => {
+// // _see.set('href', link.href)
+// }
+//
+// // we want it before the label transforms
+// see.when(found.length, whenFound, whenNotFound)
+//
+// // @see => http
+// see.transform('href', x => (x === '@see' ? see.get('label') || '' : x))
+//
+// // use label if it's a url
+// see.transform('href', href => {
+// const label = see.get('label')
+// if (isUrl(label) && !isUrl(href)) return label
+// else return href
+// })
+//
+// // if href is not a url, transform toGithubRepoPath
+// see.transform('href', href => {
+// const label = see.get('label')
+// if (isUrl(href)) return href
+// else return files.toRepoPath(href || label || '')
+// // else return href
+// })
+//
+// // @example
+// // github.com/Class.method //=> github.com/Class#method
+// see.transform('href', hrefDotToAnchorTransform)
+//
+// // can be scoped, no need for +1 func
+// // strip new lines and default fallback
+// see.transform('href', hrefStripTransform)
+//
+//
+// // grab it from the nameMap
+// see.transform('label', label => {
+// if (links.has(label)) {
+// see.set('href', links.get(label))
+// }
+// return label
+// })
+// see.transform('label', label => {
+// const href = see.get('href')
+// if (label === '@see' && href) return href //return humanizeLinkLabel(href)
+// return label
+// })
+// // ugh this messes with the href...
+// // need to tighten up the expected output add more tests
+// see.transform('label', label => {
+// if (isUrl(label)) {
+// // return humanizeLinkLabel(label)
+// }
+// return label
+// })
+//
+// // log.data({link, found}).echo()
+// // see.when(found.length, whenFound, whenNotFound)
+// see.label(link.label).href(link.href)
+//
+// return see.entries()
diff --git a/test/TraverseChain.js b/test/TraverseChain.js
index 76d766c..555815b 100644
--- a/test/TraverseChain.js
+++ b/test/TraverseChain.js
@@ -1,5 +1,5 @@
const log = require('fliplog')
-const {Chain, matcher} = require('../src')
+const {Chain, matcher, isNumber} = require('../src')
const TraverseChain = require('../src/TraverseChain')
test('traversal with function callback for vals and keys', () => {
@@ -24,7 +24,7 @@ test('traversal with .onMatch', () => {
.vals([/true/])
.onMatch((current, traverser) => {
// log.quick(traverser)
- log.data(traverser, current, traverser.remove, traverser.update).echo()
+ // log.data(traverser, current, traverser.remove, traverser.update).echo()
expect(traverser.path.join('.')).toEqual('one.two')
expect(current === true).toBe(true)
expect(typeof traverser.remove === 'function').toBe(true)
@@ -109,6 +109,7 @@ test('.traverse(true)', () => {
},
matchme: 'minime',
notme: 'eh',
+ num: 100,
},
},
}
@@ -119,7 +120,7 @@ test('.traverse(true)', () => {
.merge(eh)
.traverse(true)
.keys([/super/, /parser/, /store/, /meta/, /className/])
- .vals([/minime/])
+ .vals([/minime/, isNumber])
.call(true)
expect(cleaned).toEqual({
diff --git a/test/__testsetup.js b/test/__testsetup.js
index c677b76..0d2c212 100644
--- a/test/__testsetup.js
+++ b/test/__testsetup.js
@@ -1,3 +1,54 @@
+let path
+const {encase} = require('../exports')
+
+// const requireResolve = encase(require.resolve)
+// requireResolve.onValid(x => path = x).call('../build/FAKEROOT/_exported')
+
+try {
+ path = require.resolve('../build/FAKEROOT/_exported')
+}
+catch (e) {
+ //
+}
+
+// if (path) {
+// const Chainable = require(path)
+// const {filterMap} = Chainable
+//
+// const izKeys = Object.keys(Chainable).filter(key => key.startsWith('is'))
+// const filterIzKeys = (value, key) => izKeys.includes(key)
+// const isses = filterMap(Chainable, filterIzKeys, value => value)
+// require('fliplog').prettyformat(isses).exit()
+// }
+
+const extend = (fn, key) => {
+ expect.extend({
+ toBeDivisibleBy(received, argument) {
+ const pass = received % argument == 0
+ if (pass) {
+ return {
+ message: () =>
+ `expected ${received} not to be divisible by ${argument}`,
+ pass: true,
+ }
+ }
+ else {
+ return {
+ message: () => `expected ${received} to be divisible by ${argument}`,
+ pass: false,
+ }
+ }
+ },
+ })
+}
+
+global.eq = (a, b) => {
+ expect(a).toEqual(b)
+}
+global.neq = (a, b) => {
+ expect(a).not.toEqual(b)
+}
+
global.fail = reason => {
console.log('FAILED: ', reason)
expect(true).toBe(false)
diff --git a/test/_stress.js b/test/_stress.js
index b426be7..b659597 100644
--- a/test/_stress.js
+++ b/test/_stress.js
@@ -1,4 +1,8 @@
module.exports = cb => {
+ const evilArray = []
+ evilArray[-1] = 'boo'
+ const emojiString = '👻'
+
const fullmap = new Map()
const fullset = new Set()
fullset.add('eh')
@@ -34,6 +38,8 @@ module.exports = cb => {
// const xml = g.XMLHttpRequest ? new g.XMLHttpRequest() : require('http')
const datas = [
+ evilArray,
+ emojiString,
generatorFunction,
class {},
[],
diff --git a/test/_traverse.js b/test/_traverse.js
index 6225f63..136372e 100644
--- a/test/_traverse.js
+++ b/test/_traverse.js
@@ -6,10 +6,33 @@ const log = require('fliplog')
const traverse = require('../src/deps/traverse')
const isArray = require('../src/deps/is/array')
const isObj = require('../src/deps/is/obj')
+const isNumber = require('../src/deps/is/number')
+const isReal = require('../src/deps/is/real')
-const {eq} = traverse
+const {eq, copy} = traverse
const deepEqual = eq
+test('pre-copy eq to themselves invariant for environment', () => {
+ const date = new Date(0, 0, 0, 0)
+ expect(date).toBe(date)
+
+ const error = new Error('ehror')
+ expect(error).toBe(error)
+
+ const regexp = new RegExp('../', 'gmi')
+ expect(regexp).toBe(regexp)
+})
+test('copy', () => {
+ const date = new Date(0, 0, 0, 0)
+ expect(copy(date)).not.toBe(date)
+
+ const error = new Error('ehror')
+ expect(copy(error)).not.toBe(error)
+
+ const regexp = new RegExp('../', 'gmi')
+ expect(copy(regexp)).not.toBe(regexp)
+})
+
test('deepDates', () => {
expect.assertions(2)
@@ -226,11 +249,64 @@ test('Fn vs Fn', () => {
console.log('noop != noops')
expect(!deepEqual(noop, noops)).toBeTruthy()
})
+test('Fn vs Fn - string diff', () => {
+ function noop() {
+ /* noop */
+ }
+ function noops() {
+ /* noops */
+ }
+ noop()
+ noops()
+
+ expect(deepEqual(noop, noop)).toBe(true)
+ expect(deepEqual(noop, noops)).toBe(false)
+})
test('ObjKeys', () => {
expect(
!deepEqual({one: true, two: true}, {one: true, three: false})
).toBeTruthy()
})
+test.skip('supports.equals', () => {
+ const alwaysFalse = {
+ equals() {
+ return false
+ },
+ }
+ const alwaysTrue = {
+ equals() {
+ return true
+ },
+ }
+
+ expect(deepEqual(alwaysFalse, alwaysTrue)).toBe(false)
+ expect(deepEqual(alwaysTrue, alwaysFalse)).toBe(true)
+})
+
+test.skip('eq: simple primitives', () => {
+ // 'null == undefined'
+ expect(eq(null, undefined)).toBe(true)
+
+ // 'null == null'
+ expect(eq(null, null)).toBe(true)
+
+ // '1 == 1'
+ expect(eq(1, 1)).toBe(true)
+ // '"1" == 1'
+ expect(eq(1, '1')).toBe(true)
+
+ // '"1" ~= 1'
+ expect(eq(1, '1', true)).toBe(true)
+
+ // '1 == 0'
+ expect(eq(1, 0)).toBe(true)
+
+ // '1 == [1]'
+ expect(eq(1, [1])).toBe(true)
+
+ // '[1] == [1]'
+ expect(eq([1], [1])).toBe(true)
+})
test.skip('edge', () => {
// '[Number(4)], [4]'
@@ -267,29 +343,6 @@ test.skip('edge', () => {
// expect(deepEqual(new Promise(r => r()).toBe(true), new Error('2')).toBe(true))
// expect(deepEqual(new Promise(r => r()).toBe(true), 'string')).toBe(true)
- // 'null == undefined'
- expect(eq(null, undefined)).toBe(true)
-
- // 'null == null'
- expect(eq(null, null)).toBe(true)
-
- // '1 == 1'
- expect(eq(1, 1)).toBe(true)
- // '"1" == 1'
- expect(eq(1, '1')).toBe(true)
-
- // '"1" ~= 1'
- expect(eq(1, '1', true)).toBe(true)
-
- // '1 == 0'
- expect(eq(1, 0)).toBe(true)
-
- // '1 == [1]'
- expect(eq(1, [1])).toBe(true)
-
- // '[1] == [1]'
- expect(eq([1], [1])).toBe(true)
-
// '{1, 3} == {1, 3}'
expect(eq({one: 2, three: 3}, {one: 2, three: 3})).toBe(true)
@@ -349,8 +402,8 @@ test('stringify', () => {
// console.log('before', t.key, t.path.join(''), '\n\n')
// s += '\nbefore\n'
- if (isArray(t.iteratee)) s += '['
- else if (isObj(t.iteratee)) s += '{'
+ if (isArray(t.node)) s += '['
+ else if (isObj(t.node)) s += '{'
})
trav.pre(traverser => {
@@ -358,7 +411,7 @@ test('stringify', () => {
// console.log('pre', traverser.key, traverser.path.join(''), '\n\n')
const key = traverser.key || traverser.path.join('')
- if (key && isObj(traverser.iteratee) && !isArray(traverser.iteratee)) {
+ if (key && isObj(traverser.node) && !isArray(traverser.node)) {
s += '"' + key + '"' + ':'
}
})
@@ -367,8 +420,8 @@ test('stringify', () => {
// console.log('after')
if (s.endsWith(',')) s = s.slice(0, -1)
// s += '\nafter\n'
- if (isArray(t.iteratee)) s += ']'
- else if (isObj(t.iteratee)) s += '}'
+ if (isArray(t.node)) s += ']'
+ else if (isObj(t.node)) s += '}'
})
trav.post(child => {
// console.log('post', child)
@@ -486,6 +539,44 @@ test('stop', () => {
// expect(acc.join(' ')).toEqual('9 30 22')
// })
+// ----- remove
+test('traverse no argument', () => {
+ traverse().forEach(() => {})
+})
+
+test('remove arr', () => {
+ traverse([]).forEach((key, val, it) => {})
+
+ const arr = [0]
+ traverse(arr).forEach((key, val, it) => it.remove())
+ expect(arr.filter(isReal)).toEqual([])
+
+ let arrString = [0, 100, 10, 100, 'not number', 200, 1000]
+ traverse(arrString).forEach((key, val, it) => {
+ log.bold(key).data(val).echo()
+ if (isNumber(val)) it.remove()
+ })
+
+ expect(arrString.filter(isReal)).toEqual(['not number'])
+})
+
+test('remove obj', () => {
+ const emptyObj = {}
+ traverse(emptyObj).forEach((key, val, it) => {})
+ expect(emptyObj).toEqual(emptyObj)
+
+ const obj = {eh: true}
+ traverse(obj).forEach((key, val, it) => it.remove())
+ expect(obj).toEqual({})
+
+ const objNumber = {eh: true, num: 100}
+ traverse(objNumber).forEach((key, val, it) => {
+ if (!isNumber(val)) it.remove()
+ })
+
+ expect(objNumber).toEqual({num: 100})
+})
+
// --- leaves.js
test('leaves test', () => {
var acc = []
@@ -613,15 +704,15 @@ test.skip('circClone - @FIXME', () => {
console.log(clone.x[3][2] !== obj)
})
-// test('circMapScrub', () => {
-// var obj = {a: 1, b: 2}
-// obj.c = obj
-//
-// var scrubbed = traverse(obj).map(function(node) {
-// if (this.circular) this.remove()
-// })
-// expect(Object.keys(scrubbed).sort()).toEqual(['a', 'b'])
-// expect(deepEqual(scrubbed, {a: 1, b: 2}, true)).toBeTruthy()
-//
-// expect(deepEqual(obj.c, obj, true)).toBeTruthy()
-// })
+test.skip('circMapScrub', () => {
+ var obj = {a: 1, b: 2}
+ obj.c = obj
+
+ var scrubbed = traverse(obj).map(function(node) {
+ if (this.circular) this.remove()
+ })
+ expect(Object.keys(scrubbed).sort()).toEqual(['a', 'b'])
+ expect(deepEqual(scrubbed, {a: 1, b: 2}, true)).toBeTruthy()
+
+ expect(deepEqual(obj.c, obj, true)).toBeTruthy()
+})
diff --git a/test/cast/toPairs.js b/test/cast/toPairs.js
new file mode 100644
index 0000000..b28ee9f
--- /dev/null
+++ b/test/cast/toPairs.js
@@ -0,0 +1,19 @@
+const toPairs = require('../../src/deps/cast/toPairs')
+
+const eq = (x, y, msg) => expect(x).toEqual(y)
+
+describe('toPairs', function() {
+ it('converts an object into an array of two-element [key, value] arrays', function() {
+ eq(toPairs({a: 1, b: 2, c: 3}), [['a', 1], ['b', 2], ['c', 3]])
+ })
+
+ it('only iterates the object\'s own properties', function() {
+ var F = function() {
+ this.x = 1
+ this.y = 2
+ }
+ F.prototype.protoProp = 'you can\'t see me'
+ var f = new F()
+ eq(toPairs(f), [['x', 1], ['y', 2]])
+ })
+})
diff --git a/test/deps/toarr.js b/test/cast/toarr.js
similarity index 100%
rename from test/deps/toarr.js
rename to test/cast/toarr.js
diff --git a/test/compose.js b/test/compose.js
index b4f3354..b7e4e76 100644
--- a/test/compose.js
+++ b/test/compose.js
@@ -5,7 +5,7 @@ const {compose} = require('../src')
const PreComposed = compose()
-class Composed extends PreComposed {}
+class Composed extends PreComposed { }
test('composable', () => {
const map = new Composed({isParent: true})
@@ -13,13 +13,20 @@ test('composable', () => {
})
test('compose custom extensions', () => {
- class CustomTarget {}
+ class CustomTarget {
+ constructor(parent) {
+ this.ok = true
+ }
+ }
const CustomComposer = SuperClass => {
- class Customed extends SuperClass {}
+ class Customed extends SuperClass {
+
+ }
return Customed
}
const CustomComposed = compose(CustomTarget, [CustomComposer])
const map = new CustomComposed()
+ expect(map.ok).toBe(true)
expect(map instanceof CustomTarget).toBe(true)
})
@@ -57,13 +64,35 @@ test('.className', () => {
})
test('extend class as decorator', () => {
+ class CustomTarget { }
+ const CustomComposer = SuperClass => {
+ class Customed extends SuperClass { }
+ return Customed
+ }
+ const CustomComposed = compose(CustomTarget, [CustomComposer])
+
class Target {
get extended() {
return true
}
}
- class ComposedTarget extends compose(Target) {}
+ class Target2 {
+ eh() { }
+ get extended2() {
+ return true
+ }
+ }
+ const CT = compose(Target, undefined)
+ class ComposedTarget extends CT { }
+ class ComposedTarget2 extends compose(Target2) { }
const map = new ComposedTarget({isParent: true})
+ const map2 = new ComposedTarget2({isParent: true})
+ // log.prettyformat(new CustomComposed()).echo()
+ // log.prettyformat(map).echo()
+ // log.prettyformat(new ComposedTarget2()).echo()
+ // log.data(new ComposedTarget2() instanceof ComposedTarget2).echo()
+ // log.data(map instanceof Target).echo()
+
expect(map.parent).toEqual({isParent: true})
expect(map.extended).toBe(true)
})
diff --git a/test/deps/conditional.js b/test/conditional/conditional.js
similarity index 97%
rename from test/deps/conditional.js
rename to test/conditional/conditional.js
index 13b0fab..088ebc1 100644
--- a/test/deps/conditional.js
+++ b/test/conditional/conditional.js
@@ -9,7 +9,7 @@ const and = require('../../src/deps/conditional/and')
const not = require('../../src/deps/conditional/not')
const some = require('../../src/deps/conditional/some')
const eq = require('../../src/deps/conditional/eq')
-const includes = require('../../src/deps/conditional/includes')
+const includes = require('../../src/deps/conditional/includes/haystackNeedle')
const includesAll = require('../../src/deps/conditional/includes/all')
const includesAny = require('../../src/deps/conditional/includes/any')
const stress = require('../_stress')
diff --git a/test/conditional/not.js b/test/conditional/not.js
new file mode 100644
index 0000000..f6d6c98
--- /dev/null
+++ b/test/conditional/not.js
@@ -0,0 +1,14 @@
+const not = require('../../src/deps/conditional/not')
+const always = require('../../src/deps/fp/always')
+
+// describe('not', function() {
+// it('reverses argument', function() {
+// expect(not(false)).toBe(true)
+// expect(not(1)).toBe(false)
+// expect(not('')).toBe(true)
+// })
+// })
+test('not', () => {
+ expect(not(always(false))(false)).toBe(true)
+ expect(not(always(true))(true)).toBe(false)
+})
diff --git a/test/conditional/or.js b/test/conditional/or.js
new file mode 100644
index 0000000..7d035d6
--- /dev/null
+++ b/test/conditional/or.js
@@ -0,0 +1,43 @@
+const or = require('../../src/deps/conditional/or')
+const always = require('../../src/deps/fp/always')
+const isString = require('../../src/deps/is/string')
+const isNumber = require('../../src/deps/is/number')
+
+const eq = (x, y) => expect(x).toEqual(y)
+
+const T = always(true)
+const F = always(false)
+describe('or', () => {
+ it.only('works with izzes', () => {
+ const num = or(isString, isNumber)(100)
+ const str = or(isString, isNumber)('100')
+ const bool = or(isString, isNumber)(true)
+ expect(num).toBe(true)
+ expect(str).toBe(true)
+ expect(bool).toBe(false)
+ })
+ it('compares two values with js && - calling functions', () => {
+ eq(or(T, T)(), true)
+ eq(or(T, F)(), true)
+ eq(or(F, T)(), true)
+ eq(or(F, F)(), false)
+ })
+
+ it('is curried', () => {
+ eq(or(F)(F)(true), false)
+ eq(or(F)(T)(true), true)
+ })
+})
+// describe('or', () => {
+// it('compares two values with js &&', function() {
+// eq(or(true, true), true)
+// eq(or(true, false), true)
+// eq(or(false, true), true)
+// eq(or(false, false), false)
+// })
+//
+// it('is curried', function() {
+// eq(or(false)(false), false)
+// eq(or(false)(true), true)
+// })
+// })
diff --git a/test/deps/_debounce.js b/test/deps/_debounce.js
new file mode 100644
index 0000000..dc7aefa
--- /dev/null
+++ b/test/deps/_debounce.js
@@ -0,0 +1,332 @@
+jest.useFakeTimers()
+
+const _ = require('../../exports')
+
+var done = () => {}
+const push = Array.prototype.push
+
+// const _clearTimeout = global.clearTimeout
+// const _setTimeout = global.setTimeout
+// const restoreTimeout = () => {
+// global.clearTimeout = _clearTimeout
+// global.setTimeout = _setTimeout
+// }
+// let timeouts = []
+// global.clearTimeout = function(index) {
+// console.log({'clearTimeout': index})
+// const [fn, timeout] = timeouts[index]
+// fn()
+// }
+// global.setTimeout = function(fn, timeout) {
+// timeouts.push([fn, timeout])
+// return timeouts.length
+// }
+//
+// global.callAllTimeouts = function() {
+// timeouts = timeouts.filter(timeout => {
+// timeout()
+// return false
+// })
+// }
+
+// https://github.com/jasmine/jasmine.github.io/blob/master/lib/jasmine-1.3.1/jasmine.js
+test('should debounce a function', function() {
+ expect.assertions(6)
+
+ var callCount = 0
+
+ var debounced = _.debounce(function(value) {
+ ++callCount
+ return value
+ }, 32)
+
+ var results = [debounced('a'), debounced('b'), debounced('c')]
+ eq(results, [undefined, undefined, undefined])
+ eq(callCount, 0)
+
+ setTimeout(function() {
+ eq(callCount, 1)
+
+ var results = [debounced('d'), debounced('e'), debounced('f')]
+ eq(results, ['c', 'c', 'c'])
+ eq(callCount, 1)
+ }, 128)
+
+ setTimeout(function() {
+ eq(callCount, 2)
+ done()
+ }, 256)
+
+ jest.runAllTimers()
+})
+
+test('subsequent debounced calls return the last `func` result', function() {
+ expect.assertions(2)
+
+ var debounced = _.debounce(_.identity, 32)
+ debounced('a')
+
+ setTimeout(function() {
+ neq(debounced('b'), 'b')
+ }, 64)
+
+ setTimeout(function() {
+ neq(debounced('c'), 'c')
+ done()
+ }, 128)
+
+ jest.runAllTimers()
+})
+
+test('should not immediately call `func` when `wait` is `0`', function() {
+ expect.assertions(2)
+
+ var callCount = 0
+ var debounced = _.debounce(function() { ++callCount }, 0)
+
+ debounced()
+ debounced()
+ eq(callCount, 0)
+
+ setTimeout(function() {
+ eq(callCount, 1)
+ done()
+ }, 5)
+
+ jest.runAllTimers()
+})
+
+test('should apply default options', function() {
+ expect.assertions(2)
+
+ var callCount = 0
+ var debounced = _.debounce(function() { callCount++ }, 32, {})
+
+ debounced()
+ eq(callCount, 0)
+
+ setTimeout(function() {
+ eq(callCount, 1)
+ done()
+ }, 64)
+
+ jest.runAllTimers()
+})
+
+test('should support a `leading` option', function() {
+ expect.assertions(4)
+
+ var callCounts = [0, 0]
+
+ var withLeading = _.debounce(function() {
+ callCounts[0]++
+ }, 32, {'leading': true})
+
+ var withLeadingAndTrailing = _.debounce(function() {
+ callCounts[1]++
+ }, 32, {'leading': true})
+
+ withLeading()
+ eq(callCounts[0], 1)
+
+ withLeadingAndTrailing()
+ withLeadingAndTrailing()
+ eq(callCounts[1], 1)
+
+ setTimeout(function() {
+ eq(callCounts, [1, 2])
+
+ withLeading()
+ eq(callCounts[0], 2)
+
+ done()
+ }, 64)
+
+ jest.runAllTimers()
+})
+
+test('subsequent leading debounced calls return the last `func` result', function() {
+ expect.assertions(2)
+
+
+ var debounced = _.debounce(_.identity, 32, {'leading': true, 'trailing': false})
+ var results = [debounced('a'), debounced('b')]
+
+ eq(results, ['a', 'a'])
+
+ setTimeout(function() {
+ var results = [debounced('c'), debounced('d')]
+ eq(results, ['c', 'c'])
+ done()
+ }, 64)
+
+ jest.runAllTimers()
+})
+
+test('should support a `trailing` option', function() {
+ expect.assertions(4)
+
+ var withCount = 0
+ var withoutCount = 0
+
+ var withTrailing = _.debounce(function() {
+ withCount++
+ }, 32, {'trailing': true})
+
+ var withoutTrailing = _.debounce(function() {
+ withoutCount++
+ }, 32, {'trailing': false})
+
+ withTrailing()
+ eq(withCount, 0)
+
+ withoutTrailing()
+ eq(withoutCount, 0)
+
+ setTimeout(function() {
+ eq(withCount, 1)
+ eq(withoutCount, 0)
+ done()
+ }, 64)
+
+ jest.runAllTimers()
+})
+
+test('should support a `maxWait` option', function() {
+ expect.assertions(4)
+
+
+ var callCount = 0
+
+ var debounced = _.debounce(function(value) {
+ ++callCount
+ return value
+ }, 32, {'maxWait': 64})
+
+ debounced()
+ debounced()
+ eq(callCount, 0)
+
+ setTimeout(function() {
+ eq(callCount, 1)
+ debounced()
+ debounced()
+ eq(callCount, 1)
+ }, 128)
+
+ setTimeout(function() {
+ eq(callCount, 2)
+ done()
+ }, 256)
+
+ jest.runAllTimers()
+})
+
+test('should support `maxWait` in a tight loop', function() {
+ expect.assertions(1)
+
+
+ // (argv || isPhantom) ? 1000 :
+ var limit = 320
+ var withCount = 0
+ var withoutCount = 0
+
+ var withMaxWait = _.debounce(function() {
+ withCount++
+ }, 64, {'maxWait': 128})
+
+ var withoutMaxWait = _.debounce(function() {
+ withoutCount++
+ }, 96)
+
+ var start = +new Date()
+ while ((new Date() - start) < limit) {
+ withMaxWait()
+ withoutMaxWait()
+ }
+ var actual = [Boolean(withoutCount), Boolean(withCount)]
+ setTimeout(function() {
+ eq(actual, [false, true])
+ done()
+ }, 1)
+
+ jest.runAllTimers()
+})
+
+console.log('@TODO queue')
+test.skip('should queue a trailing call for subsequent debounced calls after `maxWait`', function() {
+ expect.assertions(1)
+
+ var callCount = 0
+
+ var debounced = _.debounce(function() {
+ ++callCount
+ }, 200, {'maxWait': 200})
+
+ debounced()
+
+ setTimeout(debounced, 190)
+ setTimeout(debounced, 200)
+ setTimeout(debounced, 210)
+
+ setTimeout(function() {
+ eq(callCount, 2)
+ done()
+ }, 500)
+
+ jest.runAllTimers()
+})
+
+console.log('@TODO maxDelayed - jest changes times for it')
+
+test.skip('should cancel `maxDelayed` when `delayed` is invoked', function() {
+ expect.assertions(2)
+
+ var callCount = 0
+
+ var debounced = _.debounce(function() {
+ callCount++
+ }, 32, {'maxWait': 64})
+
+ debounced()
+
+ setTimeout(function() {
+ debounced()
+ eq(callCount, 1)
+ }, 128)
+
+ setTimeout(function() {
+ eq(callCount, 2)
+ done()
+ }, 192)
+
+ jest.runAllTimers()
+})
+
+test('should invoke the trailing call with the correct arguments and `this` binding', function() {
+ expect.assertions(2)
+
+ var actual
+ var callCount = 0
+ var object = {}
+
+ var debounced = _.debounce(function(value) {
+ actual = [this]
+ push.apply(actual, arguments)
+ return ++callCount != 2
+ }, 32, {'leading': true, 'maxWait': 64})
+
+ // @HACK
+ while (true) {
+ if (!debounced.call(object, 'a')) {
+ break
+ }
+ }
+ setTimeout(function() {
+ eq(callCount, 2)
+ eq(actual, [object, 'a'])
+ done()
+ }, 64)
+
+ jest.runAllTimers()
+})
diff --git a/test/deps/_debounceAndThrottle.js b/test/deps/_debounceAndThrottle.js
new file mode 100644
index 0000000..b52eaa1
--- /dev/null
+++ b/test/deps/_debounceAndThrottle.js
@@ -0,0 +1,197 @@
+jest.useFakeTimers()
+
+const _ = require('../../exports')
+
+const push = Array.prototype.push
+
+_.forEach(['debounce', 'throttle'], function(methodName) {
+ var func = _[methodName]
+ var isDebounce = methodName === 'debounce'
+
+ const recursive = '`_.' + methodName + '` supports recursive calls'
+ const shouldNotErrWithoutOpts = '`_.' + methodName + '` should not error for non-object `options` values'
+ const default0 = '`_.' + methodName + '` should use a default `wait` of `0`'
+ const rightContext = '`_.' +
+ methodName +
+ '` should invoke `func` with the correct `this` binding'
+ const cancelDelayed = '`_.' + methodName + '` should support cancelling delayed calls'
+ const reset = '`_.' + methodName + '` should reset `lastCalled` after cancelling'
+ const flushing = '`_.' + methodName + '` should support flushing delayed calls'
+ const cancelAndNoop = '`_.' +
+ methodName +
+ '` should noop `cancel` and `flush` when nothing is queued'
+
+
+ test(shouldNotErrWithoutOpts, function() {
+ expect.assertions(1)
+
+ func(_.noop, 32, 1)
+ expect(true).toBeTruthy()
+ })
+
+ test(default0, function() {
+ expect.assertions(1)
+
+ var callCount = 0
+ var funced = func(() => callCount++)
+
+ funced()
+
+ setTimeout(function() {
+ funced()
+ eq(callCount, isDebounce ? 1 : 2)
+ // done()
+ }, 32)
+
+ jest.runAllTimers()
+ })
+
+ test(rightContext, function() {
+ expect.assertions(1)
+
+ var actual = []
+ var object = {
+ funced: func(function() {
+ actual.push(this)
+ }, 32),
+ }
+ var expected = _.times(isDebounce ? 1 : 2, _.always(object))
+
+ object.funced()
+ if (!isDebounce) {
+ object.funced()
+ }
+
+ setTimeout(function() {
+ eq(actual, expected)
+ // done()
+ }, 64)
+
+ jest.runAllTimers()
+ })
+
+ test(recursive, function() {
+ expect.assertions(2)
+
+ var actual = []
+ console.log('mapping strings?')
+ var args = _.map(['a', 'b', 'c'], letter => [{}, letter])
+ console.log('uh oh')
+ var expected = args.slice()
+ var queue = args.slice()
+
+ console.log({args, actual})
+
+ var funced = func(function() {
+ var current = [this]
+ push.apply(current, arguments)
+ actual.push(current)
+
+ var next = queue.shift()
+ if (next) {
+ funced.call(next[0], next[1])
+ }
+ }, 32)
+
+ console.log({args, actual})
+
+ var next = queue.shift()
+ funced.call(next[0], next[1])
+ eq(actual, expected.slice(0, isDebounce ? 0 : 1))
+
+ setTimeout(function() {
+ eq(actual, expected.slice(0, actual.length))
+ // done()
+ }, 256)
+
+ jest.runAllTimers()
+ })
+
+ test(cancelDelayed, function() {
+ expect.assertions(1)
+
+ var callCount = 0
+
+ var funced = func(
+ () => callCount++,
+ 32,
+ {leading: false}
+ )
+
+ funced()
+ funced.cancel()
+
+ setTimeout(function() {
+ eq(callCount, 0)
+ // done()
+ }, 64)
+
+ jest.runAllTimers()
+ })
+
+
+ test(reset, function() {
+ expect.assertions(3)
+
+ var callCount = 0
+
+ var funced = func(
+ () => ++callCount,
+ 32,
+ {leading: true}
+ )
+
+ eq(funced(), 1)
+ funced.cancel()
+
+ eq(funced(), 2)
+ funced()
+
+ setTimeout(function() {
+ eq(callCount, 3)
+ // done()
+ }, 64)
+
+ jest.runAllTimers()
+ })
+
+
+ test(flushing, function() {
+ expect.assertions(2)
+
+ var callCount = 0
+
+ var funced = func(
+ () => ++callCount,
+ 32,
+ {leading: false}
+ )
+
+ funced()
+ eq(funced.flush(), 1)
+
+ setTimeout(function() {
+ eq(callCount, 1)
+ // done()
+ }, 64)
+
+ jest.runAllTimers()
+ })
+
+ test(cancelAndNoop, function() {
+ expect.assertions(2)
+
+ var callCount = 0
+ var funced = func(() => callCount++, 32)
+
+ funced.cancel()
+ eq(funced.flush(), undefined)
+
+ setTimeout(function() {
+ eq(callCount, 0)
+ // done()
+ }, 64)
+
+ jest.runAllTimers()
+ })
+})
diff --git a/test/deps/_mergedopemaps.js b/test/deps/_mergedopemaps.js
new file mode 100644
index 0000000..684ca61
--- /dev/null
+++ b/test/deps/_mergedopemaps.js
@@ -0,0 +1,15 @@
+const dopemergeMap = require('../../src/deps/dopemerge/map')
+
+test.skip('dopemerge map & set', () => {
+ // test
+ var targetMap = new Map()
+ targetMap.set('true', false)
+ targetMap.set('obj', {obj: []})
+ targetMap.set('arr', [1])
+ var srcMap = new Map()
+ srcMap.set('true', true)
+ srcMap.set('obj', {obj: [Symbol]})
+ srcMap.set('arr', [2])
+ srcMap.set('emptyArr', [])
+ var mergedMap = dopemergeMap(targetMap, srcMap, {clone: true})
+})
diff --git a/test/deps/_throttle.js b/test/deps/_throttle.js
new file mode 100644
index 0000000..308ba4c
--- /dev/null
+++ b/test/deps/_throttle.js
@@ -0,0 +1,298 @@
+jest.useFakeTimers()
+
+const _ = require('../../exports')
+
+test('should throttle a function', function() {
+ expect.assertions(2)
+
+ var callCount = 0
+ var throttled = _.throttle(() => callCount++, 32)
+
+ throttled()
+ throttled()
+ throttled()
+
+ var lastCount = callCount
+ expect(callCount).toBeTruthy()
+
+ setTimeout(function() {
+ expect(callCount > lastCount).toBeTruthy()
+ // done()
+ }, 64)
+
+ jest.runAllTimers()
+})
+
+console.log('@TODO fix jest here')
+test.skip('subsequent calls should return the result of the first call', function() {
+ expect.assertions(5)
+
+ var throttled = _.throttle(_.identity, 32)
+ var results = [throttled('a'), throttled('b')]
+
+ eq(results, ['a', 'a'])
+
+ setTimeout(function() {
+ var timeoutResults = [throttled('c'), throttled('d')]
+ neq(timeoutResults[0], 'a')
+ eq(timeoutResults[0], 'c')
+
+ neq(timeoutResults[1], 'd')
+ eq(timeoutResults[1], 'c')
+ // done()
+ }, 64)
+
+ jest.runAllTimers()
+})
+
+test('should clear timeout when `func` is called', function() {
+ expect.assertions(1)
+
+ var callCount = 0
+ var dateCount = 0
+
+ // var lodash = _.runInContext({
+ // 'Date': {
+ // 'now': function() {
+ // return ++dateCount == 5 ? Infinity : +new Date()
+ // },
+ // },
+ // })
+
+ var throttled = _.throttle(() => callCount++, 32)
+
+ throttled()
+ throttled()
+
+ setTimeout(function() {
+ eq(callCount, 2)
+ // done()
+ }, 64)
+
+ jest.runAllTimers()
+})
+
+test('should not trigger a trailing call when invoked once', function() {
+ expect.assertions(2)
+
+ var callCount = 0
+ var throttled = _.throttle(() => callCount++, 32)
+
+ throttled()
+ eq(callCount, 1)
+
+ setTimeout(function() {
+ eq(callCount, 1)
+ // done()
+ }, 64)
+
+ jest.runAllTimers()
+})
+
+_.times(2, function(index) {
+ test(
+ 'should trigger a call when invoked repeatedly' +
+ (index ? ' and `leading` is `false`' : ''),
+ function() {
+ expect.assertions(1)
+
+ var callCount = 0,
+ // (argv || isPhantom) ? 1000 :
+ limit = 320,
+ options = index ? {leading: false} : {},
+ throttled = _.throttle(
+ function() {
+ callCount++
+ },
+ 32,
+ options
+ )
+
+ var start = +new Date()
+ while (new Date() - start < limit) {
+ throttled()
+ }
+ var actual = callCount > 1
+ setTimeout(function() {
+ expect(actual).toBeTruthy()
+ // done()
+ }, 1)
+
+ jest.runAllTimers()
+ }
+ )
+})
+
+// off with mock timers?
+test.skip('should trigger a second throttled call as soon as possible', function() {
+ expect.assertions(3)
+
+ var callCount = 0
+
+ var throttled = _.throttle(
+ () => callCount++,
+ 128,
+ {leading: false}
+ )
+
+ throttled()
+
+ setTimeout(function() {
+ eq(callCount, 1)
+ throttled()
+ }, 192)
+
+ jest.runAllTimers()
+
+ setTimeout(function() {
+ eq(callCount, 1)
+ }, 254)
+
+ jest.runAllTimers()
+
+ // would wait until 3rd call but is not full timeout...
+ setTimeout(function() {
+ eq(callCount, 2)
+ // done()
+ }, 384)
+
+ jest.runAllTimers()
+})
+
+test('should apply default options', function() {
+ expect.assertions(2)
+
+ var callCount = 0
+ var throttled = _.throttle(
+ function() {
+ callCount++
+ },
+ 32,
+ {}
+ )
+
+ throttled()
+ throttled()
+ eq(callCount, 1)
+
+ setTimeout(function() {
+ eq(callCount, 2)
+ // done()
+ }, 128)
+
+ jest.runAllTimers()
+})
+
+test('should support a `leading` option', function() {
+ expect.assertions(2)
+
+ var withLeading = _.throttle(_.identity, 32, {leading: true})
+ eq(withLeading('a'), 'a')
+
+ var withoutLeading = _.throttle(_.identity, 32, {leading: false})
+ eq(withoutLeading('a'), undefined)
+
+ jest.runAllTimers()
+})
+
+test('should support a `trailing` option', function() {
+ expect.assertions(6)
+
+ var withCount = 0
+ var withoutCount = 0
+
+ var withTrailing = _.throttle(
+ function(value) {
+ withCount++
+ return value
+ },
+ 64,
+ {trailing: true}
+ )
+
+ var withoutTrailing = _.throttle(
+ function(value) {
+ withoutCount++
+ return value
+ },
+ 64,
+ {trailing: false}
+ )
+
+ eq(withTrailing('a'), 'a')
+ eq(withTrailing('b'), 'a')
+
+ eq(withoutTrailing('a'), 'a')
+ eq(withoutTrailing('b'), 'a')
+
+ setTimeout(function() {
+ eq(withCount, 2)
+ eq(withoutCount, 1)
+ // done()
+ }, 256)
+
+ jest.runAllTimers()
+})
+
+test('should not update `lastCalled`, at the end of the timeout, when `trailing` is `false`', function() {
+ expect.assertions(1)
+
+ var callCount = 0
+
+ var throttled = _.throttle(
+ () => callCount++,
+ 64,
+ {trailing: false}
+ )
+
+ throttled()
+ throttled()
+
+ setTimeout(function() {
+ throttled()
+ throttled()
+ }, 96)
+
+ setTimeout(function() {
+ expect(callCount > 1).toBeTruthy()
+ // done()
+ }, 192)
+
+ jest.runAllTimers()
+})
+
+test.skip('should work with a system time of `0`', function() {
+ expect.assertions(3)
+
+ // if (!isModularize) {
+ // var callCount = 0,
+ // dateCount = 0
+ //
+ // var lodash = _.runInContext({
+ // 'Date': {
+ // 'now': function() {
+ // return ++dateCount < 4 ? 0 : +new Date()
+ // },
+ // },
+ // })
+ //
+ // var throttled = lodash.throttle(function(value) {
+ // callCount++
+ // return value
+ // }, 32)
+ //
+ // var results = [throttled('a'), throttled('b'), throttled('c')]
+ // eq(results, ['a', 'a', 'a'])
+ // eq(callCount, 1)
+ //
+ // setTimeout(function() {
+ // eq(callCount, 2)
+ // // done()
+ // }, 64)
+ // }
+ // else {
+ // skipAssert(assert, 3)
+ // // done()
+ // }
+ // jest.runAllTimers()
+})
diff --git a/test/deps/escape.js b/test/deps/escape.js
new file mode 100644
index 0000000..69c7f46
--- /dev/null
+++ b/test/deps/escape.js
@@ -0,0 +1,7 @@
+const escapeStringRegExp = require('../../src/deps/string/escapeRegExp')
+
+test('excape string regexp', () => {
+ const actual = escapeStringRegExp('\\ ^ $ * + ? . ( ) | { } [ ]')
+ const escaped = '\\\\ \\^ \\$ \\* \\+ \\? \\. \\( \\) \\| \\{ \\} \\[ \\]'
+ expect(actual).toEqual(escaped)
+})
diff --git a/test/deps/flatten.js b/test/deps/flatten.js
new file mode 100644
index 0000000..661cfff
--- /dev/null
+++ b/test/deps/flatten.js
@@ -0,0 +1,37 @@
+// https://github.com/jashkenas/underscore/blob/master/test/arrays.js#L87
+const flattens = require('../../src/deps/array/flatten')
+const flatten = require('../../src/deps/array/flattenRecursive')
+const range = require('../../src/deps/math/range')
+
+const eq = (x, y, msg) => expect(x).toEqual(y)
+test('flatten', () => {
+ eq(flatten(null), [], 'supports null')
+ eq(flatten(void 0), [], 'supports undefined')
+
+ eq(flatten([[], [[]], []]), [], 'supports empty arrays')
+ // eq(flatten([[], [[]], []], true), [[]], 'can shallowly flatten empty arrays')
+
+ let list = [1, [2], [3, [[[4]]]]]
+ eq(flatten(list), [1, 2, 3, 4], 'can flatten nested arrays')
+ eq(flattens(list, true), [1, 2, 3, [[[4]]]], 'can shallowly flatten nested arrays')
+ eq(flatten(list, true), [1, 2, 3, 4], 'can shallowly flatten nested arrays')
+
+ let result = (function() { return flatten(arguments) })(1, [2], [3, [[[4]]]])
+ eq(result, [1, 2, 3, 4], 'works on an arguments object')
+ list = [[1], [2], [3], [[4]]]
+ eq(flattens(list, true), [1, 2, 3, [4]], 'can shallowly flatten arrays containing only other arrays')
+ eq(flatten(list, true), [1, 2, 3, 4], 'can shallowly flatten arrays containing only other arrays')
+})
+
+// slows down test suite
+test.skip('hardcore huge & heavy', () => {
+ eq(flatten([range(10), range(10), 5, 1, 3], true).length, 23, 'can flatten medium length arrays')
+ eq(flatten([range(10), range(10), 5, 1, 3]).length, 23, 'can shallowly flatten medium length arrays')
+ eq(flatten([new Array(100000), range(56000), 5, 1, 3]).length, 156003, 'can handle massive arrays')
+ eq(flatten([new Array(100000), range(56000), 5, 1, 3], true).length, 156003, 'can handle massive arrays in shallow mode')
+
+ let x = range(100000)
+ for (let i = 0; i < 1000; i++) x = [x]
+ eq(flatten(x), range(100000), 'can handle very deep arrays')
+ eq(flattens(x, true), x[0], 'can handle very deep arrays in shallow mode')
+})
diff --git a/test/deps/kindOf.js b/test/deps/kindOf.js
new file mode 100644
index 0000000..c4118c5
--- /dev/null
+++ b/test/deps/kindOf.js
@@ -0,0 +1,7 @@
+const getTag = require('../../src/deps/is/toS')
+const kindOf = require('../../src/deps/util/kindOf')
+const stress = require('../_stress')
+
+test('kindOf', () => {
+ stress(x => expect(getTag(x).toLowerCase()).toContain(kindOf(x)))
+})
diff --git a/test/deps/lastIndexOf.js b/test/deps/lastIndexOf.js
new file mode 100644
index 0000000..b4624f6
--- /dev/null
+++ b/test/deps/lastIndexOf.js
@@ -0,0 +1,63 @@
+// const lastIndexOf = require('../../src/deps/fp/lastIndexOf')
+// const map = require('../../src/deps/loop/map/map')
+
+// https://github.com/jashkenas/underscore/blob/master/test/arrays.js#L61
+const eq = (x, y, msg) => expect(x).toEqual(y)
+
+test.skip('lastIndexOf', () => {
+ var numbers = [1, 0, 1]
+ var falsy = [void 0, '', 0, false, NaN, null, void 0]
+ eq(lastIndexOf(numbers, 1), 2)
+
+ numbers = [1, 0, 1, 0, 0, 1, 0, 0, 0]
+ numbers.lastIndexOf = null
+ eq(lastIndexOf(numbers, 1), 5, 'can compute lastIndexOf, even without the native function')
+ eq(lastIndexOf(numbers, 0), 8, 'lastIndexOf the other element')
+ var result = (function() { return lastIndexOf(arguments, 1) })(1, 0, 1, 0, 0, 1, 0, 0, 0)
+ eq(result, 5, 'works on an arguments object')
+
+ each([null, void 0, [], false], function(val) {
+ var msg = 'Handles: ' + (isArray(val) ? '[]' : val)
+ eq(lastIndexOf(val, 2), -1, msg)
+ eq(lastIndexOf(val, 2, -1), -1, msg)
+ eq(lastIndexOf(val, 2, -20), -1, msg)
+ eq(lastIndexOf(val, 2, 15), -1, msg)
+ })
+
+ numbers = [1, 2, 3, 1, 2, 3, 1, 2, 3]
+ var index = lastIndexOf(numbers, 2, 2)
+ eq(index, 1, 'supports the fromIndex argument')
+
+ var array = [1, 2, 3, 1, 2, 3]
+
+ eq(lastIndexOf(array, 1, 0), 0, 'starts at the correct from idx')
+ eq(lastIndexOf(array, 3), 5, 'should return the index of the last matched value')
+ eq(lastIndexOf(array, 4), -1, 'should return `-1` for an unmatched value')
+
+ eq(lastIndexOf(array, 1, 2), 0, 'should work with a positive `fromIndex`')
+
+ each([6, 8, Math.pow(2, 32), Infinity], function(fromIndex) {
+ eq(lastIndexOf(array, void 0, fromIndex), -1)
+ eq(lastIndexOf(array, 1, fromIndex), 3)
+ eq(lastIndexOf(array, '', fromIndex), -1)
+ })
+
+ var expected = map(falsy, function(value) {
+ return typeof value === 'number' ? -1 : 5
+ })
+
+ var actual = map(falsy, function(fromIndex) {
+ return lastIndexOf(array, 3, fromIndex)
+ })
+
+ eq(actual, expected, 'should treat falsy `fromIndex` values, except `0` and `NaN`, as `array.length`')
+ eq(lastIndexOf(array, 3, '1'), 5, 'should treat non-number `fromIndex` values as `array.length`')
+ eq(lastIndexOf(array, 3, true), 5, 'should treat non-number `fromIndex` values as `array.length`')
+
+ eq(lastIndexOf(array, 2, -3), 1, 'should work with a negative `fromIndex`')
+ eq(lastIndexOf(array, 1, -3), 3, 'neg `fromIndex` starts at the right index')
+
+ eq(map([-6, -8, -Infinity], function(fromIndex) {
+ return lastIndexOf(array, 1, fromIndex)
+ }), [0, -1, -1])
+})
diff --git a/test/deps/matcher.js b/test/deps/matcher.js
index 64dd06b..82caf56 100644
--- a/test/deps/matcher.js
+++ b/test/deps/matcher.js
@@ -1,6 +1,6 @@
const log = require('fliplog')
const m = require('../../src/deps/matcher')
-const toTest = require('../../src/deps/matcher/to-test')
+const toTest = require('../../src/deps/cast/toTestable')
test('matcher *', () => {
expect(m('canada.arr.0', 'canada.*').length).toBeTruthy()
diff --git a/test/deps/pooler.js b/test/deps/pooler.js
new file mode 100644
index 0000000..1cb5d5a
--- /dev/null
+++ b/test/deps/pooler.js
@@ -0,0 +1,55 @@
+const addPoolingTo = require('../../src/deps/cache/pooler')
+const isFunction = require('../../src/deps/is/function')
+const isArray = require('../../src/deps/is/array')
+const isNumber = require('../../src/deps/is/number')
+
+test('pooling', () => {
+ // expect.assertions(5)
+ let count = 0
+
+ function Eh() {
+ this.count = this.count || count
+ count = count + 1
+ this.canada = true
+ }
+
+ // expect this is called
+ Eh.prototype.destructor = function() {
+ this.canada = undefined
+ // expect(this.canada).toBe(undefined)
+ }
+
+ addPoolingTo(Eh)
+
+ expect(isFunction(Eh.release)).toBe(true)
+ expect(isFunction(Eh.getPooled)).toBe(true)
+ expect(isArray(Eh.instancePool)).toBe(true)
+ expect(isNumber(Eh.poolSize)).toBe(true)
+
+ const eh = Eh.getPooled()
+ const eh2 = Eh.getPooled()
+ expect(Eh.instancePool.length).toBe(0)
+
+ // back into the pool
+ Eh.release(eh)
+ expect(Eh.instancePool.length).toBe(1)
+
+ // again
+ Eh.release(eh2)
+ expect(Eh.instancePool.length).toBe(2)
+
+ // back out of the pool
+ const eh3 = Eh.getPooled()
+ expect(Eh.instancePool.length).toBe(1)
+ expect(eh3 instanceof Eh).toBe(true)
+
+ Eh.release(eh3)
+
+ // we used 3 times
+ expect(count).toBe(3)
+
+ // but we actually created only 2 of them
+ // usually we would not leave leftover props, but this is for the test
+ expect(Eh.instancePool[0].count).toBe(0)
+ expect(Eh.instancePool[1].count).toBe(1)
+})
diff --git a/test/fp/always.js b/test/fp/always.js
new file mode 100644
index 0000000..74451ac
--- /dev/null
+++ b/test/fp/always.js
@@ -0,0 +1,18 @@
+const always = require('../../src/deps/fp/always')
+
+test('works with various types', function() {
+ expect(always(false)()).toEqual(false)
+ expect(always('abc')()).toEqual('abc')
+
+ expect(always({a: 1, b: 2})()).toEqual({a: 1, b: 2})
+
+ var obj = {a: 1, b: 2}
+ expect(always(obj)()).toEqual(obj)
+
+ var now = new Date(1776, 6, 4)
+ expect(always(now)()).toEqual(now)
+
+ expect(always(undefined)()).toEqual(undefined)
+ expect(always(null)()).toEqual(null)
+ expect(always(100)()).toEqual(100)
+})
diff --git a/test/fp/bind.js b/test/fp/bind.js
new file mode 100644
index 0000000..a7bd8e9
--- /dev/null
+++ b/test/fp/bind.js
@@ -0,0 +1,94 @@
+const bind = require('../../src/deps/fp/bind')
+
+describe('bind', function() {
+ function Foo(x) {
+ this.x = x
+ }
+ function add(x) {
+ return this.x + x
+ }
+ function Bar(x, y) {
+ this.x = x
+ this.y = y
+ }
+ Bar.prototype = new Foo()
+ Bar.prototype.getX = function() {
+ return 'prototype getX'
+ }
+
+ it('returns a function', function() {
+ eq(typeof bind(add, Foo), 'function')
+ })
+
+ it('returns a function bound to the specified context object', function() {
+ const f = new Foo(12)
+ function isFoo() {
+ return this instanceof Foo
+ }
+ const isFooBound = bind(isFoo, f)
+ eq(isFoo(), false)
+ eq(isFooBound(), true)
+ })
+
+ it('works with built-in types', function() {
+ const abc = bind(String.prototype.toLowerCase, 'ABCDEFG')
+ eq(typeof abc, 'function')
+ eq(abc(), 'abcdefg')
+ })
+
+ it('works with user-defined types', function() {
+ const f = new Foo(12)
+ function getX() {
+ return this.x
+ }
+ const getXFooBound = bind(getX, f)
+ eq(getXFooBound(), 12)
+ })
+
+ it('works with plain objects', function() {
+ const pojso = {
+ x: 100,
+ }
+ function incThis() {
+ return this.x + 1
+ }
+ const incPojso = bind(incThis, pojso)
+ eq(typeof incPojso, 'function')
+ eq(incPojso(), 101)
+ })
+
+ it('does not interfere with existing object methods', function() {
+ const b = new Bar('a', 'b')
+ function getX() {
+ return this.x
+ }
+ const getXBarBound = bind(getX, b)
+ eq(b.getX(), 'prototype getX')
+ eq(getXBarBound(), 'a')
+ })
+
+ it('is curried', function() {
+ const f = new Foo(1)
+ eq(bind(add)(f)(10), 11)
+ })
+
+ it('preserves arity', function() {
+ const f0 = function() {
+ return 0
+ }
+ const f1 = function(a) {
+ return a
+ }
+ const f2 = function(a, b) {
+ return a + b
+ }
+ const f3 = function(a, b, c) {
+ return a + b + c
+ }
+
+ eq(bind(f0, {}).length, 0)
+ eq(bind(f1, {}).length, 1)
+ eq(bind(f2, {}).length, 2)
+ eq(bind(f3, {}).length, 3)
+ })
+})
diff --git a/test/fp/construct.js b/test/fp/construct.js
new file mode 100644
index 0000000..0e79b4e
--- /dev/null
+++ b/test/fp/construct.js
@@ -0,0 +1,118 @@
+const construct = require("../../src/deps/fp/construct");
+
+describe("construct", function() {
+ const Rectangle = function(w, h) {
+ this.width = w;
+ this.height = h;
+ };
+ Rectangle.prototype.area = function() {
+ return this.width * this.height;
+ };
+
+ it("turns a constructor function into one that can be called without `new`", function() {
+ const rect = construct(Rectangle);
+ const r1 = rect(3, 4);
+ eq(r1.constructor, Rectangle);
+ eq(r1.width, 3);
+ eq(r1.area(), 12);
+
+ const regex = construct(RegExp);
+ const word = regex("word", "gi");
+ eq(word.constructor, RegExp);
+ eq(word.source, "word");
+ eq(word.global, true);
+ });
+
+ it("can be used to create Date object", function() {
+ const date = construct(Date)(1984, 3, 26, 0, 0, 0, 0);
+ eq(date.constructor, Date);
+ eq(date.getFullYear(), 1984);
+ });
+
+ it("supports constructors with no arguments", function() {
+ function Foo() {}
+ const foo = construct(Foo)();
+ eq(foo.constructor, Foo);
+ });
+
+ it.skip(
+ "does not support constructor with greater than ten arguments",
+ function() {
+ const over10 = function() {
+ function Foo($0, $1, $2, $3, $4, $5, $6, $7, $8, $9, $10) {
+ this.eleventh = $10;
+ }
+ construct(Foo);
+ };
+ expect(over10).toThrow(/Constructor with greater than ten arguments/);
+ }
+ );
+
+ it("returns a curried function", function() {
+ const rect = construct(Rectangle);
+ const rect3 = rect(3);
+ const r1 = rect3(4);
+ eq(r1.constructor, Rectangle);
+ eq(r1.width, 3);
+ eq(r1.height, 4);
+ eq(r1.area(), 12);
+
+ const regex = construct(RegExp);
+ const word = regex("word");
+ const complete = word("gi");
+ eq(complete.constructor, RegExp);
+ eq(complete.source, "word");
+ eq(complete.global, true);
+ });
+});
+
+describe("constructN", function() {
+ const Circle = function(r) {
+ this.r = r;
+ this.colors = Array.prototype.slice.call(arguments, 1);
+ };
+ Circle.prototype.area = function() {
+ return Math.PI * Math.pow(this.r, 2);
+ };
+
+ it("turns a constructor function into a function with n arguments", function() {
+ const circle = construct(2, Circle);
+ const c1 = circle(1, "red");
+ eq(c1.constructor, Circle);
+ eq(c1.r, 1);
+ eq(c1.area(), Math.PI);
+ eq(c1.colors, ["red"]);
+
+ const regex = construct(1, RegExp);
+ const pattern = regex("[a-z]");
+ eq(pattern.constructor, RegExp);
+ eq(pattern.source, "[a-z]");
+ });
+
+ it("can be used to create Date object", function() {
+ const date = construct(3, Date)(1984, 3, 26);
+ eq(date.constructor, Date);
+ eq(date.getFullYear(), 1984);
+ });
+
+ it("supports constructors with no arguments", function() {
+ function Foo() {}
+ const foo = construct(0, Foo)();
+ eq(foo.constructor, Foo);
+ });
+
+ // is not curried
+ it.skip("is curried", function() {
+ function G(a, b, c) {
+ this.a = a;
+ this.b = b;
+ this.c = c;
+ }
+ const construct2 = construct(2);
+ eq(typeof construct2, "function");
+ const g2 = construct2(G);
+ eq(typeof g2, "function");
+ eq(g2("a", "b").constructor, G);
+ eq(g2("a")("b").constructor, G);
+ });
+});
diff --git a/test/fp/curry.js b/test/fp/curry.js
new file mode 100644
index 0000000..65eb66d
--- /dev/null
+++ b/test/fp/curry.js
@@ -0,0 +1,113 @@
+var curryN = require('../../src/deps/fp/curry')
+
+describe('curryN', function() {
+ function source(a, b, c, d) {
+ void d
+ return a * b * c
+ }
+ it('accepts an arity', function() {
+ var curried = curryN(3, source)
+ expect(curried(1)(2)(3)).toEqual(6)
+ expect(curried(1, 2)(3)).toEqual(6)
+ expect(curried(1)(2, 3)).toEqual(6)
+ expect(curried(1, 2, 3)).toEqual(6)
+ })
+
+ it.skip('can be partially applied', function() {
+ var curry3 = curryN(3)
+ var curried = curry3(source)
+ expect(curried.length, 3)
+ expect(curried(1)(2)(3)).toEqual(6)
+ expect(curried(1, 2)(3)).toEqual(6)
+ expect(curried(1)(2, 3)).toEqual(6)
+ expect(curried(1, 2, 3)).toEqual(6)
+ })
+
+ it('preserves context', function() {
+ var ctx = {x: 10}
+ var f = function(a, b) {
+ return a + b * this.x
+ }
+ var g = curryN(2, f)
+
+ expect(g.call(ctx, 2, 4)).toEqual(42)
+ expect(g.call(ctx, 2).call(ctx, 4)).toEqual(42)
+ })
+
+ it('supports R.__ placeholder', function() {
+ var f = function() {
+ return Array.from(arguments)
+ }
+ var g = curryN(3, f)
+ var _ = '_' // R.__
+
+ expect(g(1)(2)(3)).toEqual([1, 2, 3])
+ expect(g(1)(2, 3)).toEqual([1, 2, 3])
+ expect(g(1, 2)(3)).toEqual([1, 2, 3])
+ expect(g(1, 2, 3)).toEqual([1, 2, 3])
+
+ expect(g(_, 2, 3)(1)).toEqual([1, 2, 3])
+ expect(g(1, _, 3)(2)).toEqual([1, 2, 3])
+ expect(g(1, 2, _)(3)).toEqual([1, 2, 3])
+
+ expect(g(1, _, _)(2)(3)).toEqual([1, 2, 3])
+ expect(g(_, 2, _)(1)(3)).toEqual([1, 2, 3])
+ expect(g(_, _, 3)(1)(2)).toEqual([1, 2, 3])
+
+ expect(g(1, _, _)(2, 3)).toEqual([1, 2, 3])
+ expect(g(_, 2, _)(1, 3)).toEqual([1, 2, 3])
+ expect(g(_, _, 3)(1, 2)).toEqual([1, 2, 3])
+
+ expect(g(1, _, _)(_, 3)(2)).toEqual([1, 2, 3])
+ expect(g(_, 2, _)(_, 3)(1)).toEqual([1, 2, 3])
+ expect(g(_, _, 3)(_, 2)(1)).toEqual([1, 2, 3])
+
+ expect(g(_, _, _)(_, _)(_)(1, 2, 3)).toEqual([1, 2, 3])
+ expect(g(_, _, _)(1, _, _)(_, _)(2, _)(_)(3)).toEqual([1, 2, 3])
+ })
+
+ it('supports @@functional/placeholder', function() {
+ var f = function() {
+ return Array.from(arguments)
+ }
+ var g = curryN(3, f)
+ var _ = '_' //{'@@functional/placeholder': true, 'x': Math.random()}
+
+ expect(g(1)(2)(3)).toEqual([1, 2, 3])
+ expect(g(1)(2, 3)).toEqual([1, 2, 3])
+ expect(g(1, 2)(3)).toEqual([1, 2, 3])
+ expect(g(1, 2, 3)).toEqual([1, 2, 3])
+
+ expect(g(_, 2, 3)(1)).toEqual([1, 2, 3])
+ expect(g(1, _, 3)(2)).toEqual([1, 2, 3])
+ expect(g(1, 2, _)(3)).toEqual([1, 2, 3])
+
+ expect(g(1, _, _)(2)(3)).toEqual([1, 2, 3])
+ expect(g(_, 2, _)(1)(3)).toEqual([1, 2, 3])
+ expect(g(_, _, 3)(1)(2)).toEqual([1, 2, 3])
+
+ expect(g(1, _, _)(2, 3)).toEqual([1, 2, 3])
+ expect(g(_, 2, _)(1, 3)).toEqual([1, 2, 3])
+ expect(g(_, _, 3)(1, 2)).toEqual([1, 2, 3])
+
+ expect(g(1, _, _)(_, 3)(2)).toEqual([1, 2, 3])
+ expect(g(_, 2, _)(_, 3)(1)).toEqual([1, 2, 3])
+ expect(g(_, _, 3)(_, 2)(1)).toEqual([1, 2, 3])
+
+ expect(g(_, _, _)(_, _)(_)(1, 2, 3)).toEqual([1, 2, 3])
+ expect(g(_, _, _)(1, _, _)(_, _)(2, _)(_)(3)).toEqual([1, 2, 3])
+ })
+
+ it('forwards extra arguments', function() {
+ var f = function() {
+ return Array.from(arguments)
+ }
+ var g = curryN(3, f)
+
+ expect(g(1, 2, 3)).toEqual([1, 2, 3])
+ expect(g(1, 2, 3, 4)).toEqual([1, 2, 3, 4])
+ expect(g(1, 2)(3, 4)).toEqual([1, 2, 3, 4])
+ expect(g(1)(2, 3, 4)).toEqual([1, 2, 3, 4])
+ expect(g(1)(2)(3, 4)).toEqual([1, 2, 3, 4])
+ })
+})
diff --git a/test/fp/evolve-transform.js b/test/fp/evolve-transform.js
new file mode 100644
index 0000000..9fba613
--- /dev/null
+++ b/test/fp/evolve-transform.js
@@ -0,0 +1,56 @@
+const evolve = require('../../src/deps/fp/evolve')
+const add = require('../../src/deps/math/add')
+
+const eq = (x, y, msg) => expect(x).toEqual(y)
+
+describe('evolve', function() {
+ it('creates a new object by evolving the `object` according to the `transformation` functions', function() {
+ var transf = {elapsed: add(1), remaining: add(-1)}
+ var object = {name: 'Tomato', elapsed: 100, remaining: 1400}
+ var expected = {name: 'Tomato', elapsed: 101, remaining: 1399}
+ eq(evolve(transf, object), expected)
+ })
+
+ it('does not invoke function if object does not contain the key', function() {
+ var transf = {n: add(1), m: add(1)}
+ var object = {m: 3}
+ var expected = {m: 4}
+ eq(evolve(transf, object), expected)
+ })
+
+ it('is not destructive', function() {
+ var transf = {elapsed: add(1), remaining: add(-1)}
+ var object = {name: 'Tomato', elapsed: 100, remaining: 1400}
+ var expected = {name: 'Tomato', elapsed: 100, remaining: 1400}
+ evolve(transf, object)
+ eq(object, expected)
+ })
+
+ it('is recursive', function() {
+ var transf = {nested: {second: add(-1), third: add(1)}}
+ var object = {first: 1, nested: {second: 2, third: 3}}
+ var expected = {first: 1, nested: {second: 1, third: 4}}
+ eq(evolve(transf, object), expected)
+ })
+
+ it('is curried', function() {
+ var tick = evolve({elapsed: add(1), remaining: add(-1)})
+ var object = {name: 'Tomato', elapsed: 100, remaining: 1400}
+ var expected = {name: 'Tomato', elapsed: 101, remaining: 1399}
+ eq(tick(object), expected)
+ })
+
+ it('ignores primitive value transformations', function() {
+ var transf = {n: 2, m: 'foo'}
+ var object = {n: 0, m: 1}
+ var expected = {n: 0, m: 1}
+ eq(evolve(transf, object), expected)
+ })
+
+ it('ignores null transformations', function() {
+ var transf = {n: null}
+ var object = {n: 0}
+ var expected = {n: 0}
+ eq(evolve(transf, object), expected)
+ })
+})
diff --git a/test/fp/first.js b/test/fp/first.js
new file mode 100644
index 0000000..5ee5741
--- /dev/null
+++ b/test/fp/first.js
@@ -0,0 +1,31 @@
+const first = require('../../src/deps/fp/first')
+const map = require('../../src/deps/loop/map/mapObjOrArray')
+const toArguments = require('../../src/deps/cast/toArguments')
+
+// https://github.com/jashkenas/underscore/blob/master/test/arrays.js#L6
+const eq = (x, y, msg) => expect(x).toEqual(y)
+test('first', () => {
+ eq(first([1, 2, 3]), 1, 'can pull out the first element of an array')
+
+ // @TODO `first` in underscore means first X, not first value...
+ // eq(first([1, 2, 3], 0), [], 'returns an empty array when n <= 0 (0 case)')
+ // eq(first([1, 2, 3], -1), [], 'returns an empty array when n <= 0 (negative case)')
+ // eq(first([1, 2, 3], 2), [1, 2], 'can fetch the first n elements')
+ // eq(first([1, 2, 3], 5), [1, 2, 3], 'returns the whole array if n > length')
+
+ let result = toArguments(4, 3, 2, 1)
+ eq(first(result), 4, 'works on an arguments object')
+
+ result = map([[1, 2, 3], [1, 2, 3]], (value, key) => {
+ console.log({value, key})
+ return first(value)
+ })
+
+ eq(result, [1, 1], 'works well with map')
+ eq(first(null), void 0, 'returns undefined when called on null')
+
+ // Array.prototype[0] = 'boo'
+ Array.prototype[-1] = 'boo'
+ eq(first([]), void 0, 'return undefined when called on a empty array')
+ delete Array.prototype[0]
+})
diff --git a/test/fp/firstLast.js b/test/fp/firstLast.js
new file mode 100644
index 0000000..bfbda97
--- /dev/null
+++ b/test/fp/firstLast.js
@@ -0,0 +1,32 @@
+const log = require('fliplog')
+const isFunction = require('../../src/deps/is/function')
+const findLast = require('../../src/deps/fp/last')
+const findLastIndex = require('../../src/deps/fp/lastIndex')
+const findFirst = require('../../src/deps/fp/first')
+
+test('can find last & last index in array', () => {
+ expect(isFunction(findLast)).toBe(true)
+ expect(isFunction(findLastIndex)).toBe(true)
+
+ const array = [0, 1, 2, 3]
+ const index = findLastIndex(array)
+ const last = findLast(array)
+
+ expect(array[index]).toEqual(last)
+ expect(index).toBe(3)
+})
+
+test('can find last & last index in object', () => {
+ const obj = {0: 0, 1: 1, 2: 2, 3: 3}
+ const index = findLastIndex(obj)
+ const last = findLast(obj)
+
+ expect(obj[index]).toEqual(last)
+ expect(index).toBe('3')
+})
+
+test('can find first', () => {
+ const array = [0, 1, 2, 3]
+ const first = findFirst(array)
+ expect(first).toEqual(0)
+})
diff --git a/test/fp/flip.js b/test/fp/flip.js
new file mode 100644
index 0000000..810a209
--- /dev/null
+++ b/test/fp/flip.js
@@ -0,0 +1,23 @@
+const flip = require('../../src/deps/fp/flip')
+
+function threeArgs(one, two, three) {
+ return [one, two, three]
+}
+
+test('flips fosho', function() {
+ const oneTwoThree = function($1, $2, $3) {
+ const flipped = flip(threeArgs)
+ const actual = flipped($1, $2, $3)
+ const usual = threeArgs($1, $2, $3)
+
+ // flipped 1 & 2 (same as .slice.reverse)
+ // expect(actual[0]).toEqual(usual[1])
+ // expect(actual[1]).toEqual(usual[2])
+
+ // only flips 2 <- disabled this
+ // expect(actual[2]).toEqual(usual[2])
+ expect(actual.reverse()).toEqual(usual)
+ }
+
+ oneTwoThree(1, 2, 3)
+})
diff --git a/test/fp/flip2.js b/test/fp/flip2.js
new file mode 100644
index 0000000..906fb33
--- /dev/null
+++ b/test/fp/flip2.js
@@ -0,0 +1,33 @@
+const flip2 = require('../../src/deps/fp/flip2')
+
+function threeArgs(one, two, three) {
+ return [one, two, three]
+}
+
+test('returns a function which inverts the first two arguments to the supplied function', function() {
+ const f = function(a, b, c) { return a + ' ' + b + ' ' + c }
+ const g = flip2(f)
+ expect(f('a', 'b', 'c')).toEqual('a b c')
+ expect(g('a', 'b', 'c')).toEqual('b a c')
+})
+test('returns a curried function', function() {
+ const f = function(a, b, c) { return a + ' ' + b + ' ' + c }
+ const g = flip2(f)('a')
+ expect(g('b', 'c')).toEqual('b a c')
+})
+test('flip2 fosho', function() {
+ const oneTwoThree = function($1, $2, $3) {
+ const flipped = flip2(threeArgs)
+ const actual = flipped($1, $2, $3)
+ const usual = threeArgs($1, $2, $3)
+
+ // flipped 1 & 2 (same as .slice.reverse)
+ expect(actual[0]).toEqual(usual[1])
+ expect(actual[1]).toEqual(usual[0])
+
+ // only flips 2 <- disabled this
+ // expect(actual[2]).toEqual(usual[2])
+ }
+
+ oneTwoThree(1, 2, 3)
+})
diff --git a/test/fp/last.js b/test/fp/last.js
new file mode 100644
index 0000000..ea36078
--- /dev/null
+++ b/test/fp/last.js
@@ -0,0 +1,36 @@
+const last = require('../../src/deps/fp/last')
+const lastIndex = require('../../src/deps/fp/lastIndex')
+const arrayToObj = require('../../src/deps/cast/arrayToObj')
+
+// https://github.com/jashkenas/underscore/blob/master/test/arrays.js#L61
+const eq = (x, y, msg) => expect(x).toEqual(y)
+test('last', () => {
+ const obj = arrayToObj([1, 2, 3])
+
+ eq(last(obj), 3)
+ eq(last([1, 2, 3]), 3, 'can pull out the last element of an array')
+
+ eq(last(null), undefined, 'returns undefined when called on null')
+
+ var arr = []
+ arr[-1] = 'boo'
+ eq(last(arr), 'boo', 'return undefined when called on a empty array')
+})
+
+test.skip('last with index @TODO', () => {
+ // let result = (function() { return _(arguments).last() })(1, 2, 3, 4)
+ // eq(result, 4, 'works on an arguments object')
+ // result = map([[1, 2, 3], [1, 2, 3]], last)
+ // eq(result, [3, 3], 'works well with map')
+
+ eq(last([1, 2, 3], 0), [], 'returns an empty array when n <= 0 (0 case)')
+ eq(last([1, 2, 3], -1), [], 'returns an empty array when n <= 0 (negative case)')
+ eq(last([1, 2, 3], 2), [2, 3], 'can fetch the last n elements')
+ eq(last([1, 2, 3], 5), [1, 2, 3], 'returns the whole array if n > length')
+
+ // changed to -1
+ eq(last(null), void 0, 'returns undefined when called on null')
+ var arr = []
+ arr[-1] = 'boo'
+ eq(last(arr), void 0, 'return undefined when called on a empty array')
+})
diff --git a/test/fp/nthArg.js b/test/fp/nthArg.js
new file mode 100644
index 0000000..40bfe97
--- /dev/null
+++ b/test/fp/nthArg.js
@@ -0,0 +1,34 @@
+const nthArg = require('../../src/deps/fp/nthArg')
+
+const eq = (x, y, msg) => expect(x).toEqual(y)
+
+describe('nthArg', function() {
+ it.skip('returns a function which returns its nth argument', function() {
+ eq(nthArg(0)('foo', 'bar'), 'foo')
+ eq(nthArg(1)('foo', 'bar'), 'bar')
+ })
+
+ it.skip('accepts negative offsets', function() {
+ eq(nthArg(-1)('foo', 'bar'), 'bar')
+ eq(nthArg(-2)('foo', 'bar'), 'foo')
+ eq(nthArg(-3)('foo', 'bar'), undefined)
+ })
+
+ it('returns a function with length n + 1 when n >= 0', function() {
+ eq(nthArg(0).length, 1)
+ eq(nthArg(1).length, 2)
+ eq(nthArg(2).length, 3)
+ eq(nthArg(3).length, 4)
+ })
+
+ it('returns a function with length 1 when n < 0', function() {
+ eq(nthArg(-1).length, 1)
+ eq(nthArg(-2).length, 1)
+ eq(nthArg(-3).length, 1)
+ })
+
+ it('returns a curried function', function() {
+ eq(nthArg(1)('foo', 'bar'), nthArg(1)('foo')('bar'))
+ eq(nthArg(2)('foo', 'bar', 'baz'), nthArg(2)('foo')('bar')('baz'))
+ })
+})
diff --git a/test/fp/path.js b/test/fp/path.js
new file mode 100644
index 0000000..8b3749a
--- /dev/null
+++ b/test/fp/path.js
@@ -0,0 +1,47 @@
+var eq = (actual, expected) => expect(actual).toEqual(expected)
+var path = require('../../src/deps/fp/path')
+
+describe('path', function() {
+ var deepObject = {a: {b: {c: 'c'}}, falseVal: false, nullVal: null, undefinedVal: undefined, arrayVal: ['arr']}
+ it('takes a path and an object and returns the value at the path or undefined', function() {
+ var obj = {
+ a: {
+ b: {
+ c: 100,
+ d: 200,
+ },
+ e: {
+ f: [100, 101, 102],
+ g: 'G',
+ },
+ h: 'H',
+ },
+ i: 'I',
+ j: ['J'],
+ }
+ eq(path(['a', 'b', 'c'], obj), 100)
+ eq(path([], obj), obj)
+ eq(path(['a', 'e', 'f', 1], obj), 101)
+ eq(path(['j', 0], obj), 'J')
+ eq(path(['j', 1], obj), undefined)
+ })
+
+ it('gets a deep property\'s value from objects', function() {
+ eq(path(['a', 'b', 'c'], deepObject), 'c')
+ eq(path(['a'], deepObject), deepObject.a)
+ })
+
+ it('returns undefined for items not found', function() {
+ eq(path(['a', 'b', 'foo'], deepObject), undefined)
+ eq(path(['bar'], deepObject), undefined)
+ eq(path(['a', 'b'], {a: null}), undefined)
+ })
+
+ it('works with falsy items', function() {
+ eq(path(['toString'], false), Boolean.prototype.toString)
+ })
+
+ it('is curried', function() {
+ eq(path(['arrayVal', '0'])(deepObject), 'arr')
+ })
+})
diff --git a/test/fp/pipe.js b/test/fp/pipe.js
new file mode 100644
index 0000000..1333d27
--- /dev/null
+++ b/test/fp/pipe.js
@@ -0,0 +1,63 @@
+const assert = require('assert')
+const isFunction = require('../../src/deps/is/function')
+const pipe = require('../../src/deps/fp/pipeTwo')
+const pipeAll = require('../../src/deps/fp/pipe')
+
+describe('pipe', function() {
+ it('is in correct order', function() {
+ function x(val) {
+ return val + 'x'
+ }
+ function y(val) {
+ return val + 'y'
+ }
+ function z(val) {
+ return val + 'z'
+ }
+
+ expect(pipeAll(x, y, z)('w')).toBe('wxyz')
+ })
+ it('is a variadic function', function() {
+ expect(isFunction(pipe)).toBe(true)
+ expect(isFunction(pipeAll)).toBe(true)
+
+ // is a smaller version just 2 args
+ // expect(pipe.length).toBe(0)
+ })
+
+ it('passes context to functions', function() {
+ function x(val) {
+ return this.x * val
+ }
+ function y(val) {
+ return this.y * val
+ }
+ function z(val) {
+ return this.z * val
+ }
+ var context = {
+ a: pipe(pipe(x, y), z),
+ x: 4,
+ y: 2,
+ z: 1,
+ }
+ expect(context.a(5)).toBe(40)
+ })
+
+ it.skip('throws if given no arguments', function() {
+ assert.throws(
+ function() { pipe() },
+ function(err) {
+ return err.constructor === Error &&
+ err.message === 'pipe requires at least one argument'
+ }
+ )
+ })
+
+ it('can be applied to one argument, (with 2 fns)', function() {
+ var f = function(a, b, c) { return [a, b, c] }
+ var g = pipe(f, x => x)
+ // expect(g.length).toEqual(3)
+ expect(g(1, 2, 3)).toEqual([1, 2, 3])
+ })
+})
diff --git a/test/fp/pluck.js b/test/fp/pluck.js
new file mode 100644
index 0000000..6fb3c2f
--- /dev/null
+++ b/test/fp/pluck.js
@@ -0,0 +1,21 @@
+const pluck = require('../../src/deps/loop/fantasy/pluck')
+
+describe.skip('pluck', function() {
+ var people = [
+ {name: 'Fred', age: 23},
+ {name: 'Wilma', age: 21},
+ {name: 'Pebbles', age: 2},
+ ]
+
+ it('returns a function that maps the appropriate property over an array', function() {
+ var nm = R.pluck('name')
+ eq(typeof nm, 'function')
+ eq(nm(people), ['Fred', 'Wilma', 'Pebbles'])
+ })
+
+ it.skip('behaves as a transducer when given a transducer in list position', function() {
+ var numbers = [{a: 1}, {a: 2}, {a: 3}, {a: 4}]
+ var transducer = R.compose(R.pluck('a'), R.map(R.add(1)), R.take(2))
+ eq(R.transduce(transducer, R.flip(R.append), [], numbers), [2, 3])
+ })
+})
diff --git a/test/fp/remove.js b/test/fp/remove.js
new file mode 100644
index 0000000..78b06d2
--- /dev/null
+++ b/test/fp/remove.js
@@ -0,0 +1,25 @@
+const remove = require('../../src/deps/fp/remove')
+const stress = require('../_stress')
+
+test('can remove obj and arr', function() {
+ expect(typeof remove).toBe('function')
+
+ const arr = [0, 1, 2]
+ remove(arr, 0)
+ expect(arr.length).toBe(2)
+ expect(arr).toEqual([1, 2])
+
+ const obj = {0: 0, 1: 1, 2: 2}
+ remove(obj, 0)
+ expect(Object.keys(obj).length).toBe(2)
+ expect(Object.values(obj)).toEqual([1, 2])
+
+
+ // and handles stress
+ // cannot handle this yet, because of `Array`
+ // stress(obj =>
+ // stress(key =>
+ // remove(obj, key)
+ // )
+ // )
+})
diff --git a/test/fp/replace.js b/test/fp/replace.js
new file mode 100644
index 0000000..8c273f6
--- /dev/null
+++ b/test/fp/replace.js
@@ -0,0 +1,18 @@
+const replace = require('../../src/deps/fp/replace')
+
+test('replaces substrings of the input string', () => {
+ expect(replace('1', 'one', '1 two three')).toEqual('one two three')
+})
+
+test('replaces regex matches of the input string', () => {
+ expect(replace(/\d+/g, 'num', '1 2 three')).toEqual('num num three')
+})
+
+test('is curried up to 3 arguments', () => {
+ expect(replace('').constructor, Function)
+ expect(replace('', '').constructor, Function)
+
+ var replaceSemicolon = replace(';')
+ var removeSemicolon = replaceSemicolon('')
+ expect(removeSemicolon('return 42;')).toEqual('return 42')
+})
diff --git a/test/fp/reverse.js b/test/fp/reverse.js
new file mode 100644
index 0000000..35ad7f8
--- /dev/null
+++ b/test/fp/reverse.js
@@ -0,0 +1,17 @@
+var reverse = require('../../src/deps/fp/reverse')
+
+var eq = (x, y) => expect(x).toEqual(y)
+
+test('reverses arrays', function() {
+ eq(reverse([]), [])
+ eq(reverse([1]), [1])
+ eq(reverse([1, 2]), [2, 1])
+ eq(reverse([1, 2, 3]), [3, 2, 1])
+})
+
+test('reverses strings', function() {
+ eq(reverse(''), '')
+ eq(reverse('a'), 'a')
+ eq(reverse('ab'), 'ba')
+ eq(reverse('abc'), 'cba')
+})
diff --git a/test/fp/slice.js b/test/fp/slice.js
new file mode 100644
index 0000000..5dbf6c1
--- /dev/null
+++ b/test/fp/slice.js
@@ -0,0 +1,35 @@
+const castArgs = require('../../src/deps/cast/toArguments')
+const slice = require('../../src/deps/flipped/sliceFlipped')
+
+describe('slice', function() {
+ it('retrieves the proper sublist of a list', function() {
+ var list = [8, 6, 7, 5, 3, 0, 9]
+ eq(slice(2, 5, list), [7, 5, 3])
+ })
+ it('handles array-like object', function() {
+ var args = castArgs(1, 2, 3, 4, 5)
+ eq(slice(1, 4, args), [2, 3, 4])
+ })
+ it('can operate on strings', function() {
+ eq(slice(0, 0, 'abc'), '')
+ eq(slice(0, 1, 'abc'), 'a')
+ eq(slice(0, 2, 'abc'), 'ab')
+ eq(slice(0, 3, 'abc'), 'abc')
+ eq(slice(0, 4, 'abc'), 'abc')
+ eq(slice(1, 0, 'abc'), '')
+ eq(slice(1, 1, 'abc'), '')
+ eq(slice(1, 2, 'abc'), 'b')
+ eq(slice(1, 3, 'abc'), 'bc')
+ eq(slice(1, 4, 'abc'), 'bc')
+ eq(slice(0, -4, 'abc'), '')
+ eq(slice(0, -3, 'abc'), '')
+ eq(slice(0, -2, 'abc'), 'a')
+ eq(slice(0, -1, 'abc'), 'ab')
+ eq(slice(0, -0, 'abc'), '')
+ eq(slice(-2, -4, 'abc'), '')
+ eq(slice(-2, -3, 'abc'), '')
+ eq(slice(-2, -2, 'abc'), '')
+ eq(slice(-2, -1, 'abc'), 'b')
+ eq(slice(-2, -0, 'abc'), '')
+ })
+})
diff --git a/test/fp/times.js b/test/fp/times.js
new file mode 100644
index 0000000..7123451
--- /dev/null
+++ b/test/fp/times.js
@@ -0,0 +1,20 @@
+var R = require('..')
+
+describe.skip('times', function() {
+ it('takes a map func', function() {
+ eq(R.times(R.identity, 5), [0, 1, 2, 3, 4])
+ eq(R.times(function(x) {
+ return x * 2
+ }, 5), [0, 2, 4, 6, 8])
+ })
+
+ it('is curried', function() {
+ var mapid = R.times(R.identity)
+ eq(mapid(5), [0, 1, 2, 3, 4])
+ })
+
+ it('throws if second argument is not a valid array length', function() {
+ assert.throws(function() { R.times(3)('cheers!') }, RangeError)
+ assert.throws(function() { R.times(R.identity, -1) }, RangeError)
+ })
+})
diff --git a/test/fp/trim.js b/test/fp/trim.js
new file mode 100644
index 0000000..f09e888
--- /dev/null
+++ b/test/fp/trim.js
@@ -0,0 +1,31 @@
+var trim = require('../../src/deps/string/trim')
+
+var eq = (x, y) => expect(x).toEqual(y)
+
+describe('trim', function() {
+ var test = '\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028\u2029\uFEFFHello, World!\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028\u2029\uFEFF'
+
+ it('trims a string', function() {
+ eq(trim(' xyz '), 'xyz')
+ })
+
+ it('trims all ES5 whitespace', function() {
+ eq(trim(test), 'Hello, World!')
+ eq(trim(test).length, 13)
+ })
+
+ it('does not trim the zero-width space', function() {
+ eq(trim('\u200b'), '\u200b')
+ eq(trim('\u200b').length, 1)
+ })
+
+ if (typeof String.prototype.trim !== 'function') {
+ it('falls back to a shim if String.prototype.trim is not present', function() {
+ eq(trim(' xyz '), 'xyz')
+ eq(trim(test), 'Hello, World!')
+ eq(trim(test).length, 13)
+ eq(trim('\u200b'), '\u200b')
+ eq(trim('\u200b').length, 1)
+ })
+ }
+})
diff --git a/test/fp/where.js b/test/fp/where.js
new file mode 100644
index 0000000..06e371b
--- /dev/null
+++ b/test/fp/where.js
@@ -0,0 +1,66 @@
+const equals = require('../../src/deps/fp/equals')
+const where = require('../../src/deps/fp/where')
+
+const eq = (x, y) => expect(x).toEqual(y)
+
+describe('where', function() {
+ it('returns true if the test object satisfies the spec', function() {
+ var spec = {x: equals(1), y: equals(2)}
+ var test1 = {x: 0, y: 200}
+ var test2 = {x: 0, y: 10}
+ var test3 = {x: 1, y: 101}
+ var test4 = {x: 1, y: 2}
+ eq(where(spec, test1), false)
+ eq(where(spec, test2), false)
+ eq(where(spec, test3), false)
+ eq(where(spec, test4), true)
+ })
+
+ it('does not need the spec and the test object to have the same interface (the test object will have a superset of the specs properties)', function() {
+ var spec = {x: equals(100)}
+ var test1 = {x: 20, y: 100, z: 100}
+ var test2 = {w: 1, x: 100, y: 100, z: 100}
+
+ eq(where(spec, test1), false)
+ eq(where(spec, test2), true)
+ })
+
+ it('matches specs that have undefined properties', function() {
+ var spec = {x: equals(undefined)}
+ var test1 = {}
+ var test2 = {x: null}
+ var test3 = {x: undefined}
+ var test4 = {x: 1}
+ eq(where(spec, test1), true)
+ eq(where(spec, test2), false)
+ eq(where(spec, test3), true)
+ eq(where(spec, test4), false)
+ })
+
+ it('is curried', function() {
+ var predicate = where({x: equals(1), y: equals(2)})
+ eq(predicate({x: 1, y: 2, z: 3}), true)
+ eq(predicate({x: 3, y: 2, z: 1}), false)
+ })
+
+ it('is true for an empty spec', function() {
+ eq(where({}, {a: 1}), true)
+ })
+
+ it('matches inherited properties', function() {
+ var spec = {
+ toString: equals(Object.prototype.toString),
+ valueOf: equals(Object.prototype.valueOf),
+ }
+ eq(where(spec, {}), true)
+ })
+
+ it('does not match inherited spec', function() {
+ function Spec() { this.y = equals(6) }
+ Spec.prototype.x = equals(5)
+ var spec = new Spec()
+
+ eq(where(spec, {y: 6}), true)
+ eq(where(spec, {x: 5}), false)
+ })
+})
diff --git a/test/is/arrayLike.js b/test/is/arrayLike.js
new file mode 100644
index 0000000..8e5955c
--- /dev/null
+++ b/test/is/arrayLike.js
@@ -0,0 +1,48 @@
+var _isArrayLike = require('../../src/deps/is/arrayLike')
+
+var eq = (x, y) => expect(x).toEqual(y)
+
+describe('isArrayLike', function() {
+ it('is true for Arrays', function() {
+ eq(_isArrayLike([]), true)
+ eq(_isArrayLike([1, 2, 3, 4]), true)
+ eq(_isArrayLike([null]), true)
+ })
+
+ it('is true for arguments', function() {
+ function test() {
+ return _isArrayLike(arguments)
+ }
+ eq(test(), true)
+ eq(test(1, 2, 3), true)
+ eq(test(null), true)
+ })
+
+ it('is false for Strings', function() {
+ eq(_isArrayLike(''), false)
+ eq(_isArrayLike('abcdefg'), false)
+ })
+
+ it('is true for arbitrary objects with numeric length, if extreme indices are defined', function() {
+ var obj1 = {length: 0}
+ var obj2 = {0: 'something', length: 0}
+ var obj3 = {0: void 0, length: 0}
+ var obj4 = {0: 'zero', 1: 'one', length: 2}
+ var obj5 = {0: 'zero', length: 2}
+ var obj6 = {1: 'one', length: 2}
+ eq(_isArrayLike(obj1), true)
+ eq(_isArrayLike(obj2), true)
+ eq(_isArrayLike(obj3), true)
+ eq(_isArrayLike(obj4), true)
+ eq(_isArrayLike(obj5), false)
+ eq(_isArrayLike(obj6), false)
+ })
+
+ it('is false for everything else', function() {
+ eq(_isArrayLike(undefined), false)
+ eq(_isArrayLike(1), false)
+ eq(_isArrayLike({}), false)
+ eq(_isArrayLike(false), false)
+ eq(_isArrayLike(function() {}), false)
+ })
+})
diff --git a/test/is/empty.js b/test/is/empty.js
new file mode 100644
index 0000000..eff5985
--- /dev/null
+++ b/test/is/empty.js
@@ -0,0 +1,49 @@
+const isEmpty = require('../../src/deps/is/empty')
+
+test('returns false for null', function() {
+ expect(isEmpty(null)).toBe(false)
+})
+
+test('returns false for undefined', function() {
+ expect(isEmpty(undefined)).toBe(false)
+})
+
+test('returns true for empty string', function() {
+ console.log(isEmpty(''), isEmpty(''), isEmpty(''))
+ expect(isEmpty('')).toBe(true)
+ expect(isEmpty(' ')).toBe(false)
+})
+
+test('returns true for empty array', function() {
+ expect(isEmpty([])).toBe(true)
+ // expect(isEmpty([[]])).toBe(false)
+})
+
+test('returns true for empty object', function() {
+ expect(isEmpty({})).toBe(true)
+ expect(isEmpty({x: 0})).toBe(false)
+})
+
+test('returns true for empty arguments object', function() {
+ expect(
+ isEmpty(
+ (function() {
+ return arguments
+ })()
+ )
+ ).toBe(true)
+
+ expect(
+ isEmpty(
+ (function() {
+ return arguments
+ })(0)
+ )
+ ).toBe(false)
+})
+
+test('returns false for every other value', function() {
+ expect(isEmpty(0)).toBe(false)
+ expect(isEmpty(NaN)).toBe(false)
+ expect(isEmpty([''])).toBe(false)
+})
diff --git a/test/is/hasIn.js b/test/is/hasIn.js
new file mode 100644
index 0000000..9fdcc02
--- /dev/null
+++ b/test/is/hasIn.js
@@ -0,0 +1,31 @@
+let hasIn = require('../../src/deps/is/hasIn')
+const flip2 = require('../../src/deps/fp/flip2')
+
+hasIn = flip2(hasIn)
+
+const eq = (x, y, msg) => expect(x).toEqual(y)
+
+describe('hasIn', function() {
+ const fred = {name: 'Fred', age: 23}
+ const anon = {age: 99}
+
+ it('returns a function that checks the appropriate property', function() {
+ const nm = hasIn('name')
+ eq(typeof nm, 'function')
+ eq(nm(fred), true)
+ eq(nm(anon), false)
+ })
+
+ it('checks properties from the prototype chain', function() {
+ const Person = function() {}
+ Person.prototype.age = function() {}
+
+ const bob = new Person()
+ eq(hasIn('age', bob), true)
+ })
+
+ it('works properly when called with two arguments', function() {
+ eq(hasIn('name', fred), true)
+ eq(hasIn('name', anon), false)
+ })
+})
diff --git a/test/is/is.js b/test/is/is.js
index 5dbd020..4d3961a 100644
--- a/test/is/is.js
+++ b/test/is/is.js
@@ -4,15 +4,11 @@ const isPromise = require('../../src/deps/is/promise')
const isAsync = require('../../src/deps/is/async')
const isAsyncish = require('../../src/deps/is/asyncish')
const isNative = require('../../src/deps/is/native')
-const ObjectDefine = require('../../src/deps/define')
+const isClass = require('../../src/deps/is/class')
+const ObjectDefine = require('../../src/deps/util/define')
+const size = require('../../src/deps/util/size')
const stress = require('../_stress')
-const {
- isMap,
- isSet,
- isFunction,
- isObjWithKeys,
- isPrototypeOf,
-} = require('./')
+const {isMap, isSet, isFunction, isObjWithKeys, isPrototypeOf} = require('./')
test('stress', () => {
stress()
@@ -83,7 +79,8 @@ var generatorFunction = function* named() {
async function asyncFunction() {}
const emptyPromise = new Promise(r => r)
const datasObjs = [
- new String('str'),
+ // @TODO
+ // new String('str'),
Object.assign(anon2, {keys: true}),
{keys: true},
]
@@ -110,6 +107,8 @@ test('should work for Set', () => {
})
test('objWithKeys', () => {
+ // datas.forEach(data => console.log([data, isObjWithKeys(data), size(data)]))
+ // datasObjs.forEach(data => console.log([data, isObjWithKeys(data)]))
datas.map(data => expect(isObjWithKeys(data)).toBe(false))
datasObjs.map(data => expect(isObjWithKeys(data)).toBe(true))
})
@@ -121,10 +120,15 @@ test('objWithKeys', () => {
// t.false(isClass({}))
// })
+test('isClass', () => {
+ const iz = isClass(eval('class Eh {}'))
+ expect(iz).toBe(true)
+ expect(isClass({})).toBe(false)
+})
test('isPrototypeOf', () => {
class SuperProto {}
class SubProto extends SuperProto {}
- var sub = new SubProto()
+ const sub = new SubProto()
// SuperProto.isPrototypeOf(sub)
expect(isPrototypeOf(Object.getPrototypeOf(sub), sub)).toBe(true)
@@ -139,7 +143,7 @@ test('isPrototypeOf on instance', () => {
enumerable: false,
value: instance => isPrototypeOf(SubProto.prototype, instance),
})
- var sub = new SubProto()
+ const sub = new SubProto()
expect(new RegExp() instanceof SubProto).toBe(false)
expect(sub instanceof SubProto).toBe(true)
diff --git a/test/is/json.js b/test/is/json.js
new file mode 100644
index 0000000..19dba4f
--- /dev/null
+++ b/test/is/json.js
@@ -0,0 +1,88 @@
+var isJSON = require('../../src/deps/is/JSON')
+
+var jsun = `{
+ "links": {
+ "self": "http://example.com/articles",
+ "next": "http://example.com/articles?page[offset]=2",
+ "last": "http://example.com/articles?page[offset]=10"
+ },
+ "data": [{
+ "type": "articles",
+ "id": "1",
+ "attributes": {
+ "title": "JSON API paints my bikeshed!"
+ },
+ "relationships": {
+ "author": {
+ "links": {
+ "self": "http://example.com/articles/1/relationships/author",
+ "related": "http://example.com/articles/1/author"
+ },
+ "data": { "type": "people", "id": "9" }
+ },
+ "comments": {
+ "links": {
+ "self": "http://example.com/articles/1/relationships/comments",
+ "related": "http://example.com/articles/1/comments"
+ },
+ "data": [
+ { "type": "comments", "id": "5" },
+ { "type": "comments", "id": "12" }
+ ]
+ }
+ },
+ "links": {
+ "self": "http://example.com/articles/1"
+ }
+ }],
+ "included": [{
+ "type": "people",
+ "id": "9",
+ "attributes": {
+ "first-name": "Dan",
+ "last-name": "Gebhardt",
+ "twitter": "dgeb"
+ },
+ "links": {
+ "self": "http://example.com/people/9"
+ }
+ }, {
+ "type": "comments",
+ "id": "5",
+ "attributes": {
+ "body": "First!"
+ },
+ "relationships": {
+ "author": {
+ "data": { "type": "people", "id": "2" }
+ }
+ },
+ "links": {
+ "self": "http://example.com/comments/5"
+ }
+ }, {
+ "type": "comments",
+ "id": "12",
+ "attributes": {
+ "body": "I like XML better"
+ },
+ "relationships": {
+ "author": {
+ "data": { "type": "people", "id": "9" }
+ }
+ },
+ "links": {
+ "self": "http://example.com/comments/12"
+ }
+ }]
+}`
+
+test('isJSON', () => {
+ expect(isJSON(jsun)).toBe(true)
+ expect(isJSON('[{}]')).toBe(true)
+
+ expect(isJSON({json: false})).toBe(false)
+ expect(isJSON([{a: [1]}])).toBe(false)
+ expect(isJSON('{malformed: {true}, oops},')).toBe(false)
+ expect(isJSON('{malformed: {true}, oops}')).toBe(false)
+})
diff --git a/test/is/not-exported-in-entry.js b/test/is/not-exported-in-entry.js
new file mode 100644
index 0000000..63cfbbf
--- /dev/null
+++ b/test/is/not-exported-in-entry.js
@@ -0,0 +1,134 @@
+const isUndefinedLike = require('../../src/deps/is/undefinedLike')
+const isBrowser = require('../../src/deps/is/browser')
+const isCircular = require('../../src/deps/is/circular')
+const isTrue = require('../../src/deps/is/true')
+const isNumber = require('../../src/deps/is/number')
+const isArrayOf = require('../../src/deps/is/arrayOf')
+const isWeakMap = require('../../src/deps/is/weakMap')
+const isWeakSet = require('../../src/deps/is/weakSet')
+const isInstanceOf = require('../../src/deps/is/instanceOf')
+const always = require('../../src/deps/fp/always')
+const localGlobal = require('../../src/deps/util/localGlobal')
+const hasInMatching = require('../../src/deps/fp/hasInMatching')
+// const isFormData = require('../../src/deps/is/formData')
+const stress = require('../_stress')
+
+test('localGlobal', () => {
+ expect(localGlobal()).toBe(global)
+})
+
+test('isUndefinedLike', () => {
+ const stringy = isUndefinedLike('undefined')
+ const native = isUndefinedLike(undefined)
+ const void0 = isUndefinedLike(void 0)
+ const falsey = isUndefinedLike('eh')
+
+ expect(stringy).toBe(true)
+ expect(native).toBe(true)
+ expect(void0).toBe(true)
+ expect(falsey).toBe(false)
+ stress(isUndefinedLike)
+})
+
+test('isBrowser', () => {
+ // @NOTE jest seems to polyfil it
+ const window = global.window
+ delete global.window
+
+ expect(isBrowser()).toBe(false)
+
+ global.window = window
+})
+
+// mocked window by default by jest o.o dangerous magic
+test('isBrowser - mock window', () => {
+ // global.window = {}
+ // global.window.window = global.window
+ // console.log('undefinedLike window', typeof window, !isUndefinedLike(typeof window))
+ // console.log('is!undefinedLike window.window', !isUndefinedLike(window.window))
+ // console.log('isbrowser:', !isUndefinedLike(typeof window) && !isUndefinedLike(window.window))
+ expect(isBrowser()).toBe(true)
+})
+
+test('isCircular', () => {
+ const a = {}
+ a.b = a
+
+ expect(isCircular(a)).toBe(true)
+
+ const eh = {}
+ eh.b = {
+ c: eh,
+ }
+ expect(isCircular(eh)).toBe(true)
+
+
+ const four = {}
+ four.b = {
+ c: 4,
+ }
+ expect(isCircular(four)).toBe(false)
+
+ const array = []
+ array.push(array)
+
+ expect(isCircular(array)).toBe(true)
+
+ expect(isCircular([])).toBe(false)
+ expect(isCircular({})).toBe(false)
+ expect(isCircular(undefined)).toBe(false)
+ expect(isCircular(null)).toBe(false)
+ expect(isCircular('eh')).toBe(false)
+})
+
+test('isInstanceOf', () => {
+ const isObjInstance = isInstanceOf(Object)
+ expect(isObjInstance({})).toBe(true)
+ expect(isObjInstance(undefined)).toBe(false)
+
+ const isArrInstance = isInstanceOf(Array)
+ expect(isArrInstance({})).toBe(false)
+
+ expect(isArrInstance(new Array())).toBe(true)
+})
+
+test('hasInMatching', () => {
+ const obj = {prop: true}
+ const hasTrueProp = hasInMatching(isTrue, '_', 'prop')
+ expect(hasTrueProp(obj)).toBe(true)
+ expect(hasInMatching(isTrue, obj, 'prop')).toBe(true)
+
+ const array = [100]
+ const firstIsNumber = hasInMatching(isNumber, '_', 0)
+ expect(firstIsNumber(array)).toBe(true)
+ expect(hasInMatching(isNumber, array, 0)).toBe(true)
+
+ expect(hasInMatching(isNumber, array, 1)).toBe(false)
+ expect(hasInMatching(isNumber, obj, 'prop')).toBe(false)
+ expect(hasInMatching(isNumber, obj, 'nope')).toBe(false)
+ expect(hasInMatching(always(false), obj, 'prop')).toBe(false)
+})
+
+test('isArrayOf', () => {
+ const nums = [0, 1, 2, 3]
+ const truths = [true, true, true]
+ const mixed = [true, true, true, 0, true, 100, false]
+ const allNums = isArrayOf(isNumber)
+ const allTrue = isArrayOf(isTrue)
+
+ expect(allNums(nums)).toBe(true)
+ expect(allTrue(truths)).toBe(true)
+
+ expect(allTrue(mixed)).toBe(false)
+ expect(allNums(mixed)).toBe(false)
+})
+
+test('isWeak', () => {
+ expect(isWeakMap(new WeakMap())).toBe(true)
+ expect(isWeakMap(new Map())).toBe(false)
+ expect(isWeakMap({})).toBe(false)
+
+ expect(isWeakSet(new WeakSet())).toBe(true)
+ expect(isWeakSet(new Set())).toBe(false)
+ expect(isWeakSet({})).toBe(false)
+})
diff --git a/test/is/simple.js b/test/is/simple.js
index 1e505e1..098e45e 100644
--- a/test/is/simple.js
+++ b/test/is/simple.js
@@ -1,8 +1,8 @@
const stress = require('../_stress')
-const {isObj, isDate, isRegExp, isArray, isError, isFunction} = require('./')
+const {isObj, isDate, isRegExp, isArray, isError, isFunction, isNil} = require('./')
test('should work for objects', () => {
- function Test() {}
+ function Test() { }
var instance = new Test()
var literal = {}
var create = Object.create(null)
@@ -41,7 +41,7 @@ test('should not mark regular expressions as Functions, but they are PureObjects
})
test('should work for functions', () => {
- expect(isFunction(t => {})).toBe(true)
+ expect(isFunction(t => { })).toBe(true)
expect(isFunction(new Function())).toBe(true)
stress(isFunction)
})
@@ -51,3 +51,12 @@ test('should work for Errors', () => {
expect(isObj(new Error(''))).toBe(true)
stress(isError)
})
+
+// test('isNill', () => {
+// eq(isNil(void 0), true)
+// eq(isNil(null), true)
+// eq(isNil([]), false)
+// eq(isNil({}), false)
+// eq(isNil(0), false)
+// eq(isNil(''), false)
+// })
diff --git a/test/is/url.js b/test/is/url.js
new file mode 100644
index 0000000..b5be922
--- /dev/null
+++ b/test/is/url.js
@@ -0,0 +1,20 @@
+test('isUrl', () => {
+ console.log('todo')
+})
+// const urls = {
+// 'www': 'www.facebook.com',
+// 'https': 'https://google.com',
+// 'httpswww': 'https://www.eh.ca',
+// 'org': 'wikipedia.org',
+// 'nope': 'wikipedia',
+// }
+//
+// const mapValues = (obj, fn) => {
+// Object.keys(obj).forEach(key => {
+// obj[key] = [obj[key], fn(obj[key])]
+// })
+// return obj
+// }
+//
+// mapValues(urls, isUrl)
+// require('fliplog').quick(urls)
diff --git a/test/loop/index.js b/test/loop/index.js
new file mode 100644
index 0000000..04b5b76
--- /dev/null
+++ b/test/loop/index.js
@@ -0,0 +1,84 @@
+const log = require('fliplog')
+const {
+ keys,
+ remove,
+ values,
+ isReal,
+ isEmpty,
+ not,
+ always,
+ concat,
+} = require('../../exports')
+const {
+ arrayEach,
+ baseEach,
+ baseFor,
+ forEach,
+ forOwn,
+ filterWhere,
+ mapObjOrArray,
+ mapAcum,
+ mapKey,
+ mapObj,
+ sort,
+ sortBy,
+ sortByR,
+ sortWith,
+ comparator,
+ keyVal,
+ flipped,
+} = require('../../src/deps/loop')
+
+test('forOwn', () => {
+ const object = {eh: true, oh: 1, canada: 'yes'}
+ forOwn(object, function(value, key) {
+ delete object[key]
+ })
+ expect(keys(object).length).toBe(0)
+})
+test('flipped: forOwn', () => {
+ const object = {eh: true, oh: 1, canada: 'yes'}
+ flipped.forOwn(object, key => delete object[key])
+ expect(keys(object).length).toBe(0)
+})
+test('flipped: forEach with `remove`', () => {
+ const object = {eh: true, oh: 1, canada: 'yes'}
+ // curried, nice
+ flipped.forEach(object, remove(object))
+ expect(keys(object).length).toBe(0)
+})
+test('flipped: mapKey with .concat', () => {
+ const appendEh = concat('_', 'eh')
+ const object = {eh: true, oh: 1, canada: 'yes'}
+ const result = flipped.mapKey(object, appendEh)
+
+ const ogKeys = keys(object)
+ const resultKeys = keys(result)
+ const ogToResultKeys = mapObjOrArray(keys(object), appendEh)
+ expect(resultKeys).toEqual(ogToResultKeys)
+})
+test('flipped: mapKey', () => {
+ const object = {eh: true, oh: 1, canada: 'yes'}
+ const result = flipped.mapKey(object, always(''))
+ expect(keys(object).length).toBe(3)
+ expect(keys(result).filter(not(isEmpty)).length).toBe(0)
+})
+test('flipped: map', () => {
+ // @TODO use cast/pairs
+ // const object = {eh: true, oh: 1, canada: 'yes'}
+ const array = ['eh', true, 'oh', 1, 'canada', 'yes']
+ const ogLength = array.length
+ const result = flipped.mapArray(array, always(null))
+ expect(values(array).length).toBe(ogLength)
+ expect(values(result).filter(isReal).length).toBe(0)
+})
+
+const comparatorMsg = `comparator:
+ builds a comparator function
+ for sorting out of a simple predicate
+ that reports whether the first param is smaller`
+
+test(comparatorMsg, () => {
+ const compareLessThan = comparator((a, b) => a < b)
+ eq([3, 1, 8, 1, 2, 5].sort(compareLessThan), [1, 1, 2, 3, 5, 8])
+})
diff --git a/test/loop/map/mapAcum.js b/test/loop/map/mapAcum.js
new file mode 100644
index 0000000..1de2d3d
--- /dev/null
+++ b/test/loop/map/mapAcum.js
@@ -0,0 +1,37 @@
+const mapAccum = require('../../../src/deps/loop/map/mapAcum')
+
+describe('mapAccum', function() {
+ var add = function(a, b) {
+ return [a + b, a + b]
+ }
+ var mult = function(a, b) {
+ return [a * b, a * b]
+ }
+ var concat = function(a, b) {
+ return [a.concat(b), a.concat(b)]
+ }
+
+ it('map and accumulate simple functions over arrays with the supplied accumulator', function() {
+ eq(mapAccum(add, 0, [1, 2, 3, 4]), [10, [1, 3, 6, 10]])
+ eq(mapAccum(mult, 1, [1, 2, 3, 4]), [24, [1, 2, 6, 24]])
+ })
+
+ it('returns the list and accumulator for an empty array', function() {
+ eq(mapAccum(add, 0, []), [0, []])
+ eq(mapAccum(mult, 1, []), [1, []])
+ eq(mapAccum(concat, [], []), [[], []])
+ })
+
+ it('is curried', function() {
+ var addOrConcat = mapAccum(add)
+ var sum = addOrConcat(0)
+ var cat = addOrConcat('')
+ eq(sum([1, 2, 3, 4]), [10, [1, 3, 6, 10]])
+ eq(cat(['1', '2', '3', '4']), ['1234', ['1', '12', '123', '1234']])
+ })
+
+ it('correctly reports the arity of curried versions', function() {
+ var sum = mapAccum(add, 0)
+ eq(sum.length, 1)
+ })
+})
diff --git a/test/deps/reduce.js b/test/loop/reduce/reduce.js
similarity index 88%
rename from test/deps/reduce.js
rename to test/loop/reduce/reduce.js
index 9cae54c..6c62ab2 100644
--- a/test/deps/reduce.js
+++ b/test/loop/reduce/reduce.js
@@ -1,6 +1,6 @@
const log = require('fliplog')
-const reduceEntries = require('../../src/deps/reduce/entries')
-const reduce = require('../../src/deps/reduce')
+const reduceEntries = require('../../../src/deps/reduce/entries')
+const reduce = require('../../../src/deps/reduce')
test('reduce calls .entries()', () => {
expect.assertions(2)
diff --git a/test/math/modulo.js b/test/math/modulo.js
new file mode 100644
index 0000000..43a8f7a
--- /dev/null
+++ b/test/math/modulo.js
@@ -0,0 +1,30 @@
+const modulo = require('../../src/deps/math/modulo')
+
+const eq = (x, y, msg) => expect(x).toEqual(y)
+
+describe('modulo', function() {
+ it('divides the first param by the second and returns the remainder', function() {
+ eq(modulo(100, 2), 0)
+ eq(modulo(100, 3), 1)
+ eq(modulo(100, 17), 15)
+ })
+
+ it('is curried', function() {
+ var hundredMod = modulo(100)
+ eq(typeof hundredMod, 'function')
+ eq(hundredMod(2), 0)
+ eq(hundredMod(3), 1)
+ eq(hundredMod(17), 15)
+ })
+
+ it('behaves right curried when passed `__` for its first argument', function() {
+ var isOdd = modulo('_', 2)
+ eq(typeof isOdd, 'function')
+ eq(isOdd(3), 1)
+ eq(isOdd(198), 0)
+ })
+
+ it('preserves javascript-style modulo evaluation for negative numbers', function() {
+ eq(modulo(-5, 4), -1)
+ })
+})
diff --git a/test/parent.js b/test/parent.js
index a4951b4..beac536 100644
--- a/test/parent.js
+++ b/test/parent.js
@@ -30,6 +30,7 @@ test('.decorate(parent)', () => {
const master = new Master()
master.advanced('a+')
master.easy(true)
+ // log.quick(master)
expect(master.get('easy-peasy')).toBe(true)
expect(master.eh.get('advanced') === 'a+').toBe(true)
})
diff --git a/test/shorthands.js b/test/shorthands.js
index 9130891..e622642 100644
--- a/test/shorthands.js
+++ b/test/shorthands.js
@@ -41,6 +41,7 @@ test('.method().encase().onValid', () => {
.encase()
.then(val => expect(val).toBeTruthy())
.catch(e => {
+ throw e
/* istanbul ignore next: this means tests fail, shouldn't hit this */
fail(e)
})
diff --git a/test/deps/camelcase.js b/test/string/camelCase.js
similarity index 83%
rename from test/deps/camelcase.js
rename to test/string/camelCase.js
index 385b91a..5a0551a 100644
--- a/test/deps/camelcase.js
+++ b/test/string/camelCase.js
@@ -1,6 +1,6 @@
// https://github.com/substack/camelize/blob/master/test/camel.js
-const log = require('fliplog');
-const camelize = require('../../src/deps/camel-case')
+const log = require('fliplog')
+const camelize = require('../../src/deps/string/camelCase')
test('camelCase', () => {
expect(camelize('one two') == 'oneTwo').toBe(true)
diff --git a/test/string/string.js b/test/string/string.js
new file mode 100644
index 0000000..1d28c82
--- /dev/null
+++ b/test/string/string.js
@@ -0,0 +1,18 @@
+const match = require('../../src/deps/string/match')
+const pipe = require('../../src/deps/fp/pipe')
+const from = require('../../src/deps/util/from')
+const className = require('../../src/deps/string/classNames')
+const stress = require('../_stress')
+
+test('className', () => {
+ class Eh {}
+ expect(className(new Eh()).split('.').shift()).toEqual('Eh')
+})
+
+test('match', () => {
+ const _match = pipe(match, from)
+ expect(_match(null, 'eh')).toEqual([])
+ expect(_match('eh', 'eh')).toEqual(['eh'])
+ expect(_match('eh', '')).toEqual([])
+ stress(match)
+})
diff --git a/test/typed.js b/test/typed.js
index a39d102..3988de8 100644
--- a/test/typed.js
+++ b/test/typed.js
@@ -1,3 +1,4 @@
+const log = require('fliplog')
const isLength = require('validator/lib/isLength')
const isNumeric = require('validator/lib/isNumeric')
const trim = require('validator/lib/trim')
@@ -44,7 +45,8 @@ test(testChecklist, () => {
// typed.short(val => {}) // valid function
try {
- typed.short(!!Boolean) // boolean, not a function, throws
+ const result = typed.short(!!Boolean) // boolean, not a function, throws
+ log.red('SHOULD NOT HIT THIS').data({result}).echo()
}
catch (e) {
return
diff --git a/test/util/keys.js b/test/util/keys.js
new file mode 100644
index 0000000..6d1db65
--- /dev/null
+++ b/test/util/keys.js
@@ -0,0 +1,66 @@
+const keysIn = require('../../src/deps/util/keysIn')
+const keys = require('../../src/deps/util/keys')
+const repeat = require('../../src/deps/fp/repeat')
+const map = require('../../src/deps/loop/fantasy/_map')
+
+const eq = (x, y, msg) => expect(x).toEqual(y)
+// eslint-disable-next-line
+const PRIMITIVES_LIST = [null, undefined, 55, '', true, false, NaN, Infinity, , []]
+
+var obj = {
+ a: 100,
+ b: [1, 2, 3],
+ c: {x: 200, y: 300},
+ d: 'D',
+ e: null,
+ f: undefined,
+}
+
+function C() { this.a = 100; this.b = 200 }
+C.prototype.x = function() { return 'x' }
+C.prototype.y = 'y'
+var cobj = new C()
+
+describe('keysIn', function() {
+ it('returns an array of the given object\'s keys', function() {
+ eq(keysIn(obj).sort(), ['a', 'b', 'c', 'd', 'e', 'f'])
+ })
+
+ it('includes the given object\'s prototype properties', function() {
+ eq(keysIn(cobj).sort(), ['a', 'b', 'x', 'y'])
+ })
+ it('ignores proto with guard', function() {
+ eq(keysIn(cobj, true).sort(), ['a', 'b'])
+ })
+
+ it.skip('works for primitives', function() {
+ var result = map(function(val) {
+ return keysIn(val)
+ }, PRIMITIVES_LIST)
+ eq(result, repeat([], 10))
+ })
+})
+
+
+describe('keys', function() {
+ it('returns an array of the given object\'s own keys', function() {
+ eq(keys(obj).sort(), ['a', 'b', 'c', 'd', 'e', 'f'])
+ })
+
+ it('works with hasOwnProperty override', function() {
+ eq(keys({
+ hasOwnProperty: false,
+ }), ['hasOwnProperty'])
+ })
+
+ it.skip('works for primitives', function() {
+ var result = map(function(val) {
+ return keys(val)
+ }, PRIMITIVES_LIST)
+ eq(result, repeat([], 10))
+ })
+
+ it('does not include the given object\'s prototype properties', function() {
+ eq(keys(cobj).sort(), ['a', 'b'])
+ })
+})
diff --git a/test/util/values.js b/test/util/values.js
new file mode 100644
index 0000000..27b95d5
--- /dev/null
+++ b/test/util/values.js
@@ -0,0 +1,111 @@
+const valuesIn = require('../../src/deps/util/valuesIn')
+const values = require('../../src/deps/util/values')
+const keys = require('../../src/deps/util/keys')
+const repeat = require('../../src/deps/fp/repeat')
+const map = require('../../src/deps/loop/fantasy/_map')
+// const indexOf = require('../../src/deps/fp/indexOf')
+
+const indexOf = (needle, haystack) => haystack.indexOf(needle)
+
+describe('valuesIn', function() {
+ var obj = {
+ a: 100,
+ b: [1, 2, 3],
+ c: {x: 200, y: 300},
+ d: 'D',
+ e: null,
+ f: undefined,
+ }
+ function C() {
+ this.a = 100
+ this.b = 200
+ }
+ C.prototype.x = function() {
+ return 'x'
+ }
+ C.prototype.y = 'y'
+ var cobj = new C()
+
+ it('returns an array of the given object\'s values', function() {
+ var vs = valuesIn(obj)
+ eq(vs.length, 6)
+ eq(indexOf(100, vs) >= 0, true)
+ eq(indexOf('D', vs) >= 0, true)
+ eq(indexOf(null, vs) >= 0, true)
+ eq(indexOf(undefined, vs) >= 0, true)
+ eq(indexOf(obj.b, vs) >= 0, true)
+ eq(indexOf(obj.c, vs) >= 0, true)
+ })
+
+ it('includes the given object\'s prototype properties', function() {
+ var vs = valuesIn(cobj)
+ eq(vs.length, 4)
+ eq(indexOf(100, vs) >= 0, true)
+ eq(indexOf(200, vs) >= 0, true)
+ eq(indexOf(cobj.x, vs) >= 0, true)
+ eq(indexOf('y', vs) >= 0, true)
+ })
+
+ it.skip('works for primitives', function() {
+ var result = map(
+ function(val) {
+ return valuesIn(val)
+ },
+ [null, undefined, 55, '', true, false, NaN, Infinity, , []]
+ )
+ eq(result, repeat([], 10))
+ })
+})
+
+describe('values', function() {
+ var obj = {
+ a: 100,
+ b: [1, 2, 3],
+ c: {x: 200, y: 300},
+ d: 'D',
+ e: null,
+ f: undefined,
+ }
+ function C() {
+ this.a = 100
+ this.b = 200
+ }
+ C.prototype.x = function() {
+ return 'x'
+ }
+ C.prototype.y = 'y'
+ var cobj = new C()
+
+ it('returns an array of the given object\'s values', function() {
+ var vs = values(obj).sort()
+ var ts = [[1, 2, 3], 100, 'D', {x: 200, y: 300}, null, undefined]
+ eq(vs.length, ts.length)
+ eq(vs[0], ts[0])
+ eq(vs[1], ts[1])
+ eq(vs[2], ts[2])
+ eq(vs[3], ts[3])
+ eq(vs[4], ts[4])
+ eq(vs[5], ts[5])
+
+ eq(
+ values({
+ hasOwnProperty: false,
+ }),
+ [false]
+ )
+ })
+
+ it('does not include the given object\'s prototype properties', function() {
+ eq(values(cobj), [100, 200])
+ })
+
+ it.skip('returns an empty object for primitives', function() {
+ var result = map(
+ function(val) {
+ return keys(val)
+ },
+ [null, undefined, 55, '', true, false, NaN, Infinity, , []]
+ )
+ eq(result, repeat([], 10))
+ })
+})
diff --git a/typings/FantasyLand.d.ts b/typings/FantasyLand.d.ts
new file mode 100644
index 0000000..4dc5e8c
--- /dev/null
+++ b/typings/FantasyLand.d.ts
@@ -0,0 +1,148 @@
+// Fantasyland export interfaces
+
+// TODO: incorporate generalized inheritance e.g.: ``; possibly needs [rank 2
+// polymorphism](https://github.com/Microsoft/TypeScript/issues/1213).
+
+import {Primitive} from './generic'
+
+export interface Setoid {
+ equals(b: Setoid): boolean;
+}
+
+export interface Semigroup {
+ concat(b: Semigroup): Semigroup;
+}
+
+export interface Monoid extends Semigroup {
+ /* static */ empty(): Monoid;
+}
+
+export interface Functor {
+ map(fn: (t: T) => U): Functor;
+}
+
+export interface Apply extends Functor {
+ apply(fn: Apply<(t: T) => U>): Apply;
+}
+
+export interface Applicative extends Apply {
+ /* static */ of(a: U): Applicative;
+}
+
+export interface Alt extends Functor {
+ alt(b: T): Alt;
+}
+
+export interface Plus extends Alt {
+ /* static */ zero(): Plus;
+}
+
+export interface Alternative extends Plus, Applicative {
+}
+
+/**
+ * Generate a function that accepts a number of arguments.
+ */
+export function nary (length: 0, fn: () => U): () => U
+export function nary (length: 1, fn: (arg: T) => U): (arg: T) => U
+export function nary (length: 2, fn: (arg1: T1, arg2: T2) => U): (arg1: T1, arg2: T2) => U
+export function nary