From 689f785d0ea03a299cd47932d0a7180a8b8fddd3 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Sat, 13 Jan 2018 14:58:52 +0200 Subject: [PATCH 01/13] Add observeMutations.md --- snippets/observeMutations.md | 23 +++++++++++++++++++++++ tag_database | 1 + 2 files changed, 24 insertions(+) create mode 100644 snippets/observeMutations.md diff --git a/snippets/observeMutations.md b/snippets/observeMutations.md new file mode 100644 index 000000000..d78e5cc39 --- /dev/null +++ b/snippets/observeMutations.md @@ -0,0 +1,23 @@ +### observeMutations + +Runs the provided callback for each mutation on the specified element. + +Use a [`MutationObserver`](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver) to observe mutations on the given element. +Use `Array.forEach()` to run the callback for each mutation that is observed. +Omit the third argument, `options`, to use the default [options](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver#MutationObserverInit) (all `true`). + +```js +const observeMutations = (element, callback, options) => new MutationObserver(mutations => mutations.forEach(m => callback(m))).observe(element, Object.assign( + { + childList: true, + attributes: true, + attributeOldValue: true, + characterData: true, + characterDataOldValue: true, + subtree: true + }, options)); +``` + +```js +observeMutations(document, console.log); // Logs all mutations that happen on the page +``` diff --git a/tag_database b/tag_database index e1d4aa6aa..040f5371a 100644 --- a/tag_database +++ b/tag_database @@ -119,6 +119,7 @@ negate:function nthElement:array objectFromPairs:object,array objectToPairs:object,array +observeMutations:browser,event,advanced off:browser,event on:browser,event once:function From 4d275eb57995d5e36c3af5d484cb8a27d14f2a0b Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Tue, 16 Jan 2018 15:57:40 +0200 Subject: [PATCH 02/13] Update observeMutations.md --- snippets/observeMutations.md | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/snippets/observeMutations.md b/snippets/observeMutations.md index d78e5cc39..7af06f90c 100644 --- a/snippets/observeMutations.md +++ b/snippets/observeMutations.md @@ -1,23 +1,27 @@ ### observeMutations -Runs the provided callback for each mutation on the specified element. +Returns a new MutationObserver and runs the provided callback for each mutation on the specified element. Use a [`MutationObserver`](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver) to observe mutations on the given element. Use `Array.forEach()` to run the callback for each mutation that is observed. Omit the third argument, `options`, to use the default [options](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver#MutationObserverInit) (all `true`). ```js -const observeMutations = (element, callback, options) => new MutationObserver(mutations => mutations.forEach(m => callback(m))).observe(element, Object.assign( - { +const observeMutations = (element, callback, options) => { + const observer = new MutationObserver(mutations => mutations.forEach(m => callback(m))); + observer.observe(element, Object.assign({ childList: true, attributes: true, attributeOldValue: true, characterData: true, characterDataOldValue: true, subtree: true - }, options)); + }, options)); + return observer; +} ``` ```js -observeMutations(document, console.log); // Logs all mutations that happen on the page +const obs = observeMutations(document, console.log); // Logs all mutations that happen on the page +obs.disconnect(); // Disconnects the observer and stops logging mutations on the page ``` From 5db858bddaf46f06e364bf078cb100481d883d87 Mon Sep 17 00:00:00 2001 From: 30secondsofcode <30secondsofcode@gmail.com> Date: Tue, 16 Jan 2018 14:03:01 +0000 Subject: [PATCH 03/13] Travis build: 1252 --- README.md | 43 ++++++++++++++++++++++++++++++++++++ docs/index.html | 22 +++++++++++++++++- snippets/observeMutations.md | 24 ++++++++++++-------- 3 files changed, 79 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 5eee0eacb..5135a2ee6 100644 --- a/README.md +++ b/README.md @@ -163,6 +163,7 @@ average(1, 2, 3); * [`hasClass`](#hasclass) * [`hide`](#hide) * [`httpsRedirect`](#httpsredirect) +* [`observeMutations`](#observemutations-) * [`off`](#off) * [`on`](#on) * [`onUserInputChange`](#onuserinputchange-) @@ -2228,6 +2229,48 @@ httpsRedirect(); // If you are on http://mydomain.com, you are redirected to htt
[⬆ Back to top](#table-of-contents) +### observeMutations ![advanced](/advanced.svg) + +Returns a new MutationObserver and runs the provided callback for each mutation on the specified element. + +Use a [`MutationObserver`](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver) to observe mutations on the given element. +Use `Array.forEach()` to run the callback for each mutation that is observed. +Omit the third argument, `options`, to use the default [options](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver#MutationObserverInit) (all `true`). + +```js +const observeMutations = (element, callback, options) => { + const observer = new MutationObserver(mutations => mutations.forEach(m => callback(m))); + observer.observe( + element, + Object.assign( + { + childList: true, + attributes: true, + attributeOldValue: true, + characterData: true, + characterDataOldValue: true, + subtree: true + }, + options + ) + ); + return observer; +}; +``` + +
+Examples + +```js +const obs = observeMutations(document, console.log); // Logs all mutations that happen on the page +obs.disconnect(); // Disconnects the observer and stops logging mutations on the page +``` + +
+ +
[⬆ Back to top](#table-of-contents) + + ### off Removes an event listener from an element. diff --git a/docs/index.html b/docs/index.html index 23b326733..205434aa1 100644 --- a/docs/index.html +++ b/docs/index.html @@ -50,7 +50,7 @@ scrollToTop(); } }, false); - }

logo 30 seconds of code Curated collection of useful JavaScript snippets that you can understand in 30 seconds or less.

 

Adapter

call

Given a key and a set of arguments, call them when given a context. Primarily useful in composition.

Use a closure to call a stored key with stored arguments.

const call = (key, ...args) => context => context[key](...args);
+      }

logo 30 seconds of code Curated collection of useful JavaScript snippets that you can understand in 30 seconds or less.

 

Adapter

call

Given a key and a set of arguments, call them when given a context. Primarily useful in composition.

Use a closure to call a stored key with stored arguments.

const call = (key, ...args) => context => context[key](...args);
 
Promise.resolve([1, 2, 3])
   .then(call('map', x => 2 * x))
   .then(console.log); //[ 2, 4, 6 ]
@@ -448,6 +448,26 @@ hub.offif (location.protocol !== 'https:') location.replace('https://' + location.href.split('//')[1]);
 };
 
httpsRedirect(); // If you are on http://mydomain.com, you are redirected to https://mydomain.com
+

observeMutationsadvanced

Returns a new MutationObserver and runs the provided callback for each mutation on the specified element.

Use a MutationObserver to observe mutations on the given element. Use Array.forEach() to run the callback for each mutation that is observed. Omit the third argument, options, to use the default options (all true).

const observeMutations = (element, callback, options) => {
+  const observer = new MutationObserver(mutations => mutations.forEach(m => callback(m)));
+  observer.observe(
+    element,
+    Object.assign(
+      {
+        childList: true,
+        attributes: true,
+        attributeOldValue: true,
+        characterData: true,
+        characterDataOldValue: true,
+        subtree: true
+      },
+      options
+    )
+  );
+  return observer;
+};
+
const obs = observeMutations(document, console.log); // Logs all mutations that happen on the page
+obs.disconnect(); // Disconnects the observer and stops logging mutations on the page
 

off

Removes an event listener from an element.

Use EventTarget.removeEventListener() to remove an event listener from an element. Omit the fourth argument opts to use false or specify it based on the options used when the event listener was added.

const off = (el, evt, fn, opts = false) => el.removeEventListener(evt, fn, opts);
 
const fn = () => console.log('!');
 document.body.addEventListener('click', fn);
diff --git a/snippets/observeMutations.md b/snippets/observeMutations.md
index 7af06f90c..9ccc56f43 100644
--- a/snippets/observeMutations.md
+++ b/snippets/observeMutations.md
@@ -9,16 +9,22 @@ Omit the third argument, `options`, to use the default [options](https://develop
 ```js
 const observeMutations = (element, callback, options) => {
   const observer = new MutationObserver(mutations => mutations.forEach(m => callback(m)));
-  observer.observe(element, Object.assign({
-    childList: true,
-    attributes: true,
-    attributeOldValue: true,
-    characterData: true,
-    characterDataOldValue: true,
-    subtree: true
-  }, options)); 
+  observer.observe(
+    element,
+    Object.assign(
+      {
+        childList: true,
+        attributes: true,
+        attributeOldValue: true,
+        characterData: true,
+        characterDataOldValue: true,
+        subtree: true
+      },
+      options
+    )
+  );
   return observer;
-}
+};
 ```
 
 ```js

From bf679849a867ca56bdfd0dc40c2bd8f7d3a0a806 Mon Sep 17 00:00:00 2001
From: Angelos Chalaris 
Date: Tue, 16 Jan 2018 16:08:18 +0200
Subject: [PATCH 04/13] Fixed archive builder

---
 scripts/build.js | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/scripts/build.js b/scripts/build.js
index 169103309..eadf1c07b 100644
--- a/scripts/build.js
+++ b/scripts/build.js
@@ -44,8 +44,8 @@ These snippets, while useful and interesting, didn\'t quite make it into the rep
 ## Table of Contents
 
 `
-    for(const snippet of Object.entries(snippets))
-      output += `* [\`${snippet[0]}\`](#${snippet[0].toLowerCase()})\n`;
+    for(const snippet of Object.entries(snippets).filter(s[0] !=== 'README.md'))
+      output += `* [\`${snippet[0].slice(0,-3)}\`](#${snippet[0].toLowerCase().slice(0,-3)})\n`;
     output += '\n---\n';
     for(const snippet of Object.entries(snippets)){
       let data = snippet[1];

From d130ca90479b6e96fb2b8484820a068f8eba476f Mon Sep 17 00:00:00 2001
From: Angelos Chalaris 
Date: Tue, 16 Jan 2018 16:13:13 +0200
Subject: [PATCH 05/13] Fixed builder

---
 scripts/build.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/scripts/build.js b/scripts/build.js
index eadf1c07b..83c16d0b3 100644
--- a/scripts/build.js
+++ b/scripts/build.js
@@ -44,7 +44,7 @@ These snippets, while useful and interesting, didn\'t quite make it into the rep
 ## Table of Contents
 
 `
-    for(const snippet of Object.entries(snippets).filter(s[0] !=== 'README.md'))
+    for(const snippet of Object.entries(snippets).filter(s[0] !== 'README.md'))
       output += `* [\`${snippet[0].slice(0,-3)}\`](#${snippet[0].toLowerCase().slice(0,-3)})\n`;
     output += '\n---\n';
     for(const snippet of Object.entries(snippets)){

From d11d20a129085b94c7ba1864275889f8f63d90be Mon Sep 17 00:00:00 2001
From: Angelos Chalaris 
Date: Tue, 16 Jan 2018 16:16:57 +0200
Subject: [PATCH 06/13] Fixed builder

---
 scripts/build.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/scripts/build.js b/scripts/build.js
index 83c16d0b3..c3fa534bd 100644
--- a/scripts/build.js
+++ b/scripts/build.js
@@ -44,7 +44,7 @@ These snippets, while useful and interesting, didn\'t quite make it into the rep
 ## Table of Contents
 
 `
-    for(const snippet of Object.entries(snippets).filter(s[0] !== 'README.md'))
+    for(const snippet of Object.entries(snippets).filter(s => s[0] !== 'README.md'))
       output += `* [\`${snippet[0].slice(0,-3)}\`](#${snippet[0].toLowerCase().slice(0,-3)})\n`;
     output += '\n---\n';
     for(const snippet of Object.entries(snippets)){

From e63c6bc840ff7af1bd25527831d3a74e4a623c0d Mon Sep 17 00:00:00 2001
From: 30secondsofcode <30secondsofcode@gmail.com>
Date: Tue, 16 Jan 2018 14:20:25 +0000
Subject: [PATCH 07/13] Travis build: 1259 [custom]

---
 dist/_30s.es5.js                              |  19 +-
 dist/_30s.es5.min.js                          |   2 +-
 dist/_30s.esm.js                              |  21 +-
 dist/_30s.js                                  |  21 +-
 dist/_30s.min.js                              |   2 +-
 snippets_archive/README.md                    | 514 ++++++++++++++++++
 test/observeMutations/observeMutations.js     |  18 +
 .../observeMutations/observeMutations.test.js |  13 +
 test/testlog                                  |  12 +-
 9 files changed, 613 insertions(+), 9 deletions(-)
 create mode 100644 test/observeMutations/observeMutations.js
 create mode 100644 test/observeMutations/observeMutations.test.js

diff --git a/dist/_30s.es5.js b/dist/_30s.es5.js
index 4a5cff1f9..f15107273 100644
--- a/dist/_30s.es5.js
+++ b/dist/_30s.es5.js
@@ -1023,6 +1023,23 @@ var objectToPairs = function objectToPairs(obj) {
   });
 };
 
+var observeMutations = function observeMutations(element, callback, options) {
+  var observer = new MutationObserver(function (mutations) {
+    return mutations.forEach(function (m) {
+      return callback(m);
+    });
+  });
+  observer.observe(element, Object.assign({
+    childList: true,
+    attributes: true,
+    attributeOldValue: true,
+    characterData: true,
+    characterDataOldValue: true,
+    subtree: true
+  }, options));
+  return observer;
+};
+
 var off = function off(el, evt, fn) {
   var opts = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
   return el.removeEventListener(evt, fn, opts);
@@ -1656,7 +1673,7 @@ var zipObject = function zipObject(props, values) {
   }, {});
 };
 
-var imports = { JSONToFile: JSONToFile, RGBToHex: RGBToHex, UUIDGeneratorBrowser: UUIDGeneratorBrowser, UUIDGeneratorNode: UUIDGeneratorNode, anagrams: anagrams, arrayToHtmlList: arrayToHtmlList, average: average, averageBy: averageBy, bottomVisible: bottomVisible, byteSize: byteSize, call: call, capitalize: capitalize, capitalizeEveryWord: capitalizeEveryWord, chainAsync: chainAsync, chunk: chunk, clampNumber: clampNumber, cleanObj: cleanObj, cloneRegExp: cloneRegExp, coalesce: coalesce, coalesceFactory: coalesceFactory, collectInto: collectInto, colorize: colorize, compact: compact, compose: compose, copyToClipboard: copyToClipboard, countBy: countBy, countOccurrences: countOccurrences, createElement: createElement, createEventHub: createEventHub, currentURL: currentURL, curry: curry, decapitalize: decapitalize, deepFlatten: deepFlatten, defer: defer, detectDeviceType: detectDeviceType, difference: difference, differenceWith: differenceWith, digitize: digitize, distance: distance, distinctValuesOfArray: distinctValuesOfArray, dropElements: dropElements, dropRight: dropRight, elementIsVisibleInViewport: elementIsVisibleInViewport, elo: elo, equals: equals, escapeHTML: escapeHTML, escapeRegExp: escapeRegExp, everyNth: everyNth, extendHex: extendHex, factorial: factorial, fibonacci: fibonacci, filterNonUnique: filterNonUnique, findLast: findLast, flatten: flatten, flip: flip, forEachRight: forEachRight, formatDuration: formatDuration, fromCamelCase: fromCamelCase, functionName: functionName, functions: functions, gcd: gcd, geometricProgression: geometricProgression, getDaysDiffBetweenDates: getDaysDiffBetweenDates, getScrollPosition: getScrollPosition, getStyle: getStyle, getType: getType, getURLParameters: getURLParameters, groupBy: groupBy, hammingDistance: hammingDistance, hasClass: hasClass, hasFlags: hasFlags, head: head, hexToRGB: hexToRGB, hide: hide, httpGet: httpGet, httpPost: httpPost, httpsRedirect: httpsRedirect, inRange: inRange, indexOfAll: indexOfAll, initial: initial, initialize2DArray: initialize2DArray, initializeArrayWithRange: initializeArrayWithRange, initializeArrayWithValues: initializeArrayWithValues, intersection: intersection, invertKeyValues: invertKeyValues, isAbsoluteURL: isAbsoluteURL, isArray: isArray, isArrayLike: isArrayLike, isBoolean: isBoolean, isDivisible: isDivisible, isEven: isEven, isFunction: isFunction, isLowerCase: isLowerCase, isNull: isNull, isNumber: isNumber, isObject: isObject, isPrime: isPrime, isPrimitive: isPrimitive, isPromiseLike: isPromiseLike, isSorted: isSorted, isString: isString, isSymbol: isSymbol, isTravisCI: isTravisCI, isUpperCase: isUpperCase, isValidJSON: isValidJSON, join: join, last: last, lcm: lcm, longestItem: longestItem, lowercaseKeys: lowercaseKeys, luhnCheck: luhnCheck, mapKeys: mapKeys, mapObject: mapObject, mapValues: mapValues, mask: mask, maxBy: maxBy, maxN: maxN, median: median, memoize: memoize, merge: merge, minBy: minBy, minN: minN, negate: negate, nthElement: nthElement, objectFromPairs: objectFromPairs, objectToPairs: objectToPairs, off: off, on: on, onUserInputChange: onUserInputChange, once: once, orderBy: orderBy, palindrome: palindrome, parseCookie: parseCookie, partition: partition, percentile: percentile, pick: pick, pipeFunctions: pipeFunctions, pluralize: pluralize, powerset: powerset, prettyBytes: prettyBytes, primes: primes, promisify: promisify, pull: pull, pullAtIndex: pullAtIndex, pullAtValue: pullAtValue, randomHexColorCode: randomHexColorCode, randomIntArrayInRange: randomIntArrayInRange, randomIntegerInRange: randomIntegerInRange, randomNumberInRange: randomNumberInRange, readFileLines: readFileLines, redirect: redirect, reducedFilter: reducedFilter, remove: remove, reverseString: reverseString, round: round, runAsync: runAsync, runPromisesInSeries: runPromisesInSeries, sample: sample, sampleSize: sampleSize, scrollToTop: scrollToTop, sdbm: sdbm, select: select, serializeCookie: serializeCookie, setStyle: setStyle, shallowClone: shallowClone, show: show, shuffle: shuffle, similarity: similarity, size: size, sleep: sleep, sortCharactersInString: sortCharactersInString, sortedIndex: sortedIndex, splitLines: splitLines, spreadOver: spreadOver, standardDeviation: standardDeviation, sum: sum, sumBy: sumBy, sumPower: sumPower, symmetricDifference: symmetricDifference, tail: tail, take: take, takeRight: takeRight, timeTaken: timeTaken, toCamelCase: toCamelCase, toDecimalMark: toDecimalMark, toKebabCase: toKebabCase, toOrdinalSuffix: toOrdinalSuffix, toSafeInteger: toSafeInteger, toSnakeCase: toSnakeCase, toggleClass: toggleClass, tomorrow: tomorrow, transform: transform, truncateString: truncateString, truthCheckCollection: truthCheckCollection, unescapeHTML: unescapeHTML, union: union, untildify: untildify, validateNumber: validateNumber, without: without, words: words, yesNo: yesNo, zip: zip, zipObject: zipObject };
+var imports = { JSONToFile: JSONToFile, RGBToHex: RGBToHex, UUIDGeneratorBrowser: UUIDGeneratorBrowser, UUIDGeneratorNode: UUIDGeneratorNode, anagrams: anagrams, arrayToHtmlList: arrayToHtmlList, average: average, averageBy: averageBy, bottomVisible: bottomVisible, byteSize: byteSize, call: call, capitalize: capitalize, capitalizeEveryWord: capitalizeEveryWord, chainAsync: chainAsync, chunk: chunk, clampNumber: clampNumber, cleanObj: cleanObj, cloneRegExp: cloneRegExp, coalesce: coalesce, coalesceFactory: coalesceFactory, collectInto: collectInto, colorize: colorize, compact: compact, compose: compose, copyToClipboard: copyToClipboard, countBy: countBy, countOccurrences: countOccurrences, createElement: createElement, createEventHub: createEventHub, currentURL: currentURL, curry: curry, decapitalize: decapitalize, deepFlatten: deepFlatten, defer: defer, detectDeviceType: detectDeviceType, difference: difference, differenceWith: differenceWith, digitize: digitize, distance: distance, distinctValuesOfArray: distinctValuesOfArray, dropElements: dropElements, dropRight: dropRight, elementIsVisibleInViewport: elementIsVisibleInViewport, elo: elo, equals: equals, escapeHTML: escapeHTML, escapeRegExp: escapeRegExp, everyNth: everyNth, extendHex: extendHex, factorial: factorial, fibonacci: fibonacci, filterNonUnique: filterNonUnique, findLast: findLast, flatten: flatten, flip: flip, forEachRight: forEachRight, formatDuration: formatDuration, fromCamelCase: fromCamelCase, functionName: functionName, functions: functions, gcd: gcd, geometricProgression: geometricProgression, getDaysDiffBetweenDates: getDaysDiffBetweenDates, getScrollPosition: getScrollPosition, getStyle: getStyle, getType: getType, getURLParameters: getURLParameters, groupBy: groupBy, hammingDistance: hammingDistance, hasClass: hasClass, hasFlags: hasFlags, head: head, hexToRGB: hexToRGB, hide: hide, httpGet: httpGet, httpPost: httpPost, httpsRedirect: httpsRedirect, inRange: inRange, indexOfAll: indexOfAll, initial: initial, initialize2DArray: initialize2DArray, initializeArrayWithRange: initializeArrayWithRange, initializeArrayWithValues: initializeArrayWithValues, intersection: intersection, invertKeyValues: invertKeyValues, isAbsoluteURL: isAbsoluteURL, isArray: isArray, isArrayLike: isArrayLike, isBoolean: isBoolean, isDivisible: isDivisible, isEven: isEven, isFunction: isFunction, isLowerCase: isLowerCase, isNull: isNull, isNumber: isNumber, isObject: isObject, isPrime: isPrime, isPrimitive: isPrimitive, isPromiseLike: isPromiseLike, isSorted: isSorted, isString: isString, isSymbol: isSymbol, isTravisCI: isTravisCI, isUpperCase: isUpperCase, isValidJSON: isValidJSON, join: join, last: last, lcm: lcm, longestItem: longestItem, lowercaseKeys: lowercaseKeys, luhnCheck: luhnCheck, mapKeys: mapKeys, mapObject: mapObject, mapValues: mapValues, mask: mask, maxBy: maxBy, maxN: maxN, median: median, memoize: memoize, merge: merge, minBy: minBy, minN: minN, negate: negate, nthElement: nthElement, objectFromPairs: objectFromPairs, objectToPairs: objectToPairs, observeMutations: observeMutations, off: off, on: on, onUserInputChange: onUserInputChange, once: once, orderBy: orderBy, palindrome: palindrome, parseCookie: parseCookie, partition: partition, percentile: percentile, pick: pick, pipeFunctions: pipeFunctions, pluralize: pluralize, powerset: powerset, prettyBytes: prettyBytes, primes: primes, promisify: promisify, pull: pull, pullAtIndex: pullAtIndex, pullAtValue: pullAtValue, randomHexColorCode: randomHexColorCode, randomIntArrayInRange: randomIntArrayInRange, randomIntegerInRange: randomIntegerInRange, randomNumberInRange: randomNumberInRange, readFileLines: readFileLines, redirect: redirect, reducedFilter: reducedFilter, remove: remove, reverseString: reverseString, round: round, runAsync: runAsync, runPromisesInSeries: runPromisesInSeries, sample: sample, sampleSize: sampleSize, scrollToTop: scrollToTop, sdbm: sdbm, select: select, serializeCookie: serializeCookie, setStyle: setStyle, shallowClone: shallowClone, show: show, shuffle: shuffle, similarity: similarity, size: size, sleep: sleep, sortCharactersInString: sortCharactersInString, sortedIndex: sortedIndex, splitLines: splitLines, spreadOver: spreadOver, standardDeviation: standardDeviation, sum: sum, sumBy: sumBy, sumPower: sumPower, symmetricDifference: symmetricDifference, tail: tail, take: take, takeRight: takeRight, timeTaken: timeTaken, toCamelCase: toCamelCase, toDecimalMark: toDecimalMark, toKebabCase: toKebabCase, toOrdinalSuffix: toOrdinalSuffix, toSafeInteger: toSafeInteger, toSnakeCase: toSnakeCase, toggleClass: toggleClass, tomorrow: tomorrow, transform: transform, truncateString: truncateString, truthCheckCollection: truthCheckCollection, unescapeHTML: unescapeHTML, union: union, untildify: untildify, validateNumber: validateNumber, without: without, words: words, yesNo: yesNo, zip: zip, zipObject: zipObject };
 
 return imports;
 
diff --git a/dist/_30s.es5.min.js b/dist/_30s.es5.min.js
index 0bbb1bc13..fbe29289a 100644
--- a/dist/_30s.es5.min.js
+++ b/dist/_30s.es5.min.js
@@ -1 +1 @@
-(function(a,b){'object'==typeof exports&&'undefined'!=typeof module?module.exports=b():'function'==typeof define&&define.amd?define(b):a._30s=b()})(this,function(){'use strict';function a(a){return Array.isArray(a)?a:Array.from(a)}function b(a){return Array.isArray(a)?a:Array.from(a)}function c(a){if(Array.isArray(a)){for(var b=0,c=Array(a.length);b>a/4).toString(16)})},UUIDGeneratorNode:function(){return'10000000-1000-4000-8000-100000000000'.replace(/[018]/g,function(a){return(a^F.randomBytes(1)[0]&15>>a/4).toString(16)})},anagrams:function a(b){return 2>=b.length?2===b.length?[b,b[1]+b[0]]:[b]:b.split('').reduce(function(c,d,e){return c.concat(a(b.slice(0,e)+b.slice(e+1)).map(function(a){return d+a}))},[])},arrayToHtmlList:function(a,b){return a.map(function(a){return document.querySelector('#'+b).innerHTML+='
  • '+a+'
  • '})},average:function(){for(var a=arguments.length,b=Array(a),c=0;c=(document.documentElement.scrollHeight||document.documentElement.clientHeight)},byteSize:function(a){return new Blob([a]).size},call:function(a){for(var b=arguments.length,c=Array(1'"]/g,function(a){return{"&":'&',"<":'<',">":'>',"'":''','"':'"'}[a]||a})},escapeRegExp:function(a){return a.replace(/[.*+?^${}()|[\]\\]/g,'\\$&')},everyNth:function(a,b){return a.filter(function(a,c){return c%b==b-1})},extendHex:function(a){return'#'+a.slice(a.startsWith('#')?1:0).split('').map(function(a){return a+a}).join('')},factorial:function a(b){return 0>b?function(){throw new TypeError('Negative numbers are not allowed!')}():1>=b?1:b*a(b-1)},fibonacci:function(a){return Array.from({length:a}).reduce(function(a,b,c){return a.concat(1a&&(a=-a);var b={day:z(a/8.64e7),hour:z(a/3.6e6)%24,minute:z(a/6e4)%60,second:z(a/1e3)%60,millisecond:z(a)%1e3};return Object.entries(b).filter(function(a){return 0!==a[1]}).map(function(a){return a[1]+' '+(1===a[1]?a[0]:a[0]+'s')}).join(', ')},fromCamelCase:function(a){var b=1>>(b?24:16))+', '+((c&(b?16711680:65280))>>>(b?16:8))+', '+((c&(b?65280:255))>>>(b?8:0))+(b?', '+(255&c):'')+')'},hide:function(){for(var a=arguments.length,b=Array(a),c=0;cc&&(c=b),null==c?0<=a&&a=b&&aa[1]?-1:1,d=!0,e=!1;try{for(var f,g=a.entries()[Symbol.iterator]();!(d=(f=g.next()).done);d=!0){var h=f.value,j=K(h,2),k=j[0],i=j[1];if(k===a.length-1)return c;if(0<(i-a[k+1])*c)return 0}}catch(a){e=!0,b=a}finally{try{!d&&g.return&&g.return()}finally{if(e)throw b}}},isString:function(a){return'string'==typeof a},isSymbol:function(a){return'symbol'===('undefined'==typeof a?'undefined':L(a))},isTravisCI:function(){return'TRAVIS'in process.env&&'CI'in process.env},isUpperCase:function(a){return a===a.toUpperCase()},isValidJSON:function(a){try{return JSON.parse(a),!0}catch(a){return!1}},join:function(a){var b=1e-c&&(b='mouse',a(b),document.removeEventListener('mousemove',d)),c=e};document.addEventListener('touchstart',function(){'touch'==b||(b='touch',a(b),document.addEventListener('mousemove',d))})},once:function(a){var b=!1;return function(){if(!b){b=!0;for(var c=arguments.length,d=Array(c),e=0;ej?1:iMath.abs(a))return a+(c?' ':'')+d[0];var e=B(z(Math.log10(0>a?-a:a)/3),d.length-1),f=+((0>a?-a:a)/A(1e3,e)).toPrecision(b);return(0>a?'-':'')+f+(c?' ':'')+d[e]},primes:function(a){var b=Array.from({length:a-1}).map(function(a,b){return b+2}),c=z(y(a)),d=Array.from({length:c-1}).map(function(a,b){return b+2});return d.forEach(function(a){return b=b.filter(function(b){return 0!=b%a||b==a})}),b},promisify:function(a){return function(){for(var b=arguments.length,c=Array(b),d=0;da[a.length-1],d=a.findIndex(function(a){return c?b>=a:b<=a});return-1===d?a.length:d},splitLines:function(a){return a.split(/\r?\n/)},spreadOver:function(a){return function(b){return a.apply(void 0,t(b))}},standardDeviation:function(a){var b=1b?a.slice(0,3',"'":'\'',""":'"'}[a]||a})},union:function(c,a){return Array.from(new Set([].concat(v(c),v(a))))},untildify:function(a){return a.replace(/^~($|\/|\\)/,('undefined'!=typeof require&&require('os').homedir())+'$1')},validateNumber:function(a){return!isNaN(parseFloat(a))&&isFinite(a)&&+a==a},without:function(a){for(var b=arguments.length,c=Array(1>a/4).toString(16)})},UUIDGeneratorNode:function(){return'10000000-1000-4000-8000-100000000000'.replace(/[018]/g,function(a){return(a^F.randomBytes(1)[0]&15>>a/4).toString(16)})},anagrams:function a(b){return 2>=b.length?2===b.length?[b,b[1]+b[0]]:[b]:b.split('').reduce(function(c,d,e){return c.concat(a(b.slice(0,e)+b.slice(e+1)).map(function(a){return d+a}))},[])},arrayToHtmlList:function(a,b){return a.map(function(a){return document.querySelector('#'+b).innerHTML+='
  • '+a+'
  • '})},average:function(){for(var a=arguments.length,b=Array(a),c=0;c=(document.documentElement.scrollHeight||document.documentElement.clientHeight)},byteSize:function(a){return new Blob([a]).size},call:function(a){for(var b=arguments.length,c=Array(1'"]/g,function(a){return{"&":'&',"<":'<',">":'>',"'":''','"':'"'}[a]||a})},escapeRegExp:function(a){return a.replace(/[.*+?^${}()|[\]\\]/g,'\\$&')},everyNth:function(a,b){return a.filter(function(a,c){return c%b==b-1})},extendHex:function(a){return'#'+a.slice(a.startsWith('#')?1:0).split('').map(function(a){return a+a}).join('')},factorial:function a(b){return 0>b?function(){throw new TypeError('Negative numbers are not allowed!')}():1>=b?1:b*a(b-1)},fibonacci:function(a){return Array.from({length:a}).reduce(function(a,b,c){return a.concat(1a&&(a=-a);var b={day:z(a/8.64e7),hour:z(a/3.6e6)%24,minute:z(a/6e4)%60,second:z(a/1e3)%60,millisecond:z(a)%1e3};return Object.entries(b).filter(function(a){return 0!==a[1]}).map(function(a){return a[1]+' '+(1===a[1]?a[0]:a[0]+'s')}).join(', ')},fromCamelCase:function(a){var b=1>>(b?24:16))+', '+((c&(b?16711680:65280))>>>(b?16:8))+', '+((c&(b?65280:255))>>>(b?8:0))+(b?', '+(255&c):'')+')'},hide:function(){for(var a=arguments.length,b=Array(a),c=0;cc&&(c=b),null==c?0<=a&&a=b&&aa[1]?-1:1,d=!0,e=!1;try{for(var f,g=a.entries()[Symbol.iterator]();!(d=(f=g.next()).done);d=!0){var h=f.value,j=K(h,2),k=j[0],i=j[1];if(k===a.length-1)return c;if(0<(i-a[k+1])*c)return 0}}catch(a){e=!0,b=a}finally{try{!d&&g.return&&g.return()}finally{if(e)throw b}}},isString:function(a){return'string'==typeof a},isSymbol:function(a){return'symbol'===('undefined'==typeof a?'undefined':L(a))},isTravisCI:function(){return'TRAVIS'in process.env&&'CI'in process.env},isUpperCase:function(a){return a===a.toUpperCase()},isValidJSON:function(a){try{return JSON.parse(a),!0}catch(a){return!1}},join:function(a){var b=1e-c&&(b='mouse',a(b),document.removeEventListener('mousemove',d)),c=e};document.addEventListener('touchstart',function(){'touch'==b||(b='touch',a(b),document.addEventListener('mousemove',d))})},once:function(a){var b=!1;return function(){if(!b){b=!0;for(var c=arguments.length,d=Array(c),e=0;ej?1:iMath.abs(a))return a+(c?' ':'')+d[0];var e=B(z(Math.log10(0>a?-a:a)/3),d.length-1),f=+((0>a?-a:a)/A(1e3,e)).toPrecision(b);return(0>a?'-':'')+f+(c?' ':'')+d[e]},primes:function(a){var b=Array.from({length:a-1}).map(function(a,b){return b+2}),c=z(y(a)),d=Array.from({length:c-1}).map(function(a,b){return b+2});return d.forEach(function(a){return b=b.filter(function(b){return 0!=b%a||b==a})}),b},promisify:function(a){return function(){for(var b=arguments.length,c=Array(b),d=0;da[a.length-1],d=a.findIndex(function(a){return c?b>=a:b<=a});return-1===d?a.length:d},splitLines:function(a){return a.split(/\r?\n/)},spreadOver:function(a){return function(b){return a.apply(void 0,t(b))}},standardDeviation:function(a){var b=1b?a.slice(0,3',"'":'\'',""":'"'}[a]||a})},union:function(c,a){return Array.from(new Set([].concat(v(c),v(a))))},untildify:function(a){return a.replace(/^~($|\/|\\)/,('undefined'!=typeof require&&require('os').homedir())+'$1')},validateNumber:function(a){return!isNaN(parseFloat(a))&&isFinite(a)&&+a==a},without:function(a){for(var b=arguments.length,c=Array(1 arr.reduce((a, v) => (a[v[0]] = v[1], a), {}); const objectToPairs = obj => Object.keys(obj).map(k => [k, obj[k]]); +const observeMutations = (element, callback, options) => { + const observer = new MutationObserver(mutations => mutations.forEach(m => callback(m))); + observer.observe( + element, + Object.assign( + { + childList: true, + attributes: true, + attributeOldValue: true, + characterData: true, + characterDataOldValue: true, + subtree: true + }, + options + ) + ); + return observer; +}; + const off = (el, evt, fn, opts = false) => el.removeEventListener(evt, fn, opts); const on = (el, evt, fn, opts = {}) => { @@ -982,6 +1001,6 @@ const zip = (...arrays) => { const zipObject = (props, values) => props.reduce((obj, prop, index) => (obj[prop] = values[index], obj), {}); -var imports = {JSONToFile,RGBToHex,UUIDGeneratorBrowser,UUIDGeneratorNode,anagrams,arrayToHtmlList,average,averageBy,bottomVisible,byteSize,call,capitalize,capitalizeEveryWord,chainAsync,chunk,clampNumber,cleanObj,cloneRegExp,coalesce,coalesceFactory,collectInto,colorize,compact,compose,copyToClipboard,countBy,countOccurrences,createElement,createEventHub,currentURL,curry,decapitalize,deepFlatten,defer,detectDeviceType,difference,differenceWith,digitize,distance,distinctValuesOfArray,dropElements,dropRight,elementIsVisibleInViewport,elo,equals,escapeHTML,escapeRegExp,everyNth,extendHex,factorial,fibonacci,filterNonUnique,findLast,flatten,flip,forEachRight,formatDuration,fromCamelCase,functionName,functions,gcd,geometricProgression,getDaysDiffBetweenDates,getScrollPosition,getStyle,getType,getURLParameters,groupBy,hammingDistance,hasClass,hasFlags,head,hexToRGB,hide,httpGet,httpPost,httpsRedirect,inRange,indexOfAll,initial,initialize2DArray,initializeArrayWithRange,initializeArrayWithValues,intersection,invertKeyValues,isAbsoluteURL,isArray,isArrayLike,isBoolean,isDivisible,isEven,isFunction,isLowerCase,isNull,isNumber,isObject,isPrime,isPrimitive,isPromiseLike,isSorted,isString,isSymbol,isTravisCI,isUpperCase,isValidJSON,join,last,lcm,longestItem,lowercaseKeys,luhnCheck,mapKeys,mapObject,mapValues,mask,maxBy,maxN,median,memoize,merge,minBy,minN,negate,nthElement,objectFromPairs,objectToPairs,off,on,onUserInputChange,once,orderBy,palindrome,parseCookie,partition,percentile,pick,pipeFunctions,pluralize,powerset,prettyBytes,primes,promisify,pull,pullAtIndex,pullAtValue,randomHexColorCode,randomIntArrayInRange,randomIntegerInRange,randomNumberInRange,readFileLines,redirect,reducedFilter,remove,reverseString,round,runAsync,runPromisesInSeries,sample,sampleSize,scrollToTop,sdbm,select,serializeCookie,setStyle,shallowClone,show,shuffle,similarity,size,sleep,sortCharactersInString,sortedIndex,splitLines,spreadOver,standardDeviation,sum,sumBy,sumPower,symmetricDifference,tail,take,takeRight,timeTaken,toCamelCase,toDecimalMark,toKebabCase,toOrdinalSuffix,toSafeInteger,toSnakeCase,toggleClass,tomorrow,transform,truncateString,truthCheckCollection,unescapeHTML,union,untildify,validateNumber,without,words,yesNo,zip,zipObject,} +var imports = {JSONToFile,RGBToHex,UUIDGeneratorBrowser,UUIDGeneratorNode,anagrams,arrayToHtmlList,average,averageBy,bottomVisible,byteSize,call,capitalize,capitalizeEveryWord,chainAsync,chunk,clampNumber,cleanObj,cloneRegExp,coalesce,coalesceFactory,collectInto,colorize,compact,compose,copyToClipboard,countBy,countOccurrences,createElement,createEventHub,currentURL,curry,decapitalize,deepFlatten,defer,detectDeviceType,difference,differenceWith,digitize,distance,distinctValuesOfArray,dropElements,dropRight,elementIsVisibleInViewport,elo,equals,escapeHTML,escapeRegExp,everyNth,extendHex,factorial,fibonacci,filterNonUnique,findLast,flatten,flip,forEachRight,formatDuration,fromCamelCase,functionName,functions,gcd,geometricProgression,getDaysDiffBetweenDates,getScrollPosition,getStyle,getType,getURLParameters,groupBy,hammingDistance,hasClass,hasFlags,head,hexToRGB,hide,httpGet,httpPost,httpsRedirect,inRange,indexOfAll,initial,initialize2DArray,initializeArrayWithRange,initializeArrayWithValues,intersection,invertKeyValues,isAbsoluteURL,isArray,isArrayLike,isBoolean,isDivisible,isEven,isFunction,isLowerCase,isNull,isNumber,isObject,isPrime,isPrimitive,isPromiseLike,isSorted,isString,isSymbol,isTravisCI,isUpperCase,isValidJSON,join,last,lcm,longestItem,lowercaseKeys,luhnCheck,mapKeys,mapObject,mapValues,mask,maxBy,maxN,median,memoize,merge,minBy,minN,negate,nthElement,objectFromPairs,objectToPairs,observeMutations,off,on,onUserInputChange,once,orderBy,palindrome,parseCookie,partition,percentile,pick,pipeFunctions,pluralize,powerset,prettyBytes,primes,promisify,pull,pullAtIndex,pullAtValue,randomHexColorCode,randomIntArrayInRange,randomIntegerInRange,randomNumberInRange,readFileLines,redirect,reducedFilter,remove,reverseString,round,runAsync,runPromisesInSeries,sample,sampleSize,scrollToTop,sdbm,select,serializeCookie,setStyle,shallowClone,show,shuffle,similarity,size,sleep,sortCharactersInString,sortedIndex,splitLines,spreadOver,standardDeviation,sum,sumBy,sumPower,symmetricDifference,tail,take,takeRight,timeTaken,toCamelCase,toDecimalMark,toKebabCase,toOrdinalSuffix,toSafeInteger,toSnakeCase,toggleClass,tomorrow,transform,truncateString,truthCheckCollection,unescapeHTML,union,untildify,validateNumber,without,words,yesNo,zip,zipObject,} export default imports; diff --git a/dist/_30s.js b/dist/_30s.js index 90a6c5836..182c248d3 100644 --- a/dist/_30s.js +++ b/dist/_30s.js @@ -595,6 +595,25 @@ const objectFromPairs = arr => arr.reduce((a, v) => (a[v[0]] = v[1], a), {}); const objectToPairs = obj => Object.keys(obj).map(k => [k, obj[k]]); +const observeMutations = (element, callback, options) => { + const observer = new MutationObserver(mutations => mutations.forEach(m => callback(m))); + observer.observe( + element, + Object.assign( + { + childList: true, + attributes: true, + attributeOldValue: true, + characterData: true, + characterDataOldValue: true, + subtree: true + }, + options + ) + ); + return observer; +}; + const off = (el, evt, fn, opts = false) => el.removeEventListener(evt, fn, opts); const on = (el, evt, fn, opts = {}) => { @@ -988,7 +1007,7 @@ const zip = (...arrays) => { const zipObject = (props, values) => props.reduce((obj, prop, index) => (obj[prop] = values[index], obj), {}); -var imports = {JSONToFile,RGBToHex,UUIDGeneratorBrowser,UUIDGeneratorNode,anagrams,arrayToHtmlList,average,averageBy,bottomVisible,byteSize,call,capitalize,capitalizeEveryWord,chainAsync,chunk,clampNumber,cleanObj,cloneRegExp,coalesce,coalesceFactory,collectInto,colorize,compact,compose,copyToClipboard,countBy,countOccurrences,createElement,createEventHub,currentURL,curry,decapitalize,deepFlatten,defer,detectDeviceType,difference,differenceWith,digitize,distance,distinctValuesOfArray,dropElements,dropRight,elementIsVisibleInViewport,elo,equals,escapeHTML,escapeRegExp,everyNth,extendHex,factorial,fibonacci,filterNonUnique,findLast,flatten,flip,forEachRight,formatDuration,fromCamelCase,functionName,functions,gcd,geometricProgression,getDaysDiffBetweenDates,getScrollPosition,getStyle,getType,getURLParameters,groupBy,hammingDistance,hasClass,hasFlags,head,hexToRGB,hide,httpGet,httpPost,httpsRedirect,inRange,indexOfAll,initial,initialize2DArray,initializeArrayWithRange,initializeArrayWithValues,intersection,invertKeyValues,isAbsoluteURL,isArray,isArrayLike,isBoolean,isDivisible,isEven,isFunction,isLowerCase,isNull,isNumber,isObject,isPrime,isPrimitive,isPromiseLike,isSorted,isString,isSymbol,isTravisCI,isUpperCase,isValidJSON,join,last,lcm,longestItem,lowercaseKeys,luhnCheck,mapKeys,mapObject,mapValues,mask,maxBy,maxN,median,memoize,merge,minBy,minN,negate,nthElement,objectFromPairs,objectToPairs,off,on,onUserInputChange,once,orderBy,palindrome,parseCookie,partition,percentile,pick,pipeFunctions,pluralize,powerset,prettyBytes,primes,promisify,pull,pullAtIndex,pullAtValue,randomHexColorCode,randomIntArrayInRange,randomIntegerInRange,randomNumberInRange,readFileLines,redirect,reducedFilter,remove,reverseString,round,runAsync,runPromisesInSeries,sample,sampleSize,scrollToTop,sdbm,select,serializeCookie,setStyle,shallowClone,show,shuffle,similarity,size,sleep,sortCharactersInString,sortedIndex,splitLines,spreadOver,standardDeviation,sum,sumBy,sumPower,symmetricDifference,tail,take,takeRight,timeTaken,toCamelCase,toDecimalMark,toKebabCase,toOrdinalSuffix,toSafeInteger,toSnakeCase,toggleClass,tomorrow,transform,truncateString,truthCheckCollection,unescapeHTML,union,untildify,validateNumber,without,words,yesNo,zip,zipObject,} +var imports = {JSONToFile,RGBToHex,UUIDGeneratorBrowser,UUIDGeneratorNode,anagrams,arrayToHtmlList,average,averageBy,bottomVisible,byteSize,call,capitalize,capitalizeEveryWord,chainAsync,chunk,clampNumber,cleanObj,cloneRegExp,coalesce,coalesceFactory,collectInto,colorize,compact,compose,copyToClipboard,countBy,countOccurrences,createElement,createEventHub,currentURL,curry,decapitalize,deepFlatten,defer,detectDeviceType,difference,differenceWith,digitize,distance,distinctValuesOfArray,dropElements,dropRight,elementIsVisibleInViewport,elo,equals,escapeHTML,escapeRegExp,everyNth,extendHex,factorial,fibonacci,filterNonUnique,findLast,flatten,flip,forEachRight,formatDuration,fromCamelCase,functionName,functions,gcd,geometricProgression,getDaysDiffBetweenDates,getScrollPosition,getStyle,getType,getURLParameters,groupBy,hammingDistance,hasClass,hasFlags,head,hexToRGB,hide,httpGet,httpPost,httpsRedirect,inRange,indexOfAll,initial,initialize2DArray,initializeArrayWithRange,initializeArrayWithValues,intersection,invertKeyValues,isAbsoluteURL,isArray,isArrayLike,isBoolean,isDivisible,isEven,isFunction,isLowerCase,isNull,isNumber,isObject,isPrime,isPrimitive,isPromiseLike,isSorted,isString,isSymbol,isTravisCI,isUpperCase,isValidJSON,join,last,lcm,longestItem,lowercaseKeys,luhnCheck,mapKeys,mapObject,mapValues,mask,maxBy,maxN,median,memoize,merge,minBy,minN,negate,nthElement,objectFromPairs,objectToPairs,observeMutations,off,on,onUserInputChange,once,orderBy,palindrome,parseCookie,partition,percentile,pick,pipeFunctions,pluralize,powerset,prettyBytes,primes,promisify,pull,pullAtIndex,pullAtValue,randomHexColorCode,randomIntArrayInRange,randomIntegerInRange,randomNumberInRange,readFileLines,redirect,reducedFilter,remove,reverseString,round,runAsync,runPromisesInSeries,sample,sampleSize,scrollToTop,sdbm,select,serializeCookie,setStyle,shallowClone,show,shuffle,similarity,size,sleep,sortCharactersInString,sortedIndex,splitLines,spreadOver,standardDeviation,sum,sumBy,sumPower,symmetricDifference,tail,take,takeRight,timeTaken,toCamelCase,toDecimalMark,toKebabCase,toOrdinalSuffix,toSafeInteger,toSnakeCase,toggleClass,tomorrow,transform,truncateString,truthCheckCollection,unescapeHTML,union,untildify,validateNumber,without,words,yesNo,zip,zipObject,} return imports; diff --git a/dist/_30s.min.js b/dist/_30s.min.js index 60cd437e3..4a9a366ef 100644 --- a/dist/_30s.min.js +++ b/dist/_30s.min.js @@ -1 +1 @@ -(function(a,b){'object'==typeof exports&&'undefined'!=typeof module?module.exports=b():'function'==typeof define&&define.amd?define(b):a._30s=b()})(this,function(){'use strict';var a=Math.round,b=Math.sqrt,c=Math.log,d=Math.floor,e=Math.min,f=Math.max,g=Math.ceil;const h='undefined'!=typeof require&&require('fs'),i='undefined'!=typeof require&&require('crypto'),j=(a)=>2>=a.length?2===a.length?[a,a[1]+a[0]]:[a]:a.split('').reduce((b,c,d)=>b.concat(j(a.slice(0,d)+a.slice(d+1)).map((a)=>c+a)),[]),k=(a,b=[],c)=>(Object.keys(a).forEach((d)=>{d===c?k(a[d],b,c):!b.includes(d)&&delete a[d]}),a),l=(a,b=a.length,...c)=>b<=c.length?a(...c):l.bind(null,a,b,...c),m=(a)=>[].concat(...a.map((a)=>Array.isArray(a)?m(a):a)),n=([...c],d=32,e)=>{const[f,a]=c,b=(a,b)=>1/(1+10**((b-a)/400)),g=(c,g)=>(e||c)+d*(g-b(g?f:a,g?a:f));if(2===c.length)return[g(f,1),g(a,0)];for(let a,b=0;b{if(c===d)return!0;if(c instanceof Date&&d instanceof Date)return c.getTime()===d.getTime();if(!c||!d||'object'!=typeof c&&'object'!=typeof d)return c===d;if(null===c||void 0===c||null===d||void 0===d)return!1;if(c.prototype!==d.prototype)return!1;let e=Object.keys(c);return!(e.length!==Object.keys(d).length)&&e.every((a)=>o(c[a],d[a]))},p=(a)=>0>a?(()=>{throw new TypeError('Negative numbers are not allowed!')})():1>=a?1:a*p(a-1),q=(a,b=1)=>1==b?a.reduce((b,a)=>b.concat(a),[]):a.reduce((c,a)=>c.concat(Array.isArray(a)?q(a,b-1):a),[]),r=(...a)=>{const c=(a,b)=>b?r(b,a%b):a;return[...a].reduce((d,a)=>c(d,a))},s='undefined'!=typeof require&&require('fs'),t=()=>{const a=document.documentElement.scrollTop||document.body.scrollTop;0h.writeFile(`${b}.json`,JSON.stringify(a,null,2)),RGBToHex:(a,c,d)=>((a<<16)+(c<<8)+d).toString(16).padStart(6,'0'),UUIDGeneratorBrowser:()=>'10000000-1000-4000-8000-100000000000'.replace(/[018]/g,(a)=>(a^crypto.getRandomValues(new Uint8Array(1))[0]&15>>a/4).toString(16)),UUIDGeneratorNode:()=>'10000000-1000-4000-8000-100000000000'.replace(/[018]/g,(a)=>(a^i.randomBytes(1)[0]&15>>a/4).toString(16)),anagrams:j,arrayToHtmlList:(a,b)=>a.map((a)=>document.querySelector('#'+b).innerHTML+=`
  • ${a}
  • `),average:(...a)=>[...a].reduce((a,b)=>a+b,0)/a.length,averageBy:(a,b)=>a.map('function'==typeof b?b:(a)=>a[b]).reduce((a,b)=>a+b,0)/a.length,bottomVisible:()=>document.documentElement.clientHeight+window.scrollY>=(document.documentElement.scrollHeight||document.documentElement.clientHeight),byteSize:(a)=>new Blob([a]).size,call:(a,...b)=>(c)=>c[a](...b),capitalize:([a,...b],c=!1)=>a.toUpperCase()+(c?b.join('').toLowerCase():b.join('')),capitalizeEveryWord:(a)=>a.replace(/\b[a-z]/g,(a)=>a.toUpperCase()),chainAsync:(a)=>{let b=0;const c=()=>a[b++](c);c()},chunk:(a,b)=>Array.from({length:g(a.length/b)},(c,d)=>a.slice(d*b,d*b+b)),clampNumber:(c,d,a)=>f(e(c,f(d,a)),e(d,a)),cleanObj:k,cloneRegExp:(a)=>new RegExp(a.source,a.flags),coalesce:(...a)=>a.find((a)=>![void 0,null].includes(a)),coalesceFactory:(a)=>(...b)=>b.find(a),collectInto:(a)=>(...b)=>a(b),colorize:(...a)=>({black:`\x1b[30m${a.join(' ')}`,red:`\x1b[31m${a.join(' ')}`,green:`\x1b[32m${a.join(' ')}`,yellow:`\x1b[33m${a.join(' ')}`,blue:`\x1b[34m${a.join(' ')}`,magenta:`\x1b[35m${a.join(' ')}`,cyan:`\x1b[36m${a.join(' ')}`,white:`\x1b[37m${a.join(' ')}`,bgBlack:`\x1b[40m${a.join(' ')}\x1b[0m`,bgRed:`\x1b[41m${a.join(' ')}\x1b[0m`,bgGreen:`\x1b[42m${a.join(' ')}\x1b[0m`,bgYellow:`\x1b[43m${a.join(' ')}\x1b[0m`,bgBlue:`\x1b[44m${a.join(' ')}\x1b[0m`,bgMagenta:`\x1b[45m${a.join(' ')}\x1b[0m`,bgCyan:`\x1b[46m${a.join(' ')}\x1b[0m`,bgWhite:`\x1b[47m${a.join(' ')}\x1b[0m`}),compact:(a)=>a.filter(Boolean),compose:(...a)=>a.reduce((a,b)=>(...c)=>a(b(...c))),copyToClipboard:(a)=>{const b=document.createElement('textarea');b.value=a,b.setAttribute('readonly',''),b.style.position='absolute',b.style.left='-9999px',document.body.appendChild(b);const c=!!(0a.map('function'==typeof b?b:(a)=>a[b]).reduce((a,b)=>(a[b]=(a[b]||0)+1,a),{}),countOccurrences:(a,b)=>a.reduce((c,a)=>a===b?c+1:c+0,0),createElement:(a)=>{const b=document.createElement('div');return b.innerHTML=a,b.firstElementChild},createEventHub:()=>({hub:Object.create(null),emit(a,b){(this.hub[a]||[]).forEach((a)=>a(b))},on(a,b){this.hub[a]||(this.hub[a]=[]),this.hub[a].push(b)},off(a,b){const c=(this.hub[a]||[]).findIndex((a)=>a===b);-1window.location.href,curry:l,decapitalize:([a,...b],c=!1)=>a.toLowerCase()+(c?b.join('').toUpperCase():b.join('')),deepFlatten:m,defer:(a,...b)=>setTimeout(a,1,...b),detectDeviceType:()=>/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)?'Mobile':'Desktop',difference:(c,a)=>{const b=new Set(a);return c.filter((a)=>!b.has(a))},differenceWith:(a,b,c)=>a.filter((d)=>-1===b.findIndex((a)=>c(d,a))),digitize:(a)=>[...`${a}`].map((a)=>parseInt(a)),distance:(a,b,c,d)=>Math.hypot(c-a,d-b),distinctValuesOfArray:(a)=>[...new Set(a)],dropElements:(a,b)=>{for(;0a.slice(0,-b),elementIsVisibleInViewport:(a,b=!1)=>{const{top:c,left:d,bottom:e,right:f}=a.getBoundingClientRect(),{innerHeight:g,innerWidth:h}=window;return b?(0a.replace(/[&<>'"]/g,(a)=>({"&":'&',"<":'<',">":'>',"'":''','"':'"'})[a]||a),escapeRegExp:(a)=>a.replace(/[.*+?^${}()|[\]\\]/g,'\\$&'),everyNth:(a,b)=>a.filter((a,c)=>c%b==b-1),extendHex:(a)=>'#'+a.slice(a.startsWith('#')?1:0).split('').map((a)=>a+a).join(''),factorial:p,fibonacci:(a)=>Array.from({length:a}).reduce((a,b,c)=>a.concat(1a.filter((b)=>a.indexOf(b)===a.lastIndexOf(b)),findLast:(a,b)=>a.filter(b).slice(-1),flatten:q,flip:(a)=>(...b)=>a(b.pop(),...b),forEachRight:(a,b)=>a.slice(0).reverse().forEach(b),formatDuration:(a)=>{0>a&&(a=-a);const b={day:d(a/8.64e7),hour:d(a/3.6e6)%24,minute:d(a/6e4)%60,second:d(a/1e3)%60,millisecond:d(a)%1e3};return Object.entries(b).filter((a)=>0!==a[1]).map((a)=>a[1]+' '+(1===a[1]?a[0]:a[0]+'s')).join(', ')},fromCamelCase:(a,b='_')=>a.replace(/([a-z\d])([A-Z])/g,'$1'+b+'$2').replace(/([A-Z]+)([A-Z][a-z\d]+)/g,'$1'+b+'$2').toLowerCase(),functionName:(a)=>(console.debug(a.name),a),functions:(a,b=!1)=>(b?[...Object.keys(a),...Object.keys(Object.getPrototypeOf(a))]:Object.keys(a)).filter((b)=>'function'==typeof a[b]),gcd:r,geometricProgression:(a,b=1,e=2)=>Array.from({length:d(c(a/b)/c(e))+1}).map((a,c)=>b*e**c),getDaysDiffBetweenDates:(a,b)=>(b-a)/86400000,getScrollPosition:(a=window)=>({x:a.pageXOffset===void 0?a.scrollLeft:a.pageXOffset,y:a.pageYOffset===void 0?a.scrollTop:a.pageYOffset}),getStyle:(a,b)=>getComputedStyle(a)[b],getType:(a)=>a===void 0?'undefined':null===a?'null':a.constructor.name.toLowerCase(),getURLParameters:(a)=>a.match(/([^?=&]+)(=([^&]*))/g).reduce((b,a)=>(b[a.slice(0,a.indexOf('='))]=a.slice(a.indexOf('=')+1),b),{}),groupBy:(a,b)=>a.map('function'==typeof b?b:(a)=>a[b]).reduce((b,c,d)=>(b[c]=(b[c]||[]).concat(a[d]),b),{}),hammingDistance:(a,b)=>((a^b).toString(2).match(/1/g)||'').length,hasClass:(a,b)=>a.classList.contains(b),hasFlags:(...a)=>a.every((a)=>process.argv.includes(/^-{1,2}/.test(a)?a:'--'+a)),head:(a)=>a[0],hexToRGB:(a)=>{let b=!1,c=a.slice(a.startsWith('#')?1:0);return 3===c.length?c=[...c].map((a)=>a+a).join(''):8===c.length&&(b=!0),c=parseInt(c,16),'rgb'+(b?'a':'')+'('+(c>>>(b?24:16))+', '+((c&(b?16711680:65280))>>>(b?16:8))+', '+((c&(b?65280:255))>>>(b?8:0))+(b?`, ${255&c}`:'')+')'},hide:(...a)=>[...a].forEach((a)=>a.style.display='none'),httpGet:(a,b,c=console.error)=>{const d=new XMLHttpRequest;d.open('GET',a,!0),d.onload=()=>b(d.responseText),d.onerror=()=>c(d),d.send()},httpPost:(a,b,c=null,d=console.error)=>{const e=new XMLHttpRequest;e.open('POST',a,!0),e.setRequestHeader('Content-type','application/json; charset=utf-8'),e.onload=()=>b(e.responseText),e.onerror=()=>d(e),e.send(c)},httpsRedirect:()=>{'https:'!==location.protocol&&location.replace('https://'+location.href.split('//')[1])},inRange:(a,b,c=null)=>(c&&b>c&&(c=b),null==c?0<=a&&a=b&&a{const c=[];return a.forEach((a,d)=>a===b&&c.push(d)),c},initial:(a)=>a.slice(0,-1),initialize2DArray:(a,b,c=null)=>Array.from({length:b}).map(()=>Array.from({length:a}).fill(c)),initializeArrayWithRange:(a,b=0,c=1)=>Array.from({length:g((a+1-b)/c)}).map((a,d)=>d*c+b),initializeArrayWithValues:(a,b=0)=>Array(a).fill(b),intersection:(c,a)=>{const b=new Set(a);return c.filter((a)=>b.has(a))},invertKeyValues:(a)=>Object.keys(a).reduce((b,c)=>(b[a[c]]=c,b),{}),isAbsoluteURL:(a)=>/^[a-z][a-z0-9+.-]*:/.test(a),isArray:(a)=>Array.isArray(a),isArrayLike:(a)=>{try{return[...a],!0}catch(a){return!1}},isBoolean:(a)=>'boolean'==typeof a,isDivisible:(a,b)=>0==a%b,isEven:(a)=>0==a%2,isFunction:(a)=>'function'==typeof a,isLowerCase:(a)=>a===a.toLowerCase(),isNull:(a)=>null===a,isNumber:(a)=>'number'==typeof a,isObject:(a)=>a===Object(a),isPrime:(a)=>{const c=d(b(a));for(var e=2;e<=c;e++)if(0==a%e)return!1;return 2<=a},isPrimitive:(a)=>!['object','function'].includes(typeof a)||null===a,isPromiseLike:(a)=>null!==a&&('object'==typeof a||'function'==typeof a)&&'function'==typeof a.then,isSorted:(a)=>{const b=a[0]>a[1]?-1:1;for(let[c,d]of a.entries()){if(c===a.length-1)return b;if(0<(d-a[c+1])*b)return 0}},isString:(a)=>'string'==typeof a,isSymbol:(a)=>'symbol'==typeof a,isTravisCI:()=>'TRAVIS'in process.env&&'CI'in process.env,isUpperCase:(a)=>a===a.toUpperCase(),isValidJSON:(a)=>{try{return JSON.parse(a),!0}catch(a){return!1}},join:(a,b=',',c=b)=>a.reduce((d,e,f)=>f==a.length-2?d+e+c:f==a.length-1?d+e:d+e+b,''),last:(a)=>a[a.length-1],lcm:(...a)=>{const b=(a,c)=>c?b(c,a%c):a,c=(a,c)=>a*c/b(a,c);return[...a].reduce((d,a)=>c(d,a))},longestItem:(...a)=>[...a].sort((c,a)=>a.length-c.length)[0],lowercaseKeys:(a)=>Object.keys(a).reduce((b,c)=>(b[c.toLowerCase()]=a[c],b),{}),luhnCheck:(a)=>{let b=(a+'').split('').reverse().map((a)=>parseInt(a)),c=b.splice(0,1)[0],d=b.reduce((a,b,c)=>0==c%2?a+2*b%9||9:a+b,0);return d+=c,0==d%10},mapKeys:(a,b)=>Object.keys(a).reduce((c,d)=>(c[b(a[d],d,a)]=a[d],c),{}),mapObject:(b,c)=>((d)=>(d=[b,b.map(c)],d[0].reduce((a,b,c)=>(a[b]=d[1][c],a),{})))(),mapValues:(a,b)=>Object.keys(a).reduce((c,d)=>(c[d]=b(a[d],d,a),c),{}),mask:(a,b=4,c='*')=>(''+a).slice(0,-b).replace(/./g,c)+(''+a).slice(-b),maxBy:(a,b)=>f(...a.map('function'==typeof b?b:(a)=>a[b])),maxN:(a,b=1)=>[...a].sort((c,a)=>a-c).slice(0,b),median:(a)=>{const b=d(a.length/2),c=[...a].sort((c,a)=>c-a);return 0==a.length%2?(c[b-1]+c[b])/2:c[b]},memoize:(a)=>{const b=new Map,c=function(c){return b.has(c)?b.get(c):b.set(c,a.call(this,c))&&b.get(c)};return c.cache=b,c},merge:(...a)=>[...a].reduce((b,c)=>Object.keys(c).reduce((d,a)=>(b[a]=b.hasOwnProperty(a)?[].concat(b[a]).concat(c[a]):c[a],b),{}),{}),minBy:(a,b)=>e(...a.map('function'==typeof b?b:(a)=>a[b])),minN:(a,b=1)=>[...a].sort((c,a)=>c-a).slice(0,b),negate:(a)=>(...b)=>!a(...b),nthElement:(a,b=0)=>(0a.reduce((b,a)=>(b[a[0]]=a[1],b),{}),objectToPairs:(a)=>Object.keys(a).map((b)=>[b,a[b]]),off:(a,b,c,d=!1)=>a.removeEventListener(b,c,d),on:(a,b,c,d={})=>{const e=(a)=>a.target.matches(d.target)&&c.call(a.target,a);if(a.addEventListener(b,d.target?e:c,d.options||!1),d.target)return e},onUserInputChange:(a)=>{let b='mouse',c=0;const d=()=>{const e=performance.now();20>e-c&&(b='mouse',a(b),document.removeEventListener('mousemove',d)),c=e};document.addEventListener('touchstart',()=>{'touch'==b||(b='touch',a(b),document.addEventListener('mousemove',d))})},once:(a)=>{let b=!1;return function(...c){if(!b)return b=!0,a.apply(this,c)}},orderBy:(a,c,d)=>[...a].sort((e,a)=>c.reduce((b,c,f)=>{if(0===b){const[g,h]=d&&'desc'===d[f]?[a[c],e[c]]:[e[c],a[c]];b=g>h?1:g{const b=a.toLowerCase().replace(/[\W_]/g,'');return b===b.split('').reverse().join('')},parseCookie:(a)=>a.split(';').map((a)=>a.split('=')).reduce((a,b)=>(a[decodeURIComponent(b[0].trim())]=decodeURIComponent(b[1].trim()),a),{}),partition:(a,b)=>a.reduce((a,c,d,e)=>(a[b(c,d,e)?0:1].push(c),a),[[],[]]),percentile:(a,b)=>100*a.reduce((a,c)=>a+(cb.reduce((b,c)=>(c in a&&(b[c]=a[c]),b),{}),pipeFunctions:(...a)=>a.reduce((a,b)=>(...c)=>b(a(...c))),pluralize:(a,b,c=b+'s')=>{const d=(a,b,c=b+'s')=>[1,-1].includes(+a)?b:c;return'object'==typeof a?(b,c)=>d(b,c,a[c]):d(a,b,c)},powerset:(a)=>a.reduce((b,a)=>b.concat(b.map((b)=>[a].concat(b))),[[]]),prettyBytes:(a,b=3,c=!0)=>{const f=['B','KB','MB','GB','TB','PB','EB','ZB','YB'];if(1>Math.abs(a))return a+(c?' ':'')+f[0];const g=e(d(Math.log10(0>a?-a:a)/3),f.length-1),h=+((0>a?-a:a)/1e3**g).toPrecision(b);return(0>a?'-':'')+h+(c?' ':'')+f[g]},primes:(a)=>{let c=Array.from({length:a-1}).map((a,b)=>b+2),e=d(b(a)),f=Array.from({length:e-1}).map((a,b)=>b+2);return f.forEach((a)=>c=c.filter((b)=>0!=b%a||b==a)),c},promisify:(a)=>(...b)=>new Promise((c,d)=>a(...b,(a,b)=>a?d(a):c(b))),pull:(a,...b)=>{let c=Array.isArray(b[0])?b[0]:b,d=a.filter((a)=>!c.includes(a));a.length=0,d.forEach((b)=>a.push(b))},pullAtIndex:(a,b)=>{let c=[],d=a.map((a,d)=>b.includes(d)?c.push(a):a).filter((a,c)=>!b.includes(c));return a.length=0,d.forEach((b)=>a.push(b)),c},pullAtValue:(a,b)=>{let c=[],d=a.forEach((a)=>b.includes(a)?c.push(a):a),e=a.filter((a)=>!b.includes(a));return a.length=0,e.forEach((b)=>a.push(b)),c},randomHexColorCode:()=>{let a=(0|1048575*Math.random()).toString(16);return'#'+(6===a.length?a:(0|15*Math.random()).toString(16)+a)},randomIntArrayInRange:(a,b,c=1)=>Array.from({length:c},()=>d(Math.random()*(b-a+1))+a),randomIntegerInRange:(a,b)=>d(Math.random()*(b-a+1))+a,randomNumberInRange:(a,b)=>Math.random()*(b-a)+a,readFileLines:(a)=>s.readFileSync(a).toString('UTF8').split('\n'),redirect:(a,b=!0)=>b?window.location.href=a:window.location.replace(a),reducedFilter:(a,b,c)=>a.filter(c).map((a)=>b.reduce((b,c)=>(b[c]=a[c],b),{})),remove:(a,b)=>Array.isArray(a)?a.filter(b).reduce((b,c)=>(a.splice(a.indexOf(c),1),b.concat(c)),[]):[],reverseString:(a)=>[...a].join(''),round:(b,c=0)=>+`${a(`${b}e${c}`)}e-${c}`,runAsync:(a)=>{const b=`var fn = ${a.toString()}; postMessage(fn());`,c=new Worker(URL.createObjectURL(new Blob([b]),{type:'application/javascript; charset=utf-8'}));return new Promise((a,b)=>{c.onmessage=({data:b})=>{a(b),c.terminate()},c.onerror=(a)=>{b(a),c.terminate()}})},runPromisesInSeries:(a)=>a.reduce((a,b)=>a.then(b),Promise.resolve()),sample:(a)=>a[d(Math.random()*a.length)],sampleSize:([...a],b=1)=>{for(let c=a.length;c;){const b=d(Math.random()*c--);[a[c],a[b]]=[a[b],a[c]]}return a.slice(0,b)},scrollToTop:t,sdbm:(a)=>{let b=a.split('');return b.reduce((a,b)=>a=b.charCodeAt(0)+(a<<6)+(a<<16)-a,0)},select:(a,...b)=>[...b].map((b)=>b.split('.').reduce((a,b)=>a&&a[b],a)),serializeCookie:(a,b)=>`${encodeURIComponent(a)}=${encodeURIComponent(b)}`,setStyle:(a,b,c)=>a.style[b]=c,shallowClone:(a)=>Object.assign({},a),show:(...a)=>[...a].forEach((a)=>a.style.display=''),shuffle:([...a])=>{for(let b=a.length;b;){const c=d(Math.random()*b--);[a[b],a[c]]=[a[c],a[b]]}return a},similarity:(a,b)=>a.filter((a)=>b.includes(a)),size:(a)=>Array.isArray(a)?a.length:a&&'object'==typeof a?a.size||a.length||Object.keys(a).length:'string'==typeof a?new Blob([a]).size:0,sleep:(a)=>new Promise((b)=>setTimeout(b,a)),sortCharactersInString:(a)=>[...a].sort((c,a)=>c.localeCompare(a)).join(''),sortedIndex:(a,b)=>{const c=a[0]>a[a.length-1],d=a.findIndex((a)=>c?b>=a:b<=a);return-1===d?a.length:d},splitLines:(a)=>a.split(/\r?\n/),spreadOver:(a)=>(b)=>a(...b),standardDeviation:(a,c=!1)=>{const d=a.reduce((a,b)=>a+b,0)/a.length;return b(a.reduce((a,b)=>a.concat((b-d)**2),[]).reduce((a,b)=>a+b,0)/(a.length-(c?0:1)))},sum:(...a)=>[...a].reduce((a,b)=>a+b,0),sumBy:(a,b)=>a.map('function'==typeof b?b:(a)=>a[b]).reduce((a,b)=>a+b,0),sumPower:(a,b=2,c=1)=>Array(a+1-c).fill(0).map((a,d)=>(d+c)**b).reduce((c,a)=>c+a,0),symmetricDifference:(c,a)=>{const b=new Set(c),d=new Set(a);return[...c.filter((a)=>!d.has(a)),...a.filter((a)=>!b.has(a))]},tail:(a)=>1a.slice(0,b),takeRight:(a,b=1)=>a.slice(a.length-b,a.length),timeTaken:(a)=>{console.time('timeTaken');const b=a();return console.timeEnd('timeTaken'),b},toCamelCase:(a)=>{let b=a&&a.match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g).map((a)=>a.slice(0,1).toUpperCase()+a.slice(1).toLowerCase()).join('');return b.slice(0,1).toLowerCase()+b.slice(1)},toDecimalMark:(a)=>a.toLocaleString('en-US'),toKebabCase:(a)=>a&&a.match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g).map((a)=>a.toLowerCase()).join('-'),toOrdinalSuffix:(a)=>{const b=parseInt(a),c=[b%10,b%100],d=['st','nd','rd','th'];return[1,2,3,4].includes(c[0])&&![11,12,13,14,15,16,17,18,19].includes(c[1])?b+d[c[0]-1]:b+d[3]},toSafeInteger:(b)=>a(f(e(b,Number.MAX_SAFE_INTEGER),Number.MIN_SAFE_INTEGER)),toSnakeCase:(a)=>a&&a.match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g).map((a)=>a.toLowerCase()).join('_'),toggleClass:(a,b)=>a.classList.toggle(b),tomorrow:()=>new Date(new Date().getTime()+8.64e7).toISOString().split('T')[0],transform:(b,c,a)=>Object.keys(b).reduce((d,a)=>c(d,b[a],a,b),a),truncateString:(a,b)=>a.length>b?a.slice(0,3a.every((a)=>a[b]),unescapeHTML:(a)=>a.replace(/&|<|>|'|"/g,(a)=>({"&":'&',"<":'<',">":'>',"'":'\'',""":'"'})[a]||a),union:(c,a)=>Array.from(new Set([...c,...a])),untildify:(a)=>a.replace(/^~($|\/|\\)/,`${'undefined'!=typeof require&&require('os').homedir()}$1`),validateNumber:(a)=>!isNaN(parseFloat(a))&&isFinite(a)&&+a==a,without:(a,...b)=>a.filter((a)=>!b.includes(a)),words:(a,b=/[^a-zA-Z-]+/)=>a.split(b).filter(Boolean),yesNo:(a,b=!1)=>!!/^(y|yes)$/i.test(a)||!/^(n|no)$/i.test(a)&&b,zip:(...a)=>{const b=f(...a.map((a)=>a.length));return Array.from({length:b}).map((b,c)=>Array.from({length:a.length},(b,d)=>a[d][c]))},zipObject:(a,b)=>a.reduce((a,c,d)=>(a[c]=b[d],a),{})}}); +(function(a,b){'object'==typeof exports&&'undefined'!=typeof module?module.exports=b():'function'==typeof define&&define.amd?define(b):a._30s=b()})(this,function(){'use strict';var a=Math.round,b=Math.sqrt,c=Math.log,d=Math.floor,e=Math.min,f=Math.max,g=Math.ceil;const h='undefined'!=typeof require&&require('fs'),i='undefined'!=typeof require&&require('crypto'),j=(a)=>2>=a.length?2===a.length?[a,a[1]+a[0]]:[a]:a.split('').reduce((b,c,d)=>b.concat(j(a.slice(0,d)+a.slice(d+1)).map((a)=>c+a)),[]),k=(a,b=[],c)=>(Object.keys(a).forEach((d)=>{d===c?k(a[d],b,c):!b.includes(d)&&delete a[d]}),a),l=(a,b=a.length,...c)=>b<=c.length?a(...c):l.bind(null,a,b,...c),m=(a)=>[].concat(...a.map((a)=>Array.isArray(a)?m(a):a)),n=([...c],d=32,e)=>{const[f,a]=c,b=(a,b)=>1/(1+10**((b-a)/400)),g=(c,g)=>(e||c)+d*(g-b(g?f:a,g?a:f));if(2===c.length)return[g(f,1),g(a,0)];for(let a,b=0;b{if(c===d)return!0;if(c instanceof Date&&d instanceof Date)return c.getTime()===d.getTime();if(!c||!d||'object'!=typeof c&&'object'!=typeof d)return c===d;if(null===c||void 0===c||null===d||void 0===d)return!1;if(c.prototype!==d.prototype)return!1;let e=Object.keys(c);return!(e.length!==Object.keys(d).length)&&e.every((a)=>o(c[a],d[a]))},p=(a)=>0>a?(()=>{throw new TypeError('Negative numbers are not allowed!')})():1>=a?1:a*p(a-1),q=(a,b=1)=>1==b?a.reduce((b,a)=>b.concat(a),[]):a.reduce((c,a)=>c.concat(Array.isArray(a)?q(a,b-1):a),[]),r=(...a)=>{const c=(a,b)=>b?r(b,a%b):a;return[...a].reduce((d,a)=>c(d,a))},s='undefined'!=typeof require&&require('fs'),t=()=>{const a=document.documentElement.scrollTop||document.body.scrollTop;0h.writeFile(`${b}.json`,JSON.stringify(a,null,2)),RGBToHex:(a,c,d)=>((a<<16)+(c<<8)+d).toString(16).padStart(6,'0'),UUIDGeneratorBrowser:()=>'10000000-1000-4000-8000-100000000000'.replace(/[018]/g,(a)=>(a^crypto.getRandomValues(new Uint8Array(1))[0]&15>>a/4).toString(16)),UUIDGeneratorNode:()=>'10000000-1000-4000-8000-100000000000'.replace(/[018]/g,(a)=>(a^i.randomBytes(1)[0]&15>>a/4).toString(16)),anagrams:j,arrayToHtmlList:(a,b)=>a.map((a)=>document.querySelector('#'+b).innerHTML+=`
  • ${a}
  • `),average:(...a)=>[...a].reduce((a,b)=>a+b,0)/a.length,averageBy:(a,b)=>a.map('function'==typeof b?b:(a)=>a[b]).reduce((a,b)=>a+b,0)/a.length,bottomVisible:()=>document.documentElement.clientHeight+window.scrollY>=(document.documentElement.scrollHeight||document.documentElement.clientHeight),byteSize:(a)=>new Blob([a]).size,call:(a,...b)=>(c)=>c[a](...b),capitalize:([a,...b],c=!1)=>a.toUpperCase()+(c?b.join('').toLowerCase():b.join('')),capitalizeEveryWord:(a)=>a.replace(/\b[a-z]/g,(a)=>a.toUpperCase()),chainAsync:(a)=>{let b=0;const c=()=>a[b++](c);c()},chunk:(a,b)=>Array.from({length:g(a.length/b)},(c,d)=>a.slice(d*b,d*b+b)),clampNumber:(c,d,a)=>f(e(c,f(d,a)),e(d,a)),cleanObj:k,cloneRegExp:(a)=>new RegExp(a.source,a.flags),coalesce:(...a)=>a.find((a)=>![void 0,null].includes(a)),coalesceFactory:(a)=>(...b)=>b.find(a),collectInto:(a)=>(...b)=>a(b),colorize:(...a)=>({black:`\x1b[30m${a.join(' ')}`,red:`\x1b[31m${a.join(' ')}`,green:`\x1b[32m${a.join(' ')}`,yellow:`\x1b[33m${a.join(' ')}`,blue:`\x1b[34m${a.join(' ')}`,magenta:`\x1b[35m${a.join(' ')}`,cyan:`\x1b[36m${a.join(' ')}`,white:`\x1b[37m${a.join(' ')}`,bgBlack:`\x1b[40m${a.join(' ')}\x1b[0m`,bgRed:`\x1b[41m${a.join(' ')}\x1b[0m`,bgGreen:`\x1b[42m${a.join(' ')}\x1b[0m`,bgYellow:`\x1b[43m${a.join(' ')}\x1b[0m`,bgBlue:`\x1b[44m${a.join(' ')}\x1b[0m`,bgMagenta:`\x1b[45m${a.join(' ')}\x1b[0m`,bgCyan:`\x1b[46m${a.join(' ')}\x1b[0m`,bgWhite:`\x1b[47m${a.join(' ')}\x1b[0m`}),compact:(a)=>a.filter(Boolean),compose:(...a)=>a.reduce((a,b)=>(...c)=>a(b(...c))),copyToClipboard:(a)=>{const b=document.createElement('textarea');b.value=a,b.setAttribute('readonly',''),b.style.position='absolute',b.style.left='-9999px',document.body.appendChild(b);const c=!!(0a.map('function'==typeof b?b:(a)=>a[b]).reduce((a,b)=>(a[b]=(a[b]||0)+1,a),{}),countOccurrences:(a,b)=>a.reduce((c,a)=>a===b?c+1:c+0,0),createElement:(a)=>{const b=document.createElement('div');return b.innerHTML=a,b.firstElementChild},createEventHub:()=>({hub:Object.create(null),emit(a,b){(this.hub[a]||[]).forEach((a)=>a(b))},on(a,b){this.hub[a]||(this.hub[a]=[]),this.hub[a].push(b)},off(a,b){const c=(this.hub[a]||[]).findIndex((a)=>a===b);-1window.location.href,curry:l,decapitalize:([a,...b],c=!1)=>a.toLowerCase()+(c?b.join('').toUpperCase():b.join('')),deepFlatten:m,defer:(a,...b)=>setTimeout(a,1,...b),detectDeviceType:()=>/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)?'Mobile':'Desktop',difference:(c,a)=>{const b=new Set(a);return c.filter((a)=>!b.has(a))},differenceWith:(a,b,c)=>a.filter((d)=>-1===b.findIndex((a)=>c(d,a))),digitize:(a)=>[...`${a}`].map((a)=>parseInt(a)),distance:(a,b,c,d)=>Math.hypot(c-a,d-b),distinctValuesOfArray:(a)=>[...new Set(a)],dropElements:(a,b)=>{for(;0a.slice(0,-b),elementIsVisibleInViewport:(a,b=!1)=>{const{top:c,left:d,bottom:e,right:f}=a.getBoundingClientRect(),{innerHeight:g,innerWidth:h}=window;return b?(0a.replace(/[&<>'"]/g,(a)=>({"&":'&',"<":'<',">":'>',"'":''','"':'"'})[a]||a),escapeRegExp:(a)=>a.replace(/[.*+?^${}()|[\]\\]/g,'\\$&'),everyNth:(a,b)=>a.filter((a,c)=>c%b==b-1),extendHex:(a)=>'#'+a.slice(a.startsWith('#')?1:0).split('').map((a)=>a+a).join(''),factorial:p,fibonacci:(a)=>Array.from({length:a}).reduce((a,b,c)=>a.concat(1a.filter((b)=>a.indexOf(b)===a.lastIndexOf(b)),findLast:(a,b)=>a.filter(b).slice(-1),flatten:q,flip:(a)=>(...b)=>a(b.pop(),...b),forEachRight:(a,b)=>a.slice(0).reverse().forEach(b),formatDuration:(a)=>{0>a&&(a=-a);const b={day:d(a/8.64e7),hour:d(a/3.6e6)%24,minute:d(a/6e4)%60,second:d(a/1e3)%60,millisecond:d(a)%1e3};return Object.entries(b).filter((a)=>0!==a[1]).map((a)=>a[1]+' '+(1===a[1]?a[0]:a[0]+'s')).join(', ')},fromCamelCase:(a,b='_')=>a.replace(/([a-z\d])([A-Z])/g,'$1'+b+'$2').replace(/([A-Z]+)([A-Z][a-z\d]+)/g,'$1'+b+'$2').toLowerCase(),functionName:(a)=>(console.debug(a.name),a),functions:(a,b=!1)=>(b?[...Object.keys(a),...Object.keys(Object.getPrototypeOf(a))]:Object.keys(a)).filter((b)=>'function'==typeof a[b]),gcd:r,geometricProgression:(a,b=1,e=2)=>Array.from({length:d(c(a/b)/c(e))+1}).map((a,c)=>b*e**c),getDaysDiffBetweenDates:(a,b)=>(b-a)/86400000,getScrollPosition:(a=window)=>({x:a.pageXOffset===void 0?a.scrollLeft:a.pageXOffset,y:a.pageYOffset===void 0?a.scrollTop:a.pageYOffset}),getStyle:(a,b)=>getComputedStyle(a)[b],getType:(a)=>a===void 0?'undefined':null===a?'null':a.constructor.name.toLowerCase(),getURLParameters:(a)=>a.match(/([^?=&]+)(=([^&]*))/g).reduce((b,a)=>(b[a.slice(0,a.indexOf('='))]=a.slice(a.indexOf('=')+1),b),{}),groupBy:(a,b)=>a.map('function'==typeof b?b:(a)=>a[b]).reduce((b,c,d)=>(b[c]=(b[c]||[]).concat(a[d]),b),{}),hammingDistance:(a,b)=>((a^b).toString(2).match(/1/g)||'').length,hasClass:(a,b)=>a.classList.contains(b),hasFlags:(...a)=>a.every((a)=>process.argv.includes(/^-{1,2}/.test(a)?a:'--'+a)),head:(a)=>a[0],hexToRGB:(a)=>{let b=!1,c=a.slice(a.startsWith('#')?1:0);return 3===c.length?c=[...c].map((a)=>a+a).join(''):8===c.length&&(b=!0),c=parseInt(c,16),'rgb'+(b?'a':'')+'('+(c>>>(b?24:16))+', '+((c&(b?16711680:65280))>>>(b?16:8))+', '+((c&(b?65280:255))>>>(b?8:0))+(b?`, ${255&c}`:'')+')'},hide:(...a)=>[...a].forEach((a)=>a.style.display='none'),httpGet:(a,b,c=console.error)=>{const d=new XMLHttpRequest;d.open('GET',a,!0),d.onload=()=>b(d.responseText),d.onerror=()=>c(d),d.send()},httpPost:(a,b,c=null,d=console.error)=>{const e=new XMLHttpRequest;e.open('POST',a,!0),e.setRequestHeader('Content-type','application/json; charset=utf-8'),e.onload=()=>b(e.responseText),e.onerror=()=>d(e),e.send(c)},httpsRedirect:()=>{'https:'!==location.protocol&&location.replace('https://'+location.href.split('//')[1])},inRange:(a,b,c=null)=>(c&&b>c&&(c=b),null==c?0<=a&&a=b&&a{const c=[];return a.forEach((a,d)=>a===b&&c.push(d)),c},initial:(a)=>a.slice(0,-1),initialize2DArray:(a,b,c=null)=>Array.from({length:b}).map(()=>Array.from({length:a}).fill(c)),initializeArrayWithRange:(a,b=0,c=1)=>Array.from({length:g((a+1-b)/c)}).map((a,d)=>d*c+b),initializeArrayWithValues:(a,b=0)=>Array(a).fill(b),intersection:(c,a)=>{const b=new Set(a);return c.filter((a)=>b.has(a))},invertKeyValues:(a)=>Object.keys(a).reduce((b,c)=>(b[a[c]]=c,b),{}),isAbsoluteURL:(a)=>/^[a-z][a-z0-9+.-]*:/.test(a),isArray:(a)=>Array.isArray(a),isArrayLike:(a)=>{try{return[...a],!0}catch(a){return!1}},isBoolean:(a)=>'boolean'==typeof a,isDivisible:(a,b)=>0==a%b,isEven:(a)=>0==a%2,isFunction:(a)=>'function'==typeof a,isLowerCase:(a)=>a===a.toLowerCase(),isNull:(a)=>null===a,isNumber:(a)=>'number'==typeof a,isObject:(a)=>a===Object(a),isPrime:(a)=>{const c=d(b(a));for(var e=2;e<=c;e++)if(0==a%e)return!1;return 2<=a},isPrimitive:(a)=>!['object','function'].includes(typeof a)||null===a,isPromiseLike:(a)=>null!==a&&('object'==typeof a||'function'==typeof a)&&'function'==typeof a.then,isSorted:(a)=>{const b=a[0]>a[1]?-1:1;for(let[c,d]of a.entries()){if(c===a.length-1)return b;if(0<(d-a[c+1])*b)return 0}},isString:(a)=>'string'==typeof a,isSymbol:(a)=>'symbol'==typeof a,isTravisCI:()=>'TRAVIS'in process.env&&'CI'in process.env,isUpperCase:(a)=>a===a.toUpperCase(),isValidJSON:(a)=>{try{return JSON.parse(a),!0}catch(a){return!1}},join:(a,b=',',c=b)=>a.reduce((d,e,f)=>f==a.length-2?d+e+c:f==a.length-1?d+e:d+e+b,''),last:(a)=>a[a.length-1],lcm:(...a)=>{const b=(a,c)=>c?b(c,a%c):a,c=(a,c)=>a*c/b(a,c);return[...a].reduce((d,a)=>c(d,a))},longestItem:(...a)=>[...a].sort((c,a)=>a.length-c.length)[0],lowercaseKeys:(a)=>Object.keys(a).reduce((b,c)=>(b[c.toLowerCase()]=a[c],b),{}),luhnCheck:(a)=>{let b=(a+'').split('').reverse().map((a)=>parseInt(a)),c=b.splice(0,1)[0],d=b.reduce((a,b,c)=>0==c%2?a+2*b%9||9:a+b,0);return d+=c,0==d%10},mapKeys:(a,b)=>Object.keys(a).reduce((c,d)=>(c[b(a[d],d,a)]=a[d],c),{}),mapObject:(b,c)=>((d)=>(d=[b,b.map(c)],d[0].reduce((a,b,c)=>(a[b]=d[1][c],a),{})))(),mapValues:(a,b)=>Object.keys(a).reduce((c,d)=>(c[d]=b(a[d],d,a),c),{}),mask:(a,b=4,c='*')=>(''+a).slice(0,-b).replace(/./g,c)+(''+a).slice(-b),maxBy:(a,b)=>f(...a.map('function'==typeof b?b:(a)=>a[b])),maxN:(a,b=1)=>[...a].sort((c,a)=>a-c).slice(0,b),median:(a)=>{const b=d(a.length/2),c=[...a].sort((c,a)=>c-a);return 0==a.length%2?(c[b-1]+c[b])/2:c[b]},memoize:(a)=>{const b=new Map,c=function(c){return b.has(c)?b.get(c):b.set(c,a.call(this,c))&&b.get(c)};return c.cache=b,c},merge:(...a)=>[...a].reduce((b,c)=>Object.keys(c).reduce((d,a)=>(b[a]=b.hasOwnProperty(a)?[].concat(b[a]).concat(c[a]):c[a],b),{}),{}),minBy:(a,b)=>e(...a.map('function'==typeof b?b:(a)=>a[b])),minN:(a,b=1)=>[...a].sort((c,a)=>c-a).slice(0,b),negate:(a)=>(...b)=>!a(...b),nthElement:(a,b=0)=>(0a.reduce((b,a)=>(b[a[0]]=a[1],b),{}),objectToPairs:(a)=>Object.keys(a).map((b)=>[b,a[b]]),observeMutations:(a,b,c)=>{const d=new MutationObserver((a)=>a.forEach((a)=>b(a)));return d.observe(a,Object.assign({childList:!0,attributes:!0,attributeOldValue:!0,characterData:!0,characterDataOldValue:!0,subtree:!0},c)),d},off:(a,b,c,d=!1)=>a.removeEventListener(b,c,d),on:(a,b,c,d={})=>{const e=(a)=>a.target.matches(d.target)&&c.call(a.target,a);if(a.addEventListener(b,d.target?e:c,d.options||!1),d.target)return e},onUserInputChange:(a)=>{let b='mouse',c=0;const d=()=>{const e=performance.now();20>e-c&&(b='mouse',a(b),document.removeEventListener('mousemove',d)),c=e};document.addEventListener('touchstart',()=>{'touch'==b||(b='touch',a(b),document.addEventListener('mousemove',d))})},once:(a)=>{let b=!1;return function(...c){if(!b)return b=!0,a.apply(this,c)}},orderBy:(a,c,d)=>[...a].sort((e,a)=>c.reduce((b,c,f)=>{if(0===b){const[g,h]=d&&'desc'===d[f]?[a[c],e[c]]:[e[c],a[c]];b=g>h?1:g{const b=a.toLowerCase().replace(/[\W_]/g,'');return b===b.split('').reverse().join('')},parseCookie:(a)=>a.split(';').map((a)=>a.split('=')).reduce((a,b)=>(a[decodeURIComponent(b[0].trim())]=decodeURIComponent(b[1].trim()),a),{}),partition:(a,b)=>a.reduce((a,c,d,e)=>(a[b(c,d,e)?0:1].push(c),a),[[],[]]),percentile:(a,b)=>100*a.reduce((a,c)=>a+(cb.reduce((b,c)=>(c in a&&(b[c]=a[c]),b),{}),pipeFunctions:(...a)=>a.reduce((a,b)=>(...c)=>b(a(...c))),pluralize:(a,b,c=b+'s')=>{const d=(a,b,c=b+'s')=>[1,-1].includes(+a)?b:c;return'object'==typeof a?(b,c)=>d(b,c,a[c]):d(a,b,c)},powerset:(a)=>a.reduce((b,a)=>b.concat(b.map((b)=>[a].concat(b))),[[]]),prettyBytes:(a,b=3,c=!0)=>{const f=['B','KB','MB','GB','TB','PB','EB','ZB','YB'];if(1>Math.abs(a))return a+(c?' ':'')+f[0];const g=e(d(Math.log10(0>a?-a:a)/3),f.length-1),h=+((0>a?-a:a)/1e3**g).toPrecision(b);return(0>a?'-':'')+h+(c?' ':'')+f[g]},primes:(a)=>{let c=Array.from({length:a-1}).map((a,b)=>b+2),e=d(b(a)),f=Array.from({length:e-1}).map((a,b)=>b+2);return f.forEach((a)=>c=c.filter((b)=>0!=b%a||b==a)),c},promisify:(a)=>(...b)=>new Promise((c,d)=>a(...b,(a,b)=>a?d(a):c(b))),pull:(a,...b)=>{let c=Array.isArray(b[0])?b[0]:b,d=a.filter((a)=>!c.includes(a));a.length=0,d.forEach((b)=>a.push(b))},pullAtIndex:(a,b)=>{let c=[],d=a.map((a,d)=>b.includes(d)?c.push(a):a).filter((a,c)=>!b.includes(c));return a.length=0,d.forEach((b)=>a.push(b)),c},pullAtValue:(a,b)=>{let c=[],d=a.forEach((a)=>b.includes(a)?c.push(a):a),e=a.filter((a)=>!b.includes(a));return a.length=0,e.forEach((b)=>a.push(b)),c},randomHexColorCode:()=>{let a=(0|1048575*Math.random()).toString(16);return'#'+(6===a.length?a:(0|15*Math.random()).toString(16)+a)},randomIntArrayInRange:(a,b,c=1)=>Array.from({length:c},()=>d(Math.random()*(b-a+1))+a),randomIntegerInRange:(a,b)=>d(Math.random()*(b-a+1))+a,randomNumberInRange:(a,b)=>Math.random()*(b-a)+a,readFileLines:(a)=>s.readFileSync(a).toString('UTF8').split('\n'),redirect:(a,b=!0)=>b?window.location.href=a:window.location.replace(a),reducedFilter:(a,b,c)=>a.filter(c).map((a)=>b.reduce((b,c)=>(b[c]=a[c],b),{})),remove:(a,b)=>Array.isArray(a)?a.filter(b).reduce((b,c)=>(a.splice(a.indexOf(c),1),b.concat(c)),[]):[],reverseString:(a)=>[...a].join(''),round:(b,c=0)=>+`${a(`${b}e${c}`)}e-${c}`,runAsync:(a)=>{const b=`var fn = ${a.toString()}; postMessage(fn());`,c=new Worker(URL.createObjectURL(new Blob([b]),{type:'application/javascript; charset=utf-8'}));return new Promise((a,b)=>{c.onmessage=({data:b})=>{a(b),c.terminate()},c.onerror=(a)=>{b(a),c.terminate()}})},runPromisesInSeries:(a)=>a.reduce((a,b)=>a.then(b),Promise.resolve()),sample:(a)=>a[d(Math.random()*a.length)],sampleSize:([...a],b=1)=>{for(let c=a.length;c;){const b=d(Math.random()*c--);[a[c],a[b]]=[a[b],a[c]]}return a.slice(0,b)},scrollToTop:t,sdbm:(a)=>{let b=a.split('');return b.reduce((a,b)=>a=b.charCodeAt(0)+(a<<6)+(a<<16)-a,0)},select:(a,...b)=>[...b].map((b)=>b.split('.').reduce((a,b)=>a&&a[b],a)),serializeCookie:(a,b)=>`${encodeURIComponent(a)}=${encodeURIComponent(b)}`,setStyle:(a,b,c)=>a.style[b]=c,shallowClone:(a)=>Object.assign({},a),show:(...a)=>[...a].forEach((a)=>a.style.display=''),shuffle:([...a])=>{for(let b=a.length;b;){const c=d(Math.random()*b--);[a[b],a[c]]=[a[c],a[b]]}return a},similarity:(a,b)=>a.filter((a)=>b.includes(a)),size:(a)=>Array.isArray(a)?a.length:a&&'object'==typeof a?a.size||a.length||Object.keys(a).length:'string'==typeof a?new Blob([a]).size:0,sleep:(a)=>new Promise((b)=>setTimeout(b,a)),sortCharactersInString:(a)=>[...a].sort((c,a)=>c.localeCompare(a)).join(''),sortedIndex:(a,b)=>{const c=a[0]>a[a.length-1],d=a.findIndex((a)=>c?b>=a:b<=a);return-1===d?a.length:d},splitLines:(a)=>a.split(/\r?\n/),spreadOver:(a)=>(b)=>a(...b),standardDeviation:(a,c=!1)=>{const d=a.reduce((a,b)=>a+b,0)/a.length;return b(a.reduce((a,b)=>a.concat((b-d)**2),[]).reduce((a,b)=>a+b,0)/(a.length-(c?0:1)))},sum:(...a)=>[...a].reduce((a,b)=>a+b,0),sumBy:(a,b)=>a.map('function'==typeof b?b:(a)=>a[b]).reduce((a,b)=>a+b,0),sumPower:(a,b=2,c=1)=>Array(a+1-c).fill(0).map((a,d)=>(d+c)**b).reduce((c,a)=>c+a,0),symmetricDifference:(c,a)=>{const b=new Set(c),d=new Set(a);return[...c.filter((a)=>!d.has(a)),...a.filter((a)=>!b.has(a))]},tail:(a)=>1a.slice(0,b),takeRight:(a,b=1)=>a.slice(a.length-b,a.length),timeTaken:(a)=>{console.time('timeTaken');const b=a();return console.timeEnd('timeTaken'),b},toCamelCase:(a)=>{let b=a&&a.match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g).map((a)=>a.slice(0,1).toUpperCase()+a.slice(1).toLowerCase()).join('');return b.slice(0,1).toLowerCase()+b.slice(1)},toDecimalMark:(a)=>a.toLocaleString('en-US'),toKebabCase:(a)=>a&&a.match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g).map((a)=>a.toLowerCase()).join('-'),toOrdinalSuffix:(a)=>{const b=parseInt(a),c=[b%10,b%100],d=['st','nd','rd','th'];return[1,2,3,4].includes(c[0])&&![11,12,13,14,15,16,17,18,19].includes(c[1])?b+d[c[0]-1]:b+d[3]},toSafeInteger:(b)=>a(f(e(b,Number.MAX_SAFE_INTEGER),Number.MIN_SAFE_INTEGER)),toSnakeCase:(a)=>a&&a.match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g).map((a)=>a.toLowerCase()).join('_'),toggleClass:(a,b)=>a.classList.toggle(b),tomorrow:()=>new Date(new Date().getTime()+8.64e7).toISOString().split('T')[0],transform:(b,c,a)=>Object.keys(b).reduce((d,a)=>c(d,b[a],a,b),a),truncateString:(a,b)=>a.length>b?a.slice(0,3a.every((a)=>a[b]),unescapeHTML:(a)=>a.replace(/&|<|>|'|"/g,(a)=>({"&":'&',"<":'<',">":'>',"'":'\'',""":'"'})[a]||a),union:(c,a)=>Array.from(new Set([...c,...a])),untildify:(a)=>a.replace(/^~($|\/|\\)/,`${'undefined'!=typeof require&&require('os').homedir()}$1`),validateNumber:(a)=>!isNaN(parseFloat(a))&&isFinite(a)&&+a==a,without:(a,...b)=>a.filter((a)=>!b.includes(a)),words:(a,b=/[^a-zA-Z-]+/)=>a.split(b).filter(Boolean),yesNo:(a,b=!1)=>!!/^(y|yes)$/i.test(a)||!/^(n|no)$/i.test(a)&&b,zip:(...a)=>{const b=f(...a.map((a)=>a.length));return Array.from({length:b}).map((b,c)=>Array.from({length:a.length},(b,d)=>a[d][c]))},zipObject:(a,b)=>a.reduce((a,c,d)=>(a[c]=b[d],a),{})}}); diff --git a/snippets_archive/README.md b/snippets_archive/README.md index 8e92cc46b..541c6eb6a 100644 --- a/snippets_archive/README.md +++ b/snippets_archive/README.md @@ -6,6 +6,268 @@ These snippets, while useful and interesting, didn't quite make it into the repo ## Table of Contents +* [`JSONToDate`](#jsontodate) +* [`speechSynthesis`](#speechsynthesis) +* [`binarySearch`](#binarysearch) +* [`collatz`](#collatz) +* [`countVowels`](#countvowels) +* [`factors`](#factors) +* [`fibonacciCountUntilNum`](#fibonaccicountuntilnum) +* [`fibonacciUntilNum`](#fibonacciuntilnum) +* [`httpDelete`](#httpdelete) +* [`httpPut`](#httpput) +* [`isArmstrongNumber`](#isarmstrongnumber) +* [`quickSort`](#quicksort) +* [`removeVowels`](#removevowels) +* [`solveRPN`](#solverpn) +* [`howManyTimes`](#howmanytimes) + +--- + +### JSONToDate + +Converts a JSON object to a date. + +Use `Date()`, to convert dates in JSON format to readable format (`dd/mm/yyyy`). + +```js +const JSONToDate = arr => { + const dt = new Date(parseInt(arr.toString().substr(6))); + return `${dt.getDate()}/${dt.getMonth() + 1}/${dt.getFullYear()}`; +}; +``` + +
    +Examples + +```js +JSONToDate(/Date(1489525200000)/); // "14/3/2017" +``` + +
    + +
    [⬆ Back to top](#table-of-contents) + + +### speechSynthesis + +Performs speech synthesis (experimental). + +Use `SpeechSynthesisUtterance.voice` and `window.speechSynthesis.getVoices()` to convert a message to speech. +Use `window.speechSynthesis.speak()` to play the message. + +Learn more about the [SpeechSynthesisUtterance interface of the Web Speech API](https://developer.mozilla.org/en-US/docs/Web/API/SpeechSynthesisUtterance). + +```js +const speechSynthesis = message => { + const msg = new SpeechSynthesisUtterance(message); + msg.voice = window.speechSynthesis.getVoices()[0]; + window.speechSynthesis.speak(msg); +}; +``` + +
    +Examples + +```js +speechSynthesis('Hello, World'); // // plays the message +``` + +
    + +
    [⬆ Back to top](#table-of-contents) + + +### binarySearch + +Use recursion. Similar to `Array.indexOf()` that finds the index of a value within an array. +The difference being this operation only works with sorted arrays which offers a major performance boost due to it's logarithmic nature when compared to a linear search or `Array.indexOf()`. + +Search a sorted array by repeatedly dividing the search interval in half. +Begin with an interval covering the whole array. +If the value of the search is less than the item in the middle of the interval, recurse into the lower half. Otherwise recurse into the upper half. +Repeatedly recurse until the value is found which is the mid or you've recursed to a point that is greater than the length which means the value doesn't exist and return `-1`. + +```js +const binarySearch = (arr, val, start = 0, end = arr.length - 1) => { + if (start > end) return -1; + const mid = Math.floor((start + end) / 2); + if (arr[mid] > val) return binarySearch(arr, val, start, mid - 1); + if (arr[mid] < val) return binarySearch(arr, val, mid + 1, end); + return mid; +} +``` + +
    +Examples + +```js +binarySearch([1, 4, 6, 7, 12, 13, 15, 18, 19, 20, 22, 24], 6); // 2 +binarySearch([1, 4, 6, 7, 12, 13, 15, 18, 19, 20, 22, 24], 21); // -1 +``` + +
    + +
    [⬆ Back to top](#table-of-contents) + + +### collatz + +Applies the Collatz algorithm. + +If `n` is even, return `n/2`. Otherwise, return `3n+1`. + +```js +const collatz = n => (n % 2 == 0 ? n / 2 : 3 * n + 1); +``` + +
    +Examples + +```js +collatz(8); // 4 +``` + +
    + +
    [⬆ Back to top](#table-of-contents) + + +### countVowels + +Retuns `number` of vowels in provided string. + +Use a regular expression to count the number of vowels `(A, E, I, O, U)` in a `string`. + +```js +const countVowels = str => (str.match(/[aeiou]/gi) || []).length; +``` + +
    +Examples + +```js +countVowels('foobar'); // 3 +countVowels('gym'); // 0 +``` + +
    + +
    [⬆ Back to top](#table-of-contents) + + +### factors + +Returns the array of factors of the given `num`. +If the second argument is set to `true` returns only the prime factors of `num`. +If `num` is `1` or `0` returns an empty array. +If `num` is less than `0` returns all the factors of `-int` together with their additive inverses. + +Use `Array.from()`, `Array.map()` and `Array.filter()` to find all the factors of `num`. +If given `num` is negative, use `Array.reduce()` to add the additive inverses to the array. +Return all results if `primes` is `false`, else determine and return only the prime factors using `isPrime` and `Array.filter()`. +Omit the second argument, `primes`, to return prime and non-prime factors by default. + +**Note**:- _Negative numbers are not considered prime._ + +```js +const factors = (num, primes = false) => { + const isPrime = num => { + const boundary = Math.floor(Math.sqrt(num)); + for (var i = 2; i <= boundary; i++) if (num % i === 0) return false; + return num >= 2; + }; + const isNeg = num < 0; + num = isNeg ? -num : num; + let array = Array.from({ length: num - 1 }) + .map((val, i) => (num % (i + 2) === 0 ? i + 2 : false)) + .filter(val => val); + if (isNeg) + array = array.reduce((acc, val) => { + acc.push(val); + acc.push(-val); + return acc; + }, []); + return primes ? array.filter(isPrime) : array; +}; +``` + +
    +Examples + +```js +factors(12); // [2,3,4,6,12] +factors(12, true); // [2,3] +factors(-12); // [2, -2, 3, -3, 4, -4, 6, -6, 12, -12] +factors(-12, true); // [2,3] +``` + +
    + +
    [⬆ Back to top](#table-of-contents) + + +### fibonacciCountUntilNum + +Returns the number of fibonnacci numbers up to `num`(`0` and `num` inclusive). + +Use a mathematical formula to calculate the number of fibonacci numbers until `num`. + +```js +const fibonacciCountUntilNum = num => + Math.ceil(Math.log(num * Math.sqrt(5) + 1 / 2) / Math.log((Math.sqrt(5) + 1) / 2)); +``` + +
    +Examples + +```js +fibonacciCountUntilNum(10); // 7 +``` + +
    + +
    [⬆ Back to top](#table-of-contents) + + +### fibonacciUntilNum + +Generates an array, containing the Fibonacci sequence, up until the nth term. + +Create an empty array of the specific length, initializing the first two values (`0` and `1`). +Use `Array.reduce()` to add values into the array, using the sum of the last two values, except for the first two. +Uses a mathematical formula to calculate the length of the array required. + +```js +const fibonacciUntilNum = num => { + let n = Math.ceil(Math.log(num * Math.sqrt(5) + 1 / 2) / Math.log((Math.sqrt(5) + 1) / 2)); + return Array.from({ length: n }).reduce( + (acc, val, i) => acc.concat(i > 1 ? acc[i - 1] + acc[i - 2] : i), + [] + ); +}; +``` + +
    +Examples + +```js +fibonacciUntilNum(10); // [ 0, 1, 1, 2, 3, 5, 8 ] +``` + +
    + +
    [⬆ Back to top](#table-of-contents) + + +![Logo](/logo.png) + +# Snippets Archive + +These snippets, while useful and interesting, didn't quite make it into the repository due to either having very specific use-cases or being outdated. However we felt like they might still be useful to some readers, so here they are. + +## Table of Contents + * [`JSONToDate.md`](#jsontodate.md) * [`speechSynthesis.md`](#speechsynthesis.md) * [`binarySearch.md`](#binarysearch.md) @@ -1795,6 +2057,258 @@ solveRPN('2 3 ^'); // 8
    [⬆ Back to top](#table-of-contents) +### howManyTimes + +Returns the number of times `num` can be divided by `divisor` (integer or fractional) without getting a fractional answer. +Works for both negative and positive integers. + +If `divisor` is `-1` or `1` return `Infinity`. +If `divisor` is `-0` or `0` return `0`. +Otherwise, keep dividing `num` with `divisor` and incrementing `i`, while the result is an integer. +Return the number of times the loop was executed, `i`. + +```js +const howManyTimes = (num, divisor) => { + if (divisor === 1 || divisor === -1) return Infinity; + if (divisor === 0) return 0; + let i = 0; + while (Number.isInteger(num / divisor)) { + i++; + num = num / divisor; + } + return i; +}; +``` + +
    +Examples + +
    +Examples + +```js +howManyTimes(100, 2); // 2 +howManyTimes(100, 2.5); // 2 +howManyTimes(100, 0); // 0 +howManyTimes(100, -1); // Infinity +``` + +
    + +
    [⬆ Back to top](#table-of-contents) + + +
    + +
    [⬆ Back to top](#table-of-contents) + + +### httpDelete + +Makes a `DELETE` request to the passed URL. + +Use `XMLHttpRequest` web api to make a `delete` request to the given `url`. +Handle the `onload` event, by running the provided `callback` function. +Handle the `onerror` event, by running the provided `err` function. +Omit the third argument, `err` to log the request to the console's error stream by default. + +```js +const httpDelete = (url, callback, err = console.error) => { + const request = new XMLHttpRequest(); + request.open("DELETE", url, true); + request.onload = () => callback(request); + request.onerror = () => err(request); + request.send(); +}; +``` + +
    +Examples + +```js +httpDelete('https://website.com/users/123', request => { + console.log(request.responseText); +}); // 'Deletes a user from the database' +``` + +
    + +
    [⬆ Back to top](#table-of-contents) + + +### httpPut + +Makes a `PUT` request to the passed URL. + +Use `XMLHttpRequest` web api to make a `put` request to the given `url`. +Set the value of an `HTTP` request header with `setRequestHeader` method. +Handle the `onload` event, by running the provided `callback` function. +Handle the `onerror` event, by running the provided `err` function. +Omit the last argument, `err` to log the request to the console's error stream by default. + +```js +const httpPut = (url, data, callback, err = console.error) => { + const request = new XMLHttpRequest(); + request.open("PUT", url, true); + request.setRequestHeader('Content-type','application/json; charset=utf-8'); + request.onload = () => callback(request); + request.onerror = () => err(request); + request.send(data); +}; +``` + +
    +Examples + +```js +const password = "fooBaz"; +const data = JSON.stringify(password); +httpPut('https://website.com/users/123', data, request => { + console.log(request.responseText); +}); // 'Updates a user's password in database' +``` + +
    + +
    [⬆ Back to top](#table-of-contents) + + +### isArmstrongNumber + +Checks if the given number is an Armstrong number or not. + +Convert the given number into an array of digits. Use the exponent operator (`**`) to get the appropriate power for each digit and sum them up. If the sum is equal to the number itself, return `true` otherwise `false`. + +```js +const isArmstrongNumber = digits => + (arr => arr.reduce((a, d) => a + parseInt(d) ** arr.length, 0) == digits)( + (digits + '').split('') + ); +``` + +
    +Examples + +```js +isArmstrongNumber(1634); // true +isArmstrongNumber(56); // false +``` + +
    + +
    [⬆ Back to top](#table-of-contents) + + +### quickSort + +QuickSort an Array (ascending sort by default). + +Use recursion. +Use `Array.filter` and spread operator (`...`) to create an array that all elements with values less than the pivot come before the pivot, and all elements with values greater than the pivot come after it. +If the parameter `desc` is truthy, return array sorts in descending order. + +```js +const quickSort = ([n, ...nums], desc) => + isNaN(n) + ? [] + : [ + ...quickSort(nums.filter(v => (desc ? v > n : v <= n)), desc), + n, + ...quickSort(nums.filter(v => (!desc ? v > n : v <= n)), desc) + ]; +``` + +
    +Examples + +```js +quickSort([4, 1, 3, 2]); // [1,2,3,4] +quickSort([4, 1, 3, 2], true); // [4,3,2,1] +``` + +
    + +
    [⬆ Back to top](#table-of-contents) + + +### removeVowels + +Returns all the vowels in a `str` replaced by `repl`. + +Use `String.replace()` with a regexp to replace all vowels in `str`. +Omot `repl` to use a default value of `''`. + +```js +const removeVowels = (str, repl = '') => str.replace(/[aeiou]/gi,repl); +``` + +
    +Examples + +```js +removeVowels("foobAr"); // "fbr" +removeVowels("foobAr","*"); // "f**b*r" +``` + +
    + +
    [⬆ Back to top](#table-of-contents) + + +### solveRPN + +Solves the given mathematical expression in [reverse polish notation](https://en.wikipedia.org/wiki/Reverse_Polish_notation). +Throws appropriate errors if there are unrecognized symbols or the expression is wrong. The valid operators are :- `+`,`-`,`*`,`/`,`^`,`**` (`^`&`**` are the exponential symbols and are same). This snippet does not supports any unary operators. + +Use a dictionary, `OPERATORS` to specify each operator's matching mathematical operation. +Use `String.replace()` with a regular expression to replace `^` with `**`, `String.split()` to tokenize the string and `Array.filter()` to remove empty tokens. +Use `Array.forEach()` to parse each `symbol`, evaluate it as a numeric value or operator and solve the mathematical expression. +Numeric values are converted to floating point numbers and pushed to a `stack`, while operators are evaluated using the `OPERATORS` dictionary and pop elements from the `stack` to apply operations. + +```js +const solveRPN = rpn => { + const OPERATORS = { + '*': (a, b) => a * b, + '+': (a, b) => a + b, + '-': (a, b) => a - b, + '/': (a, b) => a / b, + '**': (a, b) => a ** b + }; + const [stack, solve] = [ + [], + rpn + .replace(/\^/g, '**') + .split(/\s+/g) + .filter(el => !/\s+/.test(el) && el !== '') + ]; + solve.forEach(symbol => { + if (!isNaN(parseFloat(symbol)) && isFinite(symbol)) { + stack.push(symbol); + } else if (Object.keys(OPERATORS).includes(symbol)) { + const [a, b] = [stack.pop(), stack.pop()]; + stack.push(OPERATORS[symbol](parseFloat(b), parseFloat(a))); + } else { + throw `${symbol} is not a recognized symbol`; + } + }); + if (stack.length === 1) return stack.pop(); + else throw `${rpn} is not a proper RPN. Please check it and try again`; +}; +``` + +
    +Examples + +```js +solveRPN('15 7 1 1 + - / 3 * 2 1 1 + + -'); // 5 +solveRPN('2 3 ^'); // 8 +``` + +
    + +
    [⬆ Back to top](#table-of-contents) + + ### howManyTimes Returns the number of times `num` can be divided by `divisor` (integer or fractional) without getting a fractional answer. diff --git a/test/observeMutations/observeMutations.js b/test/observeMutations/observeMutations.js new file mode 100644 index 000000000..15a462fac --- /dev/null +++ b/test/observeMutations/observeMutations.js @@ -0,0 +1,18 @@ +module.exports = observeMutations = (element, callback, options) => { +const observer = new MutationObserver(mutations => mutations.forEach(m => callback(m))); +observer.observe( +element, +Object.assign( +{ +childList: true, +attributes: true, +attributeOldValue: true, +characterData: true, +characterDataOldValue: true, +subtree: true +}, +options +) +); +return observer; +}; \ No newline at end of file diff --git a/test/observeMutations/observeMutations.test.js b/test/observeMutations/observeMutations.test.js new file mode 100644 index 000000000..eca8ff0d4 --- /dev/null +++ b/test/observeMutations/observeMutations.test.js @@ -0,0 +1,13 @@ +const test = require('tape'); +const observeMutations = require('./observeMutations.js'); + +test('Testing observeMutations', (t) => { + //For more information on all the methods supported by tape + //Please go to https://github.com/substack/tape + t.true(typeof observeMutations === 'function', 'observeMutations is a Function'); + //t.deepEqual(observeMutations(args..), 'Expected'); + //t.equal(observeMutations(args..), 'Expected'); + //t.false(observeMutations(args..), 'Expected'); + //t.throws(observeMutations(args..), 'Expected'); + t.end(); +}); \ No newline at end of file diff --git a/test/testlog b/test/testlog index 42b59cf00..558b0fba4 100644 --- a/test/testlog +++ b/test/testlog @@ -1,4 +1,4 @@ -Test log for: Tue Jan 16 2018 13:20:30 GMT+0000 (UTC) +Test log for: Tue Jan 16 2018 14:20:20 GMT+0000 (UTC) > 30-seconds-of-code@0.0.1 test /home/travis/build/Chalarangelo/30-seconds-of-code > tape test/**/*.test.js | tap-spec @@ -734,6 +734,10 @@ Test log for: Tue Jan 16 2018 13:20:30 GMT+0000 (UTC) ✔ objectToPairs is a Function ✔ Creates an array of key-value pair arrays from an object. + Testing observeMutations + + ✔ observeMutations is a Function + Testing off ✔ off is a Function @@ -1142,8 +1146,8 @@ Test log for: Tue Jan 16 2018 13:20:30 GMT+0000 (UTC) ✔ Array was zipped to object - total: 489 - passing: 489 - duration: 512ms + total: 490 + passing: 490 + duration: 270ms From f076160341630ebb7bd903904e2149a04f29593b Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Tue, 16 Jan 2018 16:23:25 +0200 Subject: [PATCH 08/13] Fixed snippet archiver build and generated README --- scripts/build.js | 4 +- snippets_archive/README.md | 1749 +++++------------------------------- 2 files changed, 212 insertions(+), 1541 deletions(-) diff --git a/scripts/build.js b/scripts/build.js index c3fa534bd..2eba5bc0e 100644 --- a/scripts/build.js +++ b/scripts/build.js @@ -26,7 +26,7 @@ if(isTravisCI() && (process.env['TRAVIS_EVENT_TYPE'] === 'cron' || process.env[' .readdirSync(SNIPPETS_ARCHIVE_PATH) .sort((a, b) => a.toLowerCase() - b.toLowerCase()); // Store the data read from each snippet in the appropriate object - for (const name of snippetFilenames) { + for (const name of snippetFilenames.filter(s => s !== 'README.md')) { snippets[name] = fs.readFileSync(path.join(SNIPPETS_ARCHIVE_PATH, name), 'utf8'); } } catch (err) { @@ -44,7 +44,7 @@ These snippets, while useful and interesting, didn\'t quite make it into the rep ## Table of Contents ` - for(const snippet of Object.entries(snippets).filter(s => s[0] !== 'README.md')) + for(const snippet of Object.entries(snippets)) output += `* [\`${snippet[0].slice(0,-3)}\`](#${snippet[0].toLowerCase().slice(0,-3)})\n`; output += '\n---\n'; for(const snippet of Object.entries(snippets)){ diff --git a/snippets_archive/README.md b/snippets_archive/README.md index 8e92cc46b..bd7001585 100644 --- a/snippets_archive/README.md +++ b/snippets_archive/README.md @@ -6,79 +6,24 @@ These snippets, while useful and interesting, didn't quite make it into the repo ## Table of Contents -* [`JSONToDate.md`](#jsontodate.md) -* [`speechSynthesis.md`](#speechsynthesis.md) -* [`binarySearch.md`](#binarysearch.md) -* [`collatz.md`](#collatz.md) -* [`countVowels.md`](#countvowels.md) -* [`factors.md`](#factors.md) -* [`fibonacciCountUntilNum.md`](#fibonaccicountuntilnum.md) -* [`fibonacciUntilNum.md`](#fibonacciuntilnum.md) -* [`README.md`](#readme.md) -* [`httpDelete.md`](#httpdelete.md) -* [`httpPut.md`](#httpput.md) -* [`isArmstrongNumber.md`](#isarmstrongnumber.md) -* [`quickSort.md`](#quicksort.md) -* [`removeVowels.md`](#removevowels.md) -* [`solveRPN.md`](#solverpn.md) -* [`howManyTimes.md`](#howmanytimes.md) +* [`binarySearch`](#binarysearch) +* [`speechSynthesis`](#speechsynthesis) +* [`countVowels`](#countvowels) +* [`factors`](#factors) +* [`fibonacciCountUntilNum`](#fibonaccicountuntilnum) +* [`fibonacciUntilNum`](#fibonacciuntilnum) +* [`howManyTimes`](#howmanytimes) +* [`httpDelete`](#httpdelete) +* [`collatz`](#collatz) +* [`isArmstrongNumber`](#isarmstrongnumber) +* [`JSONToDate`](#jsontodate) +* [`quickSort`](#quicksort) +* [`removeVowels`](#removevowels) +* [`solveRPN`](#solverpn) +* [`httpPut`](#httpput) --- -### JSONToDate - -Converts a JSON object to a date. - -Use `Date()`, to convert dates in JSON format to readable format (`dd/mm/yyyy`). - -```js -const JSONToDate = arr => { - const dt = new Date(parseInt(arr.toString().substr(6))); - return `${dt.getDate()}/${dt.getMonth() + 1}/${dt.getFullYear()}`; -}; -``` - -
    -Examples - -```js -JSONToDate(/Date(1489525200000)/); // "14/3/2017" -``` - -
    - -
    [⬆ Back to top](#table-of-contents) - - -### speechSynthesis - -Performs speech synthesis (experimental). - -Use `SpeechSynthesisUtterance.voice` and `window.speechSynthesis.getVoices()` to convert a message to speech. -Use `window.speechSynthesis.speak()` to play the message. - -Learn more about the [SpeechSynthesisUtterance interface of the Web Speech API](https://developer.mozilla.org/en-US/docs/Web/API/SpeechSynthesisUtterance). - -```js -const speechSynthesis = message => { - const msg = new SpeechSynthesisUtterance(message); - msg.voice = window.speechSynthesis.getVoices()[0]; - window.speechSynthesis.speak(msg); -}; -``` - -
    -Examples - -```js -speechSynthesis('Hello, World'); // // plays the message -``` - -
    - -
    [⬆ Back to top](#table-of-contents) - - ### binarySearch Use recursion. Similar to `Array.indexOf()` that finds the index of a value within an array. @@ -112,21 +57,28 @@ binarySearch([1, 4, 6, 7, 12, 13, 15, 18, 19, 20, 22, 24], 21); // -1
    [⬆ Back to top](#table-of-contents) -### collatz +### speechSynthesis -Applies the Collatz algorithm. +Performs speech synthesis (experimental). -If `n` is even, return `n/2`. Otherwise, return `3n+1`. +Use `SpeechSynthesisUtterance.voice` and `window.speechSynthesis.getVoices()` to convert a message to speech. +Use `window.speechSynthesis.speak()` to play the message. + +Learn more about the [SpeechSynthesisUtterance interface of the Web Speech API](https://developer.mozilla.org/en-US/docs/Web/API/SpeechSynthesisUtterance). ```js -const collatz = n => (n % 2 == 0 ? n / 2 : 3 * n + 1); +const speechSynthesis = message => { + const msg = new SpeechSynthesisUtterance(message); + msg.voice = window.speechSynthesis.getVoices()[0]; + window.speechSynthesis.speak(msg); +}; ```
    Examples ```js -collatz(8); // 4 +speechSynthesis('Hello, World'); // // plays the message ```
    @@ -261,698 +213,6 @@ fibonacciUntilNum(10); // [ 0, 1, 1, 2, 3, 5, 8 ]
    [⬆ Back to top](#table-of-contents) -![Logo](/logo.png) - -# Snippets Archive - -These snippets, while useful and interesting, didn't quite make it into the repository due to either having very specific use-cases or being outdated. However we felt like they might still be useful to some readers, so here they are. - -## Table of Contents - -* [`JSONToDate.md`](#jsontodate.md) -* [`speechSynthesis.md`](#speechsynthesis.md) -* [`binarySearch.md`](#binarysearch.md) -* [`collatz.md`](#collatz.md) -* [`countVowels.md`](#countvowels.md) -* [`factors.md`](#factors.md) -* [`fibonacciCountUntilNum.md`](#fibonaccicountuntilnum.md) -* [`README.md`](#readme.md) -* [`howManyTimes.md`](#howmanytimes.md) -* [`isArmstrongNumber.md`](#isarmstrongnumber.md) -* [`quickSort.md`](#quicksort.md) -* [`removeVowels.md`](#removevowels.md) -* [`solveRPN.md`](#solverpn.md) -* [`fibonacciUntilNum.md`](#fibonacciuntilnum.md) - ---- - -### JSONToDate - -Converts a JSON object to a date. - -Use `Date()`, to convert dates in JSON format to readable format (`dd/mm/yyyy`). - -```js -const JSONToDate = arr => { - const dt = new Date(parseInt(arr.toString().substr(6))); - return `${dt.getDate()}/${dt.getMonth() + 1}/${dt.getFullYear()}`; -}; -``` - -
    -Examples - -```js -JSONToDate(/Date(1489525200000)/); // "14/3/2017" -``` - -
    - -
    [⬆ Back to top](#table-of-contents) - - -### speechSynthesis - -Performs speech synthesis (experimental). - -Use `SpeechSynthesisUtterance.voice` and `window.speechSynthesis.getVoices()` to convert a message to speech. -Use `window.speechSynthesis.speak()` to play the message. - -Learn more about the [SpeechSynthesisUtterance interface of the Web Speech API](https://developer.mozilla.org/en-US/docs/Web/API/SpeechSynthesisUtterance). - -```js -const speechSynthesis = message => { - const msg = new SpeechSynthesisUtterance(message); - msg.voice = window.speechSynthesis.getVoices()[0]; - window.speechSynthesis.speak(msg); -}; -``` - -
    -Examples - -```js -speechSynthesis('Hello, World'); // // plays the message -``` - -
    - -
    [⬆ Back to top](#table-of-contents) - - -### binarySearch - -Use recursion. Similar to `Array.indexOf()` that finds the index of a value within an array. -The difference being this operation only works with sorted arrays which offers a major performance boost due to it's logarithmic nature when compared to a linear search or `Array.indexOf()`. - -Search a sorted array by repeatedly dividing the search interval in half. -Begin with an interval covering the whole array. -If the value of the search is less than the item in the middle of the interval, recurse into the lower half. Otherwise recurse into the upper half. -Repeatedly recurse until the value is found which is the mid or you've recursed to a point that is greater than the length which means the value doesn't exist and return `-1`. - -```js -const binarySearch = (arr, val, start = 0, end = arr.length - 1) => { - if (start > end) return -1; - const mid = Math.floor((start + end) / 2); - if (arr[mid] > val) return binarySearch(arr, val, start, mid - 1); - if (arr[mid] < val) return binarySearch(arr, val, mid + 1, end); - return mid; -} -``` - -
    -Examples - -```js -binarySearch([1, 4, 6, 7, 12, 13, 15, 18, 19, 20, 22, 24], 6); // 2 -binarySearch([1, 4, 6, 7, 12, 13, 15, 18, 19, 20, 22, 24], 21); // -1 -``` - -
    - -
    [⬆ Back to top](#table-of-contents) - - -### collatz - -Applies the Collatz algorithm. - -If `n` is even, return `n/2`. Otherwise, return `3n+1`. - -```js -const collatz = n => (n % 2 == 0 ? n / 2 : 3 * n + 1); -``` - -
    -Examples - -```js -collatz(8); // 4 -``` - -
    - -
    [⬆ Back to top](#table-of-contents) - - -### countVowels - -Retuns `number` of vowels in provided string. - -Use a regular expression to count the number of vowels `(A, E, I, O, U)` in a `string`. - -```js -const countVowels = str => (str.match(/[aeiou]/gi) || []).length; -``` - -
    -Examples - -```js -countVowels('foobar'); // 3 -countVowels('gym'); // 0 -``` - -
    - -
    [⬆ Back to top](#table-of-contents) - - -### factors - -Returns the array of factors of the given `num`. -If the second argument is set to `true` returns only the prime factors of `num`. -If `num` is `1` or `0` returns an empty array. -If `num` is less than `0` returns all the factors of `-int` together with their additive inverses. - -Use `Array.from()`, `Array.map()` and `Array.filter()` to find all the factors of `num`. -If given `num` is negative, use `Array.reduce()` to add the additive inverses to the array. -Return all results if `primes` is `false`, else determine and return only the prime factors using `isPrime` and `Array.filter()`. -Omit the second argument, `primes`, to return prime and non-prime factors by default. - -**Note**:- _Negative numbers are not considered prime._ - -```js -const factors = (num, primes = false) => { - const isPrime = num => { - const boundary = Math.floor(Math.sqrt(num)); - for (var i = 2; i <= boundary; i++) if (num % i === 0) return false; - return num >= 2; - }; - const isNeg = num < 0; - num = isNeg ? -num : num; - let array = Array.from({ length: num - 1 }) - .map((val, i) => (num % (i + 2) === 0 ? i + 2 : false)) - .filter(val => val); - if (isNeg) - array = array.reduce((acc, val) => { - acc.push(val); - acc.push(-val); - return acc; - }, []); - return primes ? array.filter(isPrime) : array; -}; -``` - -
    -Examples - -```js -factors(12); // [2,3,4,6,12] -factors(12, true); // [2,3] -factors(-12); // [2, -2, 3, -3, 4, -4, 6, -6, 12, -12] -factors(-12, true); // [2,3] -``` - -
    - -
    [⬆ Back to top](#table-of-contents) - - -### fibonacciCountUntilNum - -Returns the number of fibonnacci numbers up to `num`(`0` and `num` inclusive). - -Use a mathematical formula to calculate the number of fibonacci numbers until `num`. - -```js -const fibonacciCountUntilNum = num => - Math.ceil(Math.log(num * Math.sqrt(5) + 1 / 2) / Math.log((Math.sqrt(5) + 1) / 2)); -``` - -
    -Examples - -```js -fibonacciCountUntilNum(10); // 7 -``` - -
    - -
    [⬆ Back to top](#table-of-contents) - - -![Logo](/logo.png) - -# Snippets Archive - -These snippets, while useful and interesting, didn't quite make it into the repository due to either having very specific use-cases or being outdated. However we felt like they might still be useful to some readers, so here they are. - -## Table of Contents - -* [`JSONToDate.md`](#jsontodate.md) -* [`speechSynthesis.md`](#speechsynthesis.md) -* [`binarySearch.md`](#binarysearch.md) -* [`collatz.md`](#collatz.md) -* [`countVowels.md`](#countvowels.md) -* [`factors.md`](#factors.md) -* [`fibonacciCountUntilNum.md`](#fibonaccicountuntilnum.md) -* [`README.md`](#readme.md) -* [`howManyTimes.md`](#howmanytimes.md) -* [`isArmstrongNumber.md`](#isarmstrongnumber.md) -* [`quickSort.md`](#quicksort.md) -* [`removeVowels.md`](#removevowels.md) -* [`solveRPN.md`](#solverpn.md) -* [`fibonacciUntilNum.md`](#fibonacciuntilnum.md) - ---- - -### JSONToDate - -Converts a JSON object to a date. - -Use `Date()`, to convert dates in JSON format to readable format (`dd/mm/yyyy`). - -```js -const JSONToDate = arr => { - const dt = new Date(parseInt(arr.toString().substr(6))); - return `${dt.getDate()}/${dt.getMonth() + 1}/${dt.getFullYear()}`; -}; -``` - -
    -Examples - -```js -JSONToDate(/Date(1489525200000)/); // "14/3/2017" -``` - -
    - -
    [⬆ Back to top](#table-of-contents) - - -### speechSynthesis - -Performs speech synthesis (experimental). - -Use `SpeechSynthesisUtterance.voice` and `window.speechSynthesis.getVoices()` to convert a message to speech. -Use `window.speechSynthesis.speak()` to play the message. - -Learn more about the [SpeechSynthesisUtterance interface of the Web Speech API](https://developer.mozilla.org/en-US/docs/Web/API/SpeechSynthesisUtterance). - -```js -const speechSynthesis = message => { - const msg = new SpeechSynthesisUtterance(message); - msg.voice = window.speechSynthesis.getVoices()[0]; - window.speechSynthesis.speak(msg); -}; -``` - -
    -Examples - -```js -speechSynthesis('Hello, World'); // // plays the message -``` - -
    - -
    [⬆ Back to top](#table-of-contents) - - -### binarySearch - -Use recursion. Similar to `Array.indexOf()` that finds the index of a value within an array. -The difference being this operation only works with sorted arrays which offers a major performance boost due to it's logarithmic nature when compared to a linear search or `Array.indexOf()`. - -Search a sorted array by repeatedly dividing the search interval in half. -Begin with an interval covering the whole array. -If the value of the search is less than the item in the middle of the interval, recurse into the lower half. Otherwise recurse into the upper half. -Repeatedly recurse until the value is found which is the mid or you've recursed to a point that is greater than the length which means the value doesn't exist and return `-1`. - -```js -const binarySearch = (arr, val, start = 0, end = arr.length - 1) => { - if (start > end) return -1; - const mid = Math.floor((start + end) / 2); - if (arr[mid] > val) return binarySearch(arr, val, start, mid - 1); - if (arr[mid] < val) return binarySearch(arr, val, mid + 1, end); - return mid; -} -``` - -
    -Examples - -```js -binarySearch([1, 4, 6, 7, 12, 13, 15, 18, 19, 20, 22, 24], 6); // 2 -binarySearch([1, 4, 6, 7, 12, 13, 15, 18, 19, 20, 22, 24], 21); // -1 -``` - -
    - -
    [⬆ Back to top](#table-of-contents) - - -### collatz - -Applies the Collatz algorithm. - -If `n` is even, return `n/2`. Otherwise, return `3n+1`. - -```js -const collatz = n => (n % 2 == 0 ? n / 2 : 3 * n + 1); -``` - -
    -Examples - -```js -collatz(8); // 4 -``` - -
    - -
    [⬆ Back to top](#table-of-contents) - - -### countVowels - -Retuns `number` of vowels in provided string. - -Use a regular expression to count the number of vowels `(A, E, I, O, U)` in a `string`. - -```js -const countVowels = str => (str.match(/[aeiou]/gi) || []).length; -``` - -
    -Examples - -```js -countVowels('foobar'); // 3 -countVowels('gym'); // 0 -``` - -
    - -
    [⬆ Back to top](#table-of-contents) - - -### factors - -Returns the array of factors of the given `num`. -If the second argument is set to `true` returns only the prime factors of `num`. -If `num` is `1` or `0` returns an empty array. -If `num` is less than `0` returns all the factors of `-int` together with their additive inverses. - -Use `Array.from()`, `Array.map()` and `Array.filter()` to find all the factors of `num`. -If given `num` is negative, use `Array.reduce()` to add the additive inverses to the array. -Return all results if `primes` is `false`, else determine and return only the prime factors using `isPrime` and `Array.filter()`. -Omit the second argument, `primes`, to return prime and non-prime factors by default. - -**Note**:- _Negative numbers are not considered prime._ - -```js -const factors = (num, primes = false) => { - const isPrime = num => { - const boundary = Math.floor(Math.sqrt(num)); - for (var i = 2; i <= boundary; i++) if (num % i === 0) return false; - return num >= 2; - }; - const isNeg = num < 0; - num = isNeg ? -num : num; - let array = Array.from({ length: num - 1 }) - .map((val, i) => (num % (i + 2) === 0 ? i + 2 : false)) - .filter(val => val); - if (isNeg) - array = array.reduce((acc, val) => { - acc.push(val); - acc.push(-val); - return acc; - }, []); - return primes ? array.filter(isPrime) : array; -}; -``` - -
    -Examples - -```js -factors(12); // [2,3,4,6,12] -factors(12, true); // [2,3] -factors(-12); // [2, -2, 3, -3, 4, -4, 6, -6, 12, -12] -factors(-12, true); // [2,3] -``` - -
    - -
    [⬆ Back to top](#table-of-contents) - - -### fibonacciCountUntilNum - -Returns the number of fibonnacci numbers up to `num`(`0` and `num` inclusive). - -Use a mathematical formula to calculate the number of fibonacci numbers until `num`. - -```js -const fibonacciCountUntilNum = num => - Math.ceil(Math.log(num * Math.sqrt(5) + 1 / 2) / Math.log((Math.sqrt(5) + 1) / 2)); -``` - -
    -Examples - -```js -fibonacciCountUntilNum(10); // 7 -``` - -
    - -
    [⬆ Back to top](#table-of-contents) - - -![Logo](/logo.png) - -# 30 seconds of code - -These snippets , while useful and interesting, didn't quite make it into the repository due to either having very specific use-cases or being outdated. However we felt like they might still be useful to some readers, so here they are. - -## Table of Contents - -* [`JSONToDate.md`](#jsontodate.md -* [`speechSynthesis.md`](#speechsynthesis.md -* [`collatz.md`](#collatz.md -* [`countVowels.md`](#countvowels.md -* [`factors.md`](#factors.md -* [`fibonacciCountUntilNum.md`](#fibonaccicountuntilnum.md -* [`binarySearch.md`](#binarysearch.md -* [`howManyTimes.md`](#howmanytimes.md -* [`isArmstrongNumber.md`](#isarmstrongnumber.md -* [`quickSort.md`](#quicksort.md -* [`removeVowels.md`](#removevowels.md -* [`solveRPN.md`](#solverpn.md -* [`fibonacciUntilNum.md`](#fibonacciuntilnum.md - ---- - -### JSONToDate - -Converts a JSON object to a date. - -Use `Date()`, to convert dates in JSON format to readable format (`dd/mm/yyyy`). - -```js -const JSONToDate = arr => { - const dt = new Date(parseInt(arr.toString().substr(6))); - return `${dt.getDate()}/${dt.getMonth() + 1}/${dt.getFullYear()}`; -}; -``` - -
    -Examples - -```js -JSONToDate(/Date(1489525200000)/); // "14/3/2017" -``` - -
    - -
    [⬆ Back to top](#table-of-contents) - - -### speechSynthesis - -Performs speech synthesis (experimental). - -Use `SpeechSynthesisUtterance.voice` and `window.speechSynthesis.getVoices()` to convert a message to speech. -Use `window.speechSynthesis.speak()` to play the message. - -Learn more about the [SpeechSynthesisUtterance interface of the Web Speech API](https://developer.mozilla.org/en-US/docs/Web/API/SpeechSynthesisUtterance). - -```js -const speechSynthesis = message => { - const msg = new SpeechSynthesisUtterance(message); - msg.voice = window.speechSynthesis.getVoices()[0]; - window.speechSynthesis.speak(msg); -}; -``` - -
    -Examples - -```js -speechSynthesis('Hello, World'); // // plays the message -``` - -
    - -
    [⬆ Back to top](#table-of-contents) - - -### collatz - -Applies the Collatz algorithm. - -If `n` is even, return `n/2`. Otherwise, return `3n+1`. - -```js -const collatz = n => (n % 2 == 0 ? n / 2 : 3 * n + 1); -``` - -
    -Examples - -```js -collatz(8); // 4 -``` - -
    - -
    [⬆ Back to top](#table-of-contents) - - -### countVowels - -Retuns `number` of vowels in provided string. - -Use a regular expression to count the number of vowels `(A, E, I, O, U)` in a `string`. - -```js -const countVowels = str => (str.match(/[aeiou]/gi) || []).length; -``` - -
    -Examples - -```js -countVowels('foobar'); // 3 -countVowels('gym'); // 0 -``` - -
    - -
    [⬆ Back to top](#table-of-contents) - - -### factors - -Returns the array of factors of the given `num`. -If the second argument is set to `true` returns only the prime factors of `num`. -If `num` is `1` or `0` returns an empty array. -If `num` is less than `0` returns all the factors of `-int` together with their additive inverses. - -Use `Array.from()`, `Array.map()` and `Array.filter()` to find all the factors of `num`. -If given `num` is negative, use `Array.reduce()` to add the additive inverses to the array. -Return all results if `primes` is `false`, else determine and return only the prime factors using `isPrime` and `Array.filter()`. -Omit the second argument, `primes`, to return prime and non-prime factors by default. - -**Note**:- _Negative numbers are not considered prime._ - -```js -const factors = (num, primes = false) => { - const isPrime = num => { - const boundary = Math.floor(Math.sqrt(num)); - for (var i = 2; i <= boundary; i++) if (num % i === 0) return false; - return num >= 2; - }; - const isNeg = num < 0; - num = isNeg ? -num : num; - let array = Array.from({ length: num - 1 }) - .map((val, i) => (num % (i + 2) === 0 ? i + 2 : false)) - .filter(val => val); - if (isNeg) - array = array.reduce((acc, val) => { - acc.push(val); - acc.push(-val); - return acc; - }, []); - return primes ? array.filter(isPrime) : array; -}; -``` - -
    -Examples - -```js -factors(12); // [2,3,4,6,12] -factors(12, true); // [2,3] -factors(-12); // [2, -2, 3, -3, 4, -4, 6, -6, 12, -12] -factors(-12, true); // [2,3] -``` - -
    - -
    [⬆ Back to top](#table-of-contents) - - -### fibonacciCountUntilNum - -Returns the number of fibonnacci numbers up to `num`(`0` and `num` inclusive). - -Use a mathematical formula to calculate the number of fibonacci numbers until `num`. - -```js -const fibonacciCountUntilNum = num => - Math.ceil(Math.log(num * Math.sqrt(5) + 1 / 2) / Math.log((Math.sqrt(5) + 1) / 2)); -``` - -
    -Examples - -```js -fibonacciCountUntilNum(10); // 7 -``` - -
    - -
    [⬆ Back to top](#table-of-contents) - - -### binarySearch - -Use recursion. Similar to `Array.indexOf()` that finds the index of a value within an array. -The difference being this operation only works with sorted arrays which offers a major performance boost due to it's logarithmic nature when compared to a linear search or `Array.indexOf()`. - -Search a sorted array by repeatedly dividing the search interval in half. -Begin with an interval covering the whole array. -If the value of the search is less than the item in the middle of the interval, recurse into the lower half. Otherwise recurse into the upper half. -Repeatedly recurse until the value is found which is the mid or you've recursed to a point that is greater than the length which means the value doesn't exist and return `-1`. - -```js -const binarySearch = (arr, val, start = 0, end = arr.length - 1) => { - if (start > end) return -1; - const mid = Math.floor((start + end) / 2); - if (arr[mid] > val) return binarySearch(arr, val, start, mid - 1); - if (arr[mid] < val) return binarySearch(arr, val, mid + 1, end); - return mid; -} -``` - -
    -Examples - -```js -binarySearch([1, 4, 6, 7, 12, 13, 15, 18, 19, 20, 22, 24], 6); // 2 -binarySearch([1, 4, 6, 7, 12, 13, 15, 18, 19, 20, 22, 24], 21); // -1 -``` - -
    - -
    [⬆ Back to top](#table-of-contents) - - ### howManyTimes Returns the number of times `num` can be divided by `divisor` (integer or fractional) without getting a fractional answer. @@ -991,604 +251,6 @@ howManyTimes(100, -1); // Infinity
    [⬆ Back to top](#table-of-contents) -### isArmstrongNumber - -Checks if the given number is an Armstrong number or not. - -Convert the given number into an array of digits. Use the exponent operator (`**`) to get the appropriate power for each digit and sum them up. If the sum is equal to the number itself, return `true` otherwise `false`. - -```js -const isArmstrongNumber = digits => - (arr => arr.reduce((a, d) => a + parseInt(d) ** arr.length, 0) == digits)( - (digits + '').split('') - ); -``` - -
    -Examples - -```js -isArmstrongNumber(1634); // true -isArmstrongNumber(56); // false -``` - -
    - -
    [⬆ Back to top](#table-of-contents) - - -### quickSort - -QuickSort an Array (ascending sort by default). - -Use recursion. -Use `Array.filter` and spread operator (`...`) to create an array that all elements with values less than the pivot come before the pivot, and all elements with values greater than the pivot come after it. -If the parameter `desc` is truthy, return array sorts in descending order. - -```js -const quickSort = ([n, ...nums], desc) => - isNaN(n) - ? [] - : [ - ...quickSort(nums.filter(v => (desc ? v > n : v <= n)), desc), - n, - ...quickSort(nums.filter(v => (!desc ? v > n : v <= n)), desc) - ]; -``` - -
    -Examples - -```js -quickSort([4, 1, 3, 2]); // [1,2,3,4] -quickSort([4, 1, 3, 2], true); // [4,3,2,1] -``` - -
    - -
    [⬆ Back to top](#table-of-contents) - - -### removeVowels - -Returns all the vowels in a `str` replaced by `repl`. - -Use `String.replace()` with a regexp to replace all vowels in `str`. -Omot `repl` to use a default value of `''`. - -```js -const removeVowels = (str, repl = '') => str.replace(/[aeiou]/gi,repl); -``` - -
    -Examples - -```js -removeVowels("foobAr"); // "fbr" -removeVowels("foobAr","*"); // "f**b*r" -``` - -
    - -
    [⬆ Back to top](#table-of-contents) - - -### solveRPN - -Solves the given mathematical expression in [reverse polish notation](https://en.wikipedia.org/wiki/Reverse_Polish_notation). -Throws appropriate errors if there are unrecognized symbols or the expression is wrong. The valid operators are :- `+`,`-`,`*`,`/`,`^`,`**` (`^`&`**` are the exponential symbols and are same). This snippet does not supports any unary operators. - -Use a dictionary, `OPERATORS` to specify each operator's matching mathematical operation. -Use `String.replace()` with a regular expression to replace `^` with `**`, `String.split()` to tokenize the string and `Array.filter()` to remove empty tokens. -Use `Array.forEach()` to parse each `symbol`, evaluate it as a numeric value or operator and solve the mathematical expression. -Numeric values are converted to floating point numbers and pushed to a `stack`, while operators are evaluated using the `OPERATORS` dictionary and pop elements from the `stack` to apply operations. - -```js -const solveRPN = rpn => { - const OPERATORS = { - '*': (a, b) => a * b, - '+': (a, b) => a + b, - '-': (a, b) => a - b, - '/': (a, b) => a / b, - '**': (a, b) => a ** b - }; - const [stack, solve] = [ - [], - rpn - .replace(/\^/g, '**') - .split(/\s+/g) - .filter(el => !/\s+/.test(el) && el !== '') - ]; - solve.forEach(symbol => { - if (!isNaN(parseFloat(symbol)) && isFinite(symbol)) { - stack.push(symbol); - } else if (Object.keys(OPERATORS).includes(symbol)) { - const [a, b] = [stack.pop(), stack.pop()]; - stack.push(OPERATORS[symbol](parseFloat(b), parseFloat(a))); - } else { - throw `${symbol} is not a recognized symbol`; - } - }); - if (stack.length === 1) return stack.pop(); - else throw `${rpn} is not a proper RPN. Please check it and try again`; -}; -``` - -
    -Examples - -```js -solveRPN('15 7 1 1 + - / 3 * 2 1 1 + + -'); // 5 -solveRPN('2 3 ^'); // 8 -``` - -
    - -
    [⬆ Back to top](#table-of-contents) - - -### fibonacciUntilNum - -Generates an array, containing the Fibonacci sequence, up until the nth term. - -Create an empty array of the specific length, initializing the first two values (`0` and `1`). -Use `Array.reduce()` to add values into the array, using the sum of the last two values, except for the first two. -Uses a mathematical formula to calculate the length of the array required. - -```js -const fibonacciUntilNum = num => { - let n = Math.ceil(Math.log(num * Math.sqrt(5) + 1 / 2) / Math.log((Math.sqrt(5) + 1) / 2)); - return Array.from({ length: n }).reduce( - (acc, val, i) => acc.concat(i > 1 ? acc[i - 1] + acc[i - 2] : i), - [] - ); -}; -``` - -
    -Examples - -
    -Examples - -```js -fibonacciUntilNum(10); // [ 0, 1, 1, 2, 3, 5, 8 ] -``` - -
    - -
    [⬆ Back to top](#table-of-contents) - - -
    - -
    [⬆ Back to top](#table-of-contents) - - -### howManyTimes - -Returns the number of times `num` can be divided by `divisor` (integer or fractional) without getting a fractional answer. -Works for both negative and positive integers. - -If `divisor` is `-1` or `1` return `Infinity`. -If `divisor` is `-0` or `0` return `0`. -Otherwise, keep dividing `num` with `divisor` and incrementing `i`, while the result is an integer. -Return the number of times the loop was executed, `i`. - -```js -const howManyTimes = (num, divisor) => { - if (divisor === 1 || divisor === -1) return Infinity; - if (divisor === 0) return 0; - let i = 0; - while (Number.isInteger(num / divisor)) { - i++; - num = num / divisor; - } - return i; -}; -``` - -
    -Examples - -```js -howManyTimes(100, 2); // 2 -howManyTimes(100, 2.5); // 2 -howManyTimes(100, 0); // 0 -howManyTimes(100, -1); // Infinity -``` - -
    - -
    [⬆ Back to top](#table-of-contents) - - -### isArmstrongNumber - -Checks if the given number is an Armstrong number or not. - -Convert the given number into an array of digits. Use the exponent operator (`**`) to get the appropriate power for each digit and sum them up. If the sum is equal to the number itself, return `true` otherwise `false`. - -```js -const isArmstrongNumber = digits => - (arr => arr.reduce((a, d) => a + parseInt(d) ** arr.length, 0) == digits)( - (digits + '').split('') - ); -``` - -
    -Examples - -```js -isArmstrongNumber(1634); // true -isArmstrongNumber(56); // false -``` - -
    - -
    [⬆ Back to top](#table-of-contents) - - -### quickSort - -QuickSort an Array (ascending sort by default). - -Use recursion. -Use `Array.filter` and spread operator (`...`) to create an array that all elements with values less than the pivot come before the pivot, and all elements with values greater than the pivot come after it. -If the parameter `desc` is truthy, return array sorts in descending order. - -```js -const quickSort = ([n, ...nums], desc) => - isNaN(n) - ? [] - : [ - ...quickSort(nums.filter(v => (desc ? v > n : v <= n)), desc), - n, - ...quickSort(nums.filter(v => (!desc ? v > n : v <= n)), desc) - ]; -``` - -
    -Examples - -```js -quickSort([4, 1, 3, 2]); // [1,2,3,4] -quickSort([4, 1, 3, 2], true); // [4,3,2,1] -``` - -
    - -
    [⬆ Back to top](#table-of-contents) - - -### removeVowels - -Returns all the vowels in a `str` replaced by `repl`. - -Use `String.replace()` with a regexp to replace all vowels in `str`. -Omot `repl` to use a default value of `''`. - -```js -const removeVowels = (str, repl = '') => str.replace(/[aeiou]/gi,repl); -``` - -
    -Examples - -```js -removeVowels("foobAr"); // "fbr" -removeVowels("foobAr","*"); // "f**b*r" -``` - -
    - -
    [⬆ Back to top](#table-of-contents) - - -### solveRPN - -Solves the given mathematical expression in [reverse polish notation](https://en.wikipedia.org/wiki/Reverse_Polish_notation). -Throws appropriate errors if there are unrecognized symbols or the expression is wrong. The valid operators are :- `+`,`-`,`*`,`/`,`^`,`**` (`^`&`**` are the exponential symbols and are same). This snippet does not supports any unary operators. - -Use a dictionary, `OPERATORS` to specify each operator's matching mathematical operation. -Use `String.replace()` with a regular expression to replace `^` with `**`, `String.split()` to tokenize the string and `Array.filter()` to remove empty tokens. -Use `Array.forEach()` to parse each `symbol`, evaluate it as a numeric value or operator and solve the mathematical expression. -Numeric values are converted to floating point numbers and pushed to a `stack`, while operators are evaluated using the `OPERATORS` dictionary and pop elements from the `stack` to apply operations. - -```js -const solveRPN = rpn => { - const OPERATORS = { - '*': (a, b) => a * b, - '+': (a, b) => a + b, - '-': (a, b) => a - b, - '/': (a, b) => a / b, - '**': (a, b) => a ** b - }; - const [stack, solve] = [ - [], - rpn - .replace(/\^/g, '**') - .split(/\s+/g) - .filter(el => !/\s+/.test(el) && el !== '') - ]; - solve.forEach(symbol => { - if (!isNaN(parseFloat(symbol)) && isFinite(symbol)) { - stack.push(symbol); - } else if (Object.keys(OPERATORS).includes(symbol)) { - const [a, b] = [stack.pop(), stack.pop()]; - stack.push(OPERATORS[symbol](parseFloat(b), parseFloat(a))); - } else { - throw `${symbol} is not a recognized symbol`; - } - }); - if (stack.length === 1) return stack.pop(); - else throw `${rpn} is not a proper RPN. Please check it and try again`; -}; -``` - -
    -Examples - -```js -solveRPN('15 7 1 1 + - / 3 * 2 1 1 + + -'); // 5 -solveRPN('2 3 ^'); // 8 -``` - -
    - -
    [⬆ Back to top](#table-of-contents) - - -### fibonacciUntilNum - -Generates an array, containing the Fibonacci sequence, up until the nth term. - -Create an empty array of the specific length, initializing the first two values (`0` and `1`). -Use `Array.reduce()` to add values into the array, using the sum of the last two values, except for the first two. -Uses a mathematical formula to calculate the length of the array required. - -```js -const fibonacciUntilNum = num => { - let n = Math.ceil(Math.log(num * Math.sqrt(5) + 1 / 2) / Math.log((Math.sqrt(5) + 1) / 2)); - return Array.from({ length: n }).reduce( - (acc, val, i) => acc.concat(i > 1 ? acc[i - 1] + acc[i - 2] : i), - [] - ); -}; -``` - -
    -Examples - -
    -Examples - -```js -fibonacciUntilNum(10); // [ 0, 1, 1, 2, 3, 5, 8 ] -``` - -
    - -
    [⬆ Back to top](#table-of-contents) - - -
    - -
    [⬆ Back to top](#table-of-contents) - - -### howManyTimes - -Returns the number of times `num` can be divided by `divisor` (integer or fractional) without getting a fractional answer. -Works for both negative and positive integers. - -If `divisor` is `-1` or `1` return `Infinity`. -If `divisor` is `-0` or `0` return `0`. -Otherwise, keep dividing `num` with `divisor` and incrementing `i`, while the result is an integer. -Return the number of times the loop was executed, `i`. - -```js -const howManyTimes = (num, divisor) => { - if (divisor === 1 || divisor === -1) return Infinity; - if (divisor === 0) return 0; - let i = 0; - while (Number.isInteger(num / divisor)) { - i++; - num = num / divisor; - } - return i; -}; -``` - -
    -Examples - -```js -howManyTimes(100, 2); // 2 -howManyTimes(100, 2.5); // 2 -howManyTimes(100, 0); // 0 -howManyTimes(100, -1); // Infinity -``` - -
    - -
    [⬆ Back to top](#table-of-contents) - - -### isArmstrongNumber - -Checks if the given number is an Armstrong number or not. - -Convert the given number into an array of digits. Use the exponent operator (`**`) to get the appropriate power for each digit and sum them up. If the sum is equal to the number itself, return `true` otherwise `false`. - -```js -const isArmstrongNumber = digits => - (arr => arr.reduce((a, d) => a + parseInt(d) ** arr.length, 0) == digits)( - (digits + '').split('') - ); -``` - -
    -Examples - -```js -isArmstrongNumber(1634); // true -isArmstrongNumber(56); // false -``` - -
    - -
    [⬆ Back to top](#table-of-contents) - - -### quickSort - -QuickSort an Array (ascending sort by default). - -Use recursion. -Use `Array.filter` and spread operator (`...`) to create an array that all elements with values less than the pivot come before the pivot, and all elements with values greater than the pivot come after it. -If the parameter `desc` is truthy, return array sorts in descending order. - -```js -const quickSort = ([n, ...nums], desc) => - isNaN(n) - ? [] - : [ - ...quickSort(nums.filter(v => (desc ? v > n : v <= n)), desc), - n, - ...quickSort(nums.filter(v => (!desc ? v > n : v <= n)), desc) - ]; -``` - -
    -Examples - -```js -quickSort([4, 1, 3, 2]); // [1,2,3,4] -quickSort([4, 1, 3, 2], true); // [4,3,2,1] -``` - -
    - -
    [⬆ Back to top](#table-of-contents) - - -### removeVowels - -Returns all the vowels in a `str` replaced by `repl`. - -Use `String.replace()` with a regexp to replace all vowels in `str`. -Omot `repl` to use a default value of `''`. - -```js -const removeVowels = (str, repl = '') => str.replace(/[aeiou]/gi,repl); -``` - -
    -Examples - -```js -removeVowels("foobAr"); // "fbr" -removeVowels("foobAr","*"); // "f**b*r" -``` - -
    - -
    [⬆ Back to top](#table-of-contents) - - -### solveRPN - -Solves the given mathematical expression in [reverse polish notation](https://en.wikipedia.org/wiki/Reverse_Polish_notation). -Throws appropriate errors if there are unrecognized symbols or the expression is wrong. The valid operators are :- `+`,`-`,`*`,`/`,`^`,`**` (`^`&`**` are the exponential symbols and are same). This snippet does not supports any unary operators. - -Use a dictionary, `OPERATORS` to specify each operator's matching mathematical operation. -Use `String.replace()` with a regular expression to replace `^` with `**`, `String.split()` to tokenize the string and `Array.filter()` to remove empty tokens. -Use `Array.forEach()` to parse each `symbol`, evaluate it as a numeric value or operator and solve the mathematical expression. -Numeric values are converted to floating point numbers and pushed to a `stack`, while operators are evaluated using the `OPERATORS` dictionary and pop elements from the `stack` to apply operations. - -```js -const solveRPN = rpn => { - const OPERATORS = { - '*': (a, b) => a * b, - '+': (a, b) => a + b, - '-': (a, b) => a - b, - '/': (a, b) => a / b, - '**': (a, b) => a ** b - }; - const [stack, solve] = [ - [], - rpn - .replace(/\^/g, '**') - .split(/\s+/g) - .filter(el => !/\s+/.test(el) && el !== '') - ]; - solve.forEach(symbol => { - if (!isNaN(parseFloat(symbol)) && isFinite(symbol)) { - stack.push(symbol); - } else if (Object.keys(OPERATORS).includes(symbol)) { - const [a, b] = [stack.pop(), stack.pop()]; - stack.push(OPERATORS[symbol](parseFloat(b), parseFloat(a))); - } else { - throw `${symbol} is not a recognized symbol`; - } - }); - if (stack.length === 1) return stack.pop(); - else throw `${rpn} is not a proper RPN. Please check it and try again`; -}; -``` - -
    -Examples - -```js -solveRPN('15 7 1 1 + - / 3 * 2 1 1 + + -'); // 5 -solveRPN('2 3 ^'); // 8 -``` - -
    - -
    [⬆ Back to top](#table-of-contents) - - -### fibonacciUntilNum - -Generates an array, containing the Fibonacci sequence, up until the nth term. - -Create an empty array of the specific length, initializing the first two values (`0` and `1`). -Use `Array.reduce()` to add values into the array, using the sum of the last two values, except for the first two. -Uses a mathematical formula to calculate the length of the array required. - -```js -const fibonacciUntilNum = num => { - let n = Math.ceil(Math.log(num * Math.sqrt(5) + 1 / 2) / Math.log((Math.sqrt(5) + 1) / 2)); - return Array.from({ length: n }).reduce( - (acc, val, i) => acc.concat(i > 1 ? acc[i - 1] + acc[i - 2] : i), - [] - ); -}; -``` - -
    -Examples - -
    -Examples - -```js -fibonacciUntilNum(10); // [ 0, 1, 1, 2, 3, 5, 8 ] -``` - -
    - -
    [⬆ Back to top](#table-of-contents) - - -
    - -
    [⬆ Back to top](#table-of-contents) - - ### httpDelete Makes a `DELETE` request to the passed URL. @@ -1622,6 +284,189 @@ httpDelete('https://website.com/users/123', request => {
    [⬆ Back to top](#table-of-contents) +### collatz + +Applies the Collatz algorithm. + +If `n` is even, return `n/2`. Otherwise, return `3n+1`. + +```js +const collatz = n => (n % 2 == 0 ? n / 2 : 3 * n + 1); +``` + +
    +Examples + +```js +collatz(8); // 4 +``` + +
    + +
    [⬆ Back to top](#table-of-contents) + + +### isArmstrongNumber + +Checks if the given number is an Armstrong number or not. + +Convert the given number into an array of digits. Use the exponent operator (`**`) to get the appropriate power for each digit and sum them up. If the sum is equal to the number itself, return `true` otherwise `false`. + +```js +const isArmstrongNumber = digits => + (arr => arr.reduce((a, d) => a + parseInt(d) ** arr.length, 0) == digits)( + (digits + '').split('') + ); +``` + +
    +Examples + +```js +isArmstrongNumber(1634); // true +isArmstrongNumber(56); // false +``` + +
    + +
    [⬆ Back to top](#table-of-contents) + + +### JSONToDate + +Converts a JSON object to a date. + +Use `Date()`, to convert dates in JSON format to readable format (`dd/mm/yyyy`). + +```js +const JSONToDate = arr => { + const dt = new Date(parseInt(arr.toString().substr(6))); + return `${dt.getDate()}/${dt.getMonth() + 1}/${dt.getFullYear()}`; +}; +``` + +
    +Examples + +```js +JSONToDate(/Date(1489525200000)/); // "14/3/2017" +``` + +
    + +
    [⬆ Back to top](#table-of-contents) + + +### quickSort + +QuickSort an Array (ascending sort by default). + +Use recursion. +Use `Array.filter` and spread operator (`...`) to create an array that all elements with values less than the pivot come before the pivot, and all elements with values greater than the pivot come after it. +If the parameter `desc` is truthy, return array sorts in descending order. + +```js +const quickSort = ([n, ...nums], desc) => + isNaN(n) + ? [] + : [ + ...quickSort(nums.filter(v => (desc ? v > n : v <= n)), desc), + n, + ...quickSort(nums.filter(v => (!desc ? v > n : v <= n)), desc) + ]; +``` + +
    +Examples + +```js +quickSort([4, 1, 3, 2]); // [1,2,3,4] +quickSort([4, 1, 3, 2], true); // [4,3,2,1] +``` + +
    + +
    [⬆ Back to top](#table-of-contents) + + +### removeVowels + +Returns all the vowels in a `str` replaced by `repl`. + +Use `String.replace()` with a regexp to replace all vowels in `str`. +Omot `repl` to use a default value of `''`. + +```js +const removeVowels = (str, repl = '') => str.replace(/[aeiou]/gi,repl); +``` + +
    +Examples + +```js +removeVowels("foobAr"); // "fbr" +removeVowels("foobAr","*"); // "f**b*r" +``` + +
    + +
    [⬆ Back to top](#table-of-contents) + + +### solveRPN + +Solves the given mathematical expression in [reverse polish notation](https://en.wikipedia.org/wiki/Reverse_Polish_notation). +Throws appropriate errors if there are unrecognized symbols or the expression is wrong. The valid operators are :- `+`,`-`,`*`,`/`,`^`,`**` (`^`&`**` are the exponential symbols and are same). This snippet does not supports any unary operators. + +Use a dictionary, `OPERATORS` to specify each operator's matching mathematical operation. +Use `String.replace()` with a regular expression to replace `^` with `**`, `String.split()` to tokenize the string and `Array.filter()` to remove empty tokens. +Use `Array.forEach()` to parse each `symbol`, evaluate it as a numeric value or operator and solve the mathematical expression. +Numeric values are converted to floating point numbers and pushed to a `stack`, while operators are evaluated using the `OPERATORS` dictionary and pop elements from the `stack` to apply operations. + +```js +const solveRPN = rpn => { + const OPERATORS = { + '*': (a, b) => a * b, + '+': (a, b) => a + b, + '-': (a, b) => a - b, + '/': (a, b) => a / b, + '**': (a, b) => a ** b + }; + const [stack, solve] = [ + [], + rpn + .replace(/\^/g, '**') + .split(/\s+/g) + .filter(el => !/\s+/.test(el) && el !== '') + ]; + solve.forEach(symbol => { + if (!isNaN(parseFloat(symbol)) && isFinite(symbol)) { + stack.push(symbol); + } else if (Object.keys(OPERATORS).includes(symbol)) { + const [a, b] = [stack.pop(), stack.pop()]; + stack.push(OPERATORS[symbol](parseFloat(b), parseFloat(a))); + } else { + throw `${symbol} is not a recognized symbol`; + } + }); + if (stack.length === 1) return stack.pop(); + else throw `${rpn} is not a proper RPN. Please check it and try again`; +}; +``` + +
    +Examples + +```js +solveRPN('15 7 1 1 + - / 3 * 2 1 1 + + -'); // 5 +solveRPN('2 3 ^'); // 8 +``` + +
    + +
    [⬆ Back to top](#table-of-contents) + + ### httpPut Makes a `PUT` request to the passed URL. @@ -1658,177 +503,3 @@ httpPut('https://website.com/users/123', data, request => {
    [⬆ Back to top](#table-of-contents) - -### isArmstrongNumber - -Checks if the given number is an Armstrong number or not. - -Convert the given number into an array of digits. Use the exponent operator (`**`) to get the appropriate power for each digit and sum them up. If the sum is equal to the number itself, return `true` otherwise `false`. - -```js -const isArmstrongNumber = digits => - (arr => arr.reduce((a, d) => a + parseInt(d) ** arr.length, 0) == digits)( - (digits + '').split('') - ); -``` - -
    -Examples - -```js -isArmstrongNumber(1634); // true -isArmstrongNumber(56); // false -``` - -
    - -
    [⬆ Back to top](#table-of-contents) - - -### quickSort - -QuickSort an Array (ascending sort by default). - -Use recursion. -Use `Array.filter` and spread operator (`...`) to create an array that all elements with values less than the pivot come before the pivot, and all elements with values greater than the pivot come after it. -If the parameter `desc` is truthy, return array sorts in descending order. - -```js -const quickSort = ([n, ...nums], desc) => - isNaN(n) - ? [] - : [ - ...quickSort(nums.filter(v => (desc ? v > n : v <= n)), desc), - n, - ...quickSort(nums.filter(v => (!desc ? v > n : v <= n)), desc) - ]; -``` - -
    -Examples - -```js -quickSort([4, 1, 3, 2]); // [1,2,3,4] -quickSort([4, 1, 3, 2], true); // [4,3,2,1] -``` - -
    - -
    [⬆ Back to top](#table-of-contents) - - -### removeVowels - -Returns all the vowels in a `str` replaced by `repl`. - -Use `String.replace()` with a regexp to replace all vowels in `str`. -Omot `repl` to use a default value of `''`. - -```js -const removeVowels = (str, repl = '') => str.replace(/[aeiou]/gi,repl); -``` - -
    -Examples - -```js -removeVowels("foobAr"); // "fbr" -removeVowels("foobAr","*"); // "f**b*r" -``` - -
    - -
    [⬆ Back to top](#table-of-contents) - - -### solveRPN - -Solves the given mathematical expression in [reverse polish notation](https://en.wikipedia.org/wiki/Reverse_Polish_notation). -Throws appropriate errors if there are unrecognized symbols or the expression is wrong. The valid operators are :- `+`,`-`,`*`,`/`,`^`,`**` (`^`&`**` are the exponential symbols and are same). This snippet does not supports any unary operators. - -Use a dictionary, `OPERATORS` to specify each operator's matching mathematical operation. -Use `String.replace()` with a regular expression to replace `^` with `**`, `String.split()` to tokenize the string and `Array.filter()` to remove empty tokens. -Use `Array.forEach()` to parse each `symbol`, evaluate it as a numeric value or operator and solve the mathematical expression. -Numeric values are converted to floating point numbers and pushed to a `stack`, while operators are evaluated using the `OPERATORS` dictionary and pop elements from the `stack` to apply operations. - -```js -const solveRPN = rpn => { - const OPERATORS = { - '*': (a, b) => a * b, - '+': (a, b) => a + b, - '-': (a, b) => a - b, - '/': (a, b) => a / b, - '**': (a, b) => a ** b - }; - const [stack, solve] = [ - [], - rpn - .replace(/\^/g, '**') - .split(/\s+/g) - .filter(el => !/\s+/.test(el) && el !== '') - ]; - solve.forEach(symbol => { - if (!isNaN(parseFloat(symbol)) && isFinite(symbol)) { - stack.push(symbol); - } else if (Object.keys(OPERATORS).includes(symbol)) { - const [a, b] = [stack.pop(), stack.pop()]; - stack.push(OPERATORS[symbol](parseFloat(b), parseFloat(a))); - } else { - throw `${symbol} is not a recognized symbol`; - } - }); - if (stack.length === 1) return stack.pop(); - else throw `${rpn} is not a proper RPN. Please check it and try again`; -}; -``` - -
    -Examples - -```js -solveRPN('15 7 1 1 + - / 3 * 2 1 1 + + -'); // 5 -solveRPN('2 3 ^'); // 8 -``` - -
    - -
    [⬆ Back to top](#table-of-contents) - - -### howManyTimes - -Returns the number of times `num` can be divided by `divisor` (integer or fractional) without getting a fractional answer. -Works for both negative and positive integers. - -If `divisor` is `-1` or `1` return `Infinity`. -If `divisor` is `-0` or `0` return `0`. -Otherwise, keep dividing `num` with `divisor` and incrementing `i`, while the result is an integer. -Return the number of times the loop was executed, `i`. - -```js -const howManyTimes = (num, divisor) => { - if (divisor === 1 || divisor === -1) return Infinity; - if (divisor === 0) return 0; - let i = 0; - while (Number.isInteger(num / divisor)) { - i++; - num = num / divisor; - } - return i; -}; -``` - -
    -Examples - -```js -howManyTimes(100, 2); // 2 -howManyTimes(100, 2.5); // 2 -howManyTimes(100, 0); // 0 -howManyTimes(100, -1); // Infinity -``` - -
    - -
    [⬆ Back to top](#table-of-contents) - From 667f705ad715e31fd97d05e66ebd39b78e45c791 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Tue, 16 Jan 2018 16:42:17 +0200 Subject: [PATCH 09/13] Added a few type checking snippets from lodash --- snippets/isArrayBuffer.md | 13 +++++++++++++ snippets/isMap.md | 13 +++++++++++++ snippets/isRegExp.md | 13 +++++++++++++ snippets/isSet.md | 13 +++++++++++++ snippets/isTypedArray.md | 13 +++++++++++++ snippets/isWeakMap.md | 13 +++++++++++++ snippets/isWeakSet.md | 13 +++++++++++++ tag_database | 7 +++++++ 8 files changed, 98 insertions(+) create mode 100644 snippets/isArrayBuffer.md create mode 100644 snippets/isMap.md create mode 100644 snippets/isRegExp.md create mode 100644 snippets/isSet.md create mode 100644 snippets/isTypedArray.md create mode 100644 snippets/isWeakMap.md create mode 100644 snippets/isWeakSet.md diff --git a/snippets/isArrayBuffer.md b/snippets/isArrayBuffer.md new file mode 100644 index 000000000..7c28d4398 --- /dev/null +++ b/snippets/isArrayBuffer.md @@ -0,0 +1,13 @@ +### isArrayBuffer + +Checks if value is classified as a ArrayBuffer object. + +Use the `instanceof`operator to check if the provided value is a `ArrayBuffer` object. + +```js +const isArrayBuffer = val => val instanceof ArrayBuffer; +``` + +```js +isArrayBuffer(new ArrayBuffer()); // true +``` diff --git a/snippets/isMap.md b/snippets/isMap.md new file mode 100644 index 000000000..b3a202c5d --- /dev/null +++ b/snippets/isMap.md @@ -0,0 +1,13 @@ +### isMap + +Checks if value is classified as a Map object. + +Use the `instanceof`operator to check if the provided value is a `Map` object. + +```js +const isMap = val => val instanceof Map; +``` + +```js +isMap(new Map()); // true +``` diff --git a/snippets/isRegExp.md b/snippets/isRegExp.md new file mode 100644 index 000000000..db57bf587 --- /dev/null +++ b/snippets/isRegExp.md @@ -0,0 +1,13 @@ +### isRegExp + +Checks if value is classified as a RegExp object. + +Use the `instanceof`operator to check if the provided value is a `RegExp` object. + +```js +const isRegExp = val => val instanceof RegExp; +``` + +```js +isRegExp(/./g); // true +``` diff --git a/snippets/isSet.md b/snippets/isSet.md new file mode 100644 index 000000000..bddf3fcbb --- /dev/null +++ b/snippets/isSet.md @@ -0,0 +1,13 @@ +### isSet + +Checks if value is classified as a Set object. + +Use the `instanceof`operator to check if the provided value is a `Set` object. + +```js +const isSet = val => val instanceof Set; +``` + +```js +isSet(new Set()); // true +``` diff --git a/snippets/isTypedArray.md b/snippets/isTypedArray.md new file mode 100644 index 000000000..7b7416bf9 --- /dev/null +++ b/snippets/isTypedArray.md @@ -0,0 +1,13 @@ +### isTypedArray + +Checks if value is classified as a TypedArray object. + +Use the `instanceof`operator to check if the provided value is a `TypedArray` object. + +```js +const isTypedArray = val => val instanceof TypedArray; +``` + +```js +isTypedArray(new TypedArray()); // true +``` diff --git a/snippets/isWeakMap.md b/snippets/isWeakMap.md new file mode 100644 index 000000000..432f17f7e --- /dev/null +++ b/snippets/isWeakMap.md @@ -0,0 +1,13 @@ +### isWeakMap + +Checks if value is classified as a WeakMap object. + +Use the `instanceof`operator to check if the provided value is a `WeakMap` object. + +```js +const isWeakMap = val => val instanceof WeakMap; +``` + +```js +isWeakMap(new WeakMap()); // true +``` diff --git a/snippets/isWeakSet.md b/snippets/isWeakSet.md new file mode 100644 index 000000000..a72a1f0ac --- /dev/null +++ b/snippets/isWeakSet.md @@ -0,0 +1,13 @@ +### isWeakSet + +Checks if value is classified as a WeakSet object. + +Use the `instanceof`operator to check if the provided value is a `WeakSet` object. + +```js +const isWeakSet = val => val instanceof WeakSet; +``` + +```js +isWeakSet(new WeakSet()); // true +``` diff --git a/tag_database b/tag_database index 83883ba8a..34a1c6e92 100644 --- a/tag_database +++ b/tag_database @@ -81,24 +81,31 @@ intersection:array,math invertKeyValues:object isAbsoluteURL:string,utility,browser,url isArray:type,array +isArrayBuffer:type isArrayLike:type,array isBoolean:type isDivisible:math isEven:math isFunction:type,function isLowerCase:string,utility +isMap:type isNull:type isNumber:type,math isObject:type,object isPrime:math isPrimitive:type,function,array,string isPromiseLike:type,function,promise +isRegExp:type,regexp +isSet:type isSorted:array isString:type,string isSymbol:type isTravisCI:node +isTypedArray:type isUpperCase:string,utility isValidJSON:type,json +isWeakMap:type +isWeakSet:type join:array JSONToFile:node,json last:array From 4ae0e03b0e8031fafaaa29a768eefbd29488710d Mon Sep 17 00:00:00 2001 From: 30secondsofcode <30secondsofcode@gmail.com> Date: Tue, 16 Jan 2018 14:46:28 +0000 Subject: [PATCH 10/13] Travis build: 1262 --- README.md | 161 ++++++++++++++++++++++++++++++++++++++++++++++++ docs/index.html | 16 ++++- 2 files changed, 176 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 5135a2ee6..fc64e5408 100644 --- a/README.md +++ b/README.md @@ -324,17 +324,24 @@ average(1, 2, 3); * [`getType`](#gettype) * [`isArray`](#isarray) +* [`isArrayBuffer`](#isarraybuffer) * [`isArrayLike`](#isarraylike) * [`isBoolean`](#isboolean) * [`isFunction`](#isfunction) +* [`isMap`](#ismap) * [`isNull`](#isnull) * [`isNumber`](#isnumber) * [`isObject`](#isobject) * [`isPrimitive`](#isprimitive) * [`isPromiseLike`](#ispromiselike) +* [`isRegExp`](#isregexp) +* [`isSet`](#isset) * [`isString`](#isstring) * [`isSymbol`](#issymbol) +* [`isTypedArray`](#istypedarray) * [`isValidJSON`](#isvalidjson) +* [`isWeakMap`](#isweakmap) +* [`isWeakSet`](#isweakset) @@ -5150,6 +5157,28 @@ isArray([1]); // true
    [⬆ Back to top](#table-of-contents) +### isArrayBuffer + +Checks if value is classified as a ArrayBuffer object. + +Use the `instanceof`operator to check if the provided value is a `ArrayBuffer` object. + +```js +const isArrayBuffer = val => val instanceof ArrayBuffer; +``` + +
    +Examples + +```js +isArrayBuffer(new ArrayBuffer()); // true +``` + +
    + +
    [⬆ Back to top](#table-of-contents) + + ### isArrayLike Checks if the provided argument is array-like (i.e. is iterable). @@ -5226,6 +5255,28 @@ isFunction(x => x); // true
    [⬆ Back to top](#table-of-contents) +### isMap + +Checks if value is classified as a Map object. + +Use the `instanceof`operator to check if the provided value is a `Map` object. + +```js +const isMap = val => val instanceof Map; +``` + +
    +Examples + +```js +isMap(new Map()); // true +``` + +
    + +
    [⬆ Back to top](#table-of-contents) + + ### isNull Returns `true` if the specified value is `null`, `false` otherwise. @@ -5359,6 +5410,50 @@ isPromiseLike({}); // false
    [⬆ Back to top](#table-of-contents) +### isRegExp + +Checks if value is classified as a RegExp object. + +Use the `instanceof`operator to check if the provided value is a `RegExp` object. + +```js +const isRegExp = val => val instanceof RegExp; +``` + +
    +Examples + +```js +isRegExp(/./g); // true +``` + +
    + +
    [⬆ Back to top](#table-of-contents) + + +### isSet + +Checks if value is classified as a Set object. + +Use the `instanceof`operator to check if the provided value is a `Set` object. + +```js +const isSet = val => val instanceof Set; +``` + +
    +Examples + +```js +isSet(new Set()); // true +``` + +
    + +
    [⬆ Back to top](#table-of-contents) + + ### isString Checks if the given argument is a string. @@ -5403,6 +5498,28 @@ isSymbol(Symbol('x')); // true
    [⬆ Back to top](#table-of-contents) +### isTypedArray + +Checks if value is classified as a TypedArray object. + +Use the `instanceof`operator to check if the provided value is a `TypedArray` object. + +```js +const isTypedArray = val => val instanceof TypedArray; +``` + +
    +Examples + +```js +isTypedArray(new TypedArray()); // true +``` + +
    + +
    [⬆ Back to top](#table-of-contents) + + ### isValidJSON Checks if the provided argument is a valid JSON. @@ -5433,6 +5550,50 @@ isValidJSON(null); // true
    [⬆ Back to top](#table-of-contents) + +### isWeakMap + +Checks if value is classified as a WeakMap object. + +Use the `instanceof`operator to check if the provided value is a `WeakMap` object. + +```js +const isWeakMap = val => val instanceof WeakMap; +``` + +
    +Examples + +```js +isWeakMap(new WeakMap()); // true +``` + +
    + +
    [⬆ Back to top](#table-of-contents) + + +### isWeakSet + +Checks if value is classified as a WeakSet object. + +Use the `instanceof`operator to check if the provided value is a `WeakSet` object. + +```js +const isWeakSet = val => val instanceof WeakSet; +``` + +
    +Examples + +```js +isWeakSet(new WeakSet()); // true +``` + +
    + +
    [⬆ Back to top](#table-of-contents) + --- ## 🔧 Utility diff --git a/docs/index.html b/docs/index.html index 205434aa1..70ea19b9d 100644 --- a/docs/index.html +++ b/docs/index.html @@ -50,7 +50,7 @@ scrollToTop(); } }, false); - }

    logo 30 seconds of code Curated collection of useful JavaScript snippets that you can understand in 30 seconds or less.

     

    Adapter

    call

    Given a key and a set of arguments, call them when given a context. Primarily useful in composition.

    Use a closure to call a stored key with stored arguments.

    const call = (key, ...args) => context => context[key](...args);
    +      }

    logo 30 seconds of code Curated collection of useful JavaScript snippets that you can understand in 30 seconds or less.

     

    Adapter

    call

    Given a key and a set of arguments, call them when given a context. Primarily useful in composition.

    Use a closure to call a stored key with stored arguments.

    const call = (key, ...args) => context => context[key](...args);
     
    Promise.resolve([1, 2, 3])
       .then(call('map', x => 2 * x))
       .then(console.log); //[ 2, 4, 6 ]
    @@ -1166,6 +1166,8 @@ Foo.prototypeShow examples
    getType(new Set([1, 2, 3])); // 'set'
     

    isArray

    Checks if the given argument is an array.

    Use Array.isArray() to check if a value is classified as an array.

    const isArray = val => Array.isArray(val);
     
    isArray([1]); // true
    +

    isArrayBuffer

    Checks if value is classified as a ArrayBuffer object.

    Use the instanceofoperator to check if the provided value is a ArrayBuffer object.

    const isArrayBuffer = val => val instanceof ArrayBuffer;
    +
    isArrayBuffer(new ArrayBuffer()); // true
     

    isArrayLike

    Checks if the provided argument is array-like (i.e. is iterable).

    Use the spread operator (...) to check if the provided argument is iterable inside a try... catch block and the comma operator (,) to return the appropriate value.

    const isArrayLike = val => {
       try {
         return [...val], true;
    @@ -1182,6 +1184,8 @@ Foo.prototype📋 Copy to clipboard

    isFunction

    Checks if the given argument is a function.

    Use typeof to check if a value is classified as a function primitive.

    const isFunction = val => typeof val === 'function';
     
    isFunction('x'); // false
     isFunction(x => x); // true
    +

    isMap

    Checks if value is classified as a Map object.

    Use the instanceofoperator to check if the provided value is a Map object.

    const isMap = val => val instanceof Map;
    +
    isMap(new Map()); // true
     

    isNull

    Returns true if the specified value is null, false otherwise.

    Use the strict equality operator to check if the value and of val are equal to null.

    const isNull = val => val === null;
     
    isNull(null); // true
     

    isNumber

    Checks if the given argument is a number.

    Use typeof to check if a value is classified as a number primitive.

    const isNumber = val => typeof val === 'number';
    @@ -1212,10 +1216,16 @@ Foo.prototype// true
     isPromiseLike(null); // false
     isPromiseLike({}); // false
    +

    isRegExp

    Checks if value is classified as a RegExp object.

    Use the instanceofoperator to check if the provided value is a RegExp object.

    const isRegExp = val => val instanceof RegExp;
    +
    isRegExp(/./g); // true
    +

    isSet

    Checks if value is classified as a Set object.

    Use the instanceofoperator to check if the provided value is a Set object.

    const isSet = val => val instanceof Set;
    +
    isSet(new Set()); // true
     

    isString

    Checks if the given argument is a string.

    Use typeof to check if a value is classified as a string primitive.

    const isString = val => typeof val === 'string';
     
    isString('10'); // true
     

    isSymbol

    Checks if the given argument is a symbol.

    Use typeof to check if a value is classified as a symbol primitive.

    const isSymbol = val => typeof val === 'symbol';
     
    isSymbol(Symbol('x')); // true
    +

    isTypedArray

    Checks if value is classified as a TypedArray object.

    Use the instanceofoperator to check if the provided value is a TypedArray object.

    const isTypedArray = val => val instanceof TypedArray;
    +
    isTypedArray(new TypedArray()); // true
     

    isValidJSON

    Checks if the provided argument is a valid JSON.

    Use JSON.parse() and a try... catch block to check if the provided argument is a valid JSON.

    const isValidJSON = obj => {
       try {
         JSON.parse(obj);
    @@ -1227,6 +1237,10 @@ Foo.prototypeShow examples
    isValidJSON('{"name":"Adam","age":20}'); // true
     isValidJSON('{"name":"Adam",age:"20"}'); // false
     isValidJSON(null); // true
    +

    isWeakMap

    Checks if value is classified as a WeakMap object.

    Use the instanceofoperator to check if the provided value is a WeakMap object.

    const isWeakMap = val => val instanceof WeakMap;
    +
    isWeakMap(new WeakMap()); // true
    +

    isWeakSet

    Checks if value is classified as a WeakSet object.

    Use the instanceofoperator to check if the provided value is a WeakSet object.

    const isWeakSet = val => val instanceof WeakSet;
    +
    isWeakSet(new WeakSet()); // true
     

    Utility

    cloneRegExp

    Clones a regular expression.

    Use new RegExp(), RegExp.source and RegExp.flags to clone the given regular expression.

    const cloneRegExp = regExp => new RegExp(regExp.source, regExp.flags);
     
    const regExp = /lorem ipsum/gi;
     const regExp2 = cloneRegExp(regExp); // /lorem ipsum/gi
    
    From 447e3467db3a94f3e84d6572038e2e803614f3e1 Mon Sep 17 00:00:00 2001
    From: Angelos Chalaris 
    Date: Tue, 16 Jan 2018 16:50:21 +0200
    Subject: [PATCH 11/13] Add isNil and isUndefined
    
    ---
     snippets/isNil.md       | 14 ++++++++++++++
     snippets/isUndefined.md | 13 +++++++++++++
     tag_database            |  2 ++
     3 files changed, 29 insertions(+)
     create mode 100644 snippets/isNil.md
     create mode 100644 snippets/isUndefined.md
    
    diff --git a/snippets/isNil.md b/snippets/isNil.md
    new file mode 100644
    index 000000000..82618c36f
    --- /dev/null
    +++ b/snippets/isNil.md
    @@ -0,0 +1,14 @@
    +### isNil
    +
    +Returns `true` if the specified value is `null` or `undefined`, `false` otherwise.
    +
    +Use the strict equality operator to check if the value and of `val` are equal to `null` or `undefined`.
    +
    +```js
    +const isNil = val => val === undefined || val === null;
    +```
    +
    +```js
    +isNil(null); // true
    +isNil(undefined); // true
    +```
    diff --git a/snippets/isUndefined.md b/snippets/isUndefined.md
    new file mode 100644
    index 000000000..265b80e57
    --- /dev/null
    +++ b/snippets/isUndefined.md
    @@ -0,0 +1,13 @@
    +### isUndefined
    +
    +Returns `true` if the specified value is `undefined`, `false` otherwise.
    +
    +Use the strict equality operator to check if the value and of `val` are equal to `undefined`.
    +
    +```js
    +const isUndefined = val => val === undefined;
    +```
    +
    +```js
    +isUndefined(undefined); // true
    +```
    diff --git a/tag_database b/tag_database
    index 34a1c6e92..c25e9f023 100644
    --- a/tag_database
    +++ b/tag_database
    @@ -89,6 +89,7 @@ isEven:math
     isFunction:type,function
     isLowerCase:string,utility
     isMap:type
    +isNil:type
     isNull:type
     isNumber:type,math
     isObject:type,object
    @@ -102,6 +103,7 @@ isString:type,string
     isSymbol:type
     isTravisCI:node
     isTypedArray:type
    +isUndefined:type
     isUpperCase:string,utility
     isValidJSON:type,json
     isWeakMap:type
    
    From e8616e54fb4ddc94c8c7f5c1b8d94f6ab1d5285e Mon Sep 17 00:00:00 2001
    From: Angelos Chalaris 
    Date: Tue, 16 Jan 2018 17:09:39 +0200
    Subject: [PATCH 12/13] Add InitializeArrayWithRangeRight.md
    
    ---
     snippets/initializeArrayWithRange.md      |  2 +-
     snippets/initializeArrayWithRangeRight.md | 18 ++++++++++++++++++
     tag_database                              |  1 +
     3 files changed, 20 insertions(+), 1 deletion(-)
     create mode 100644 snippets/initializeArrayWithRangeRight.md
    
    diff --git a/snippets/initializeArrayWithRange.md b/snippets/initializeArrayWithRange.md
    index 228c6fcaf..f5f9f435a9 100644
    --- a/snippets/initializeArrayWithRange.md
    +++ b/snippets/initializeArrayWithRange.md
    @@ -1,6 +1,6 @@
     ### initializeArrayWithRange
     
    -Initializes an array containing the numbers in the specified range where `start` and `end` are inclusive with there common difference `step`.
    +Initializes an array containing the numbers in the specified range where `start` and `end` are inclusive with their common difference `step`.
     
     Use `Array.from(Math.ceil((end+1-start)/step))` to create an array of the desired length(the amounts of elements is equal to `(end-start)/step` or `(end+1-start)/step` for inclusive end), `Array.map()` to fill with the desired values in a range.
     You can omit `start` to use a default value of `0`.
    diff --git a/snippets/initializeArrayWithRangeRight.md b/snippets/initializeArrayWithRangeRight.md
    new file mode 100644
    index 000000000..0b73c0197
    --- /dev/null
    +++ b/snippets/initializeArrayWithRangeRight.md
    @@ -0,0 +1,18 @@
    +### initializeArrayWithRangeRight
    +
    +Initializes an array containing the numbers in the specified range (in reverse) where `start` and `end` are inclusive with their common difference `step`.
    +
    +Use `Array.from(Math.ceil((end+1-start)/step))` to create an array of the desired length(the amounts of elements is equal to `(end-start)/step` or `(end+1-start)/step` for inclusive end), `Array.map()` to fill with the desired values in a range.
    +You can omit `start` to use a default value of `0`.
    +You can omit `step` to use a default value of `1`.
    +
    +```js
    +const initializeArrayWithRangeRight = (end, start = 0, step = 1) =>
    +  Array.from({ length: Math.ceil((end + 1 - start) / step) }).map((v, i, arr) => (arr.length - i - 1) * step + start);
    +```
    +
    +```js
    +initializeArrayWithRangeRight(5); // [5,4,3,2,1,0]
    +initializeArrayWithRangeRight(7, 3); // [7,6,5,4,3]
    +initializeArrayWithRangeRight(9, 0, 2); // [8,6,4,2,0]
    +```
    diff --git a/tag_database b/tag_database
    index c25e9f023..cc70b1ddf 100644
    --- a/tag_database
    +++ b/tag_database
    @@ -75,6 +75,7 @@ indexOfAll:array
     initial:array
     initialize2DArray:array
     initializeArrayWithRange:array,math
    +initializeArrayWithRangeRight:array,math
     initializeArrayWithValues:array,math
     inRange:math
     intersection:array,math
    
    From 644c2d36fc494e8494c56306c936be086f6757e9 Mon Sep 17 00:00:00 2001
    From: 30secondsofcode <30secondsofcode@gmail.com>
    Date: Tue, 16 Jan 2018 15:14:29 +0000
    Subject: [PATCH 13/13] Travis build: 1265
    
    ---
     README.md                                 | 79 ++++++++++++++++++++++-
     docs/index.html                           | 16 ++++-
     snippets/initializeArrayWithRangeRight.md |  4 +-
     3 files changed, 95 insertions(+), 4 deletions(-)
    
    diff --git a/README.md b/README.md
    index fc64e5408..b3607ac90 100644
    --- a/README.md
    +++ b/README.md
    @@ -112,6 +112,7 @@ average(1, 2, 3);
     * [`initial`](#initial)
     * [`initialize2DArray`](#initialize2darray)
     * [`initializeArrayWithRange`](#initializearraywithrange)
    +* [`initializeArrayWithRangeRight`](#initializearraywithrangeright)
     * [`initializeArrayWithValues`](#initializearraywithvalues)
     * [`intersection`](#intersection)
     * [`isSorted`](#issorted)
    @@ -329,6 +330,7 @@ average(1, 2, 3);
     * [`isBoolean`](#isboolean)
     * [`isFunction`](#isfunction)
     * [`isMap`](#ismap)
    +* [`isNil`](#isnil)
     * [`isNull`](#isnull)
     * [`isNumber`](#isnumber)
     * [`isObject`](#isobject)
    @@ -339,6 +341,7 @@ average(1, 2, 3);
     * [`isString`](#isstring)
     * [`isSymbol`](#issymbol)
     * [`isTypedArray`](#istypedarray)
    +* [`isUndefined`](#isundefined)
     * [`isValidJSON`](#isvalidjson)
     * [`isWeakMap`](#isweakmap)
     * [`isWeakSet`](#isweakset)
    @@ -1024,7 +1027,7 @@ initialize2DArray(2, 2, 0); // [[0,0], [0,0]]
     
     ### initializeArrayWithRange
     
    -Initializes an array containing the numbers in the specified range where `start` and `end` are inclusive with there common difference `step`.
    +Initializes an array containing the numbers in the specified range where `start` and `end` are inclusive with their common difference `step`.
     
     Use `Array.from(Math.ceil((end+1-start)/step))` to create an array of the desired length(the amounts of elements is equal to `(end-start)/step` or `(end+1-start)/step` for inclusive end), `Array.map()` to fill with the desired values in a range.
     You can omit `start` to use a default value of `0`.
    @@ -1049,6 +1052,35 @@ initializeArrayWithRange(9, 0, 2); // [0,2,4,6,8]
     
    [⬆ Back to top](#table-of-contents) +### initializeArrayWithRangeRight + +Initializes an array containing the numbers in the specified range (in reverse) where `start` and `end` are inclusive with their common difference `step`. + +Use `Array.from(Math.ceil((end+1-start)/step))` to create an array of the desired length(the amounts of elements is equal to `(end-start)/step` or `(end+1-start)/step` for inclusive end), `Array.map()` to fill with the desired values in a range. +You can omit `start` to use a default value of `0`. +You can omit `step` to use a default value of `1`. + +```js +const initializeArrayWithRangeRight = (end, start = 0, step = 1) => + Array.from({ length: Math.ceil((end + 1 - start) / step) }).map( + (v, i, arr) => (arr.length - i - 1) * step + start + ); +``` + +
    +Examples + +```js +initializeArrayWithRangeRight(5); // [5,4,3,2,1,0] +initializeArrayWithRangeRight(7, 3); // [7,6,5,4,3] +initializeArrayWithRangeRight(9, 0, 2); // [8,6,4,2,0] +``` + +
    + +
    [⬆ Back to top](#table-of-contents) + + ### initializeArrayWithValues Initializes and fills an array with the specified values. @@ -5277,6 +5309,29 @@ isMap(new Map()); // true
    [⬆ Back to top](#table-of-contents) +### isNil + +Returns `true` if the specified value is `null` or `undefined`, `false` otherwise. + +Use the strict equality operator to check if the value and of `val` are equal to `null` or `undefined`. + +```js +const isNil = val => val === undefined || val === null; +``` + +
    +Examples + +```js +isNil(null); // true +isNil(undefined); // true +``` + +
    + +
    [⬆ Back to top](#table-of-contents) + + ### isNull Returns `true` if the specified value is `null`, `false` otherwise. @@ -5520,6 +5575,28 @@ isTypedArray(new TypedArray()); // true
    [⬆ Back to top](#table-of-contents) +### isUndefined + +Returns `true` if the specified value is `undefined`, `false` otherwise. + +Use the strict equality operator to check if the value and of `val` are equal to `undefined`. + +```js +const isUndefined = val => val === undefined; +``` + +
    +Examples + +```js +isUndefined(undefined); // true +``` + +
    + +
    [⬆ Back to top](#table-of-contents) + + ### isValidJSON Checks if the provided argument is a valid JSON. diff --git a/docs/index.html b/docs/index.html index 70ea19b9d..35d97f198 100644 --- a/docs/index.html +++ b/docs/index.html @@ -50,7 +50,7 @@ scrollToTop(); } }, false); - }

    logo 30 seconds of code Curated collection of useful JavaScript snippets that you can understand in 30 seconds or less.

     

    Adapter

    call

    Given a key and a set of arguments, call them when given a context. Primarily useful in composition.

    Use a closure to call a stored key with stored arguments.

    const call = (key, ...args) => context => context[key](...args);
    +      }

    logo 30 seconds of code Curated collection of useful JavaScript snippets that you can understand in 30 seconds or less.

     

    Adapter

    call

    Given a key and a set of arguments, call them when given a context. Primarily useful in composition.

    Use a closure to call a stored key with stored arguments.

    const call = (key, ...args) => context => context[key](...args);
     
    Promise.resolve([1, 2, 3])
       .then(call('map', x => 2 * x))
       .then(console.log); //[ 2, 4, 6 ]
    @@ -161,11 +161,18 @@ Object.assig
     

    initialize2DArray

    Initializes a 2D array of given width and height and value.

    Use Array.map() to generate h rows where each is a new array of size w initialize with value. If the value is not provided, default to null.

    const initialize2DArray = (w, h, val = null) =>
       Array.from({ length: h }).map(() => Array.from({ length: w }).fill(val));
     
    initialize2DArray(2, 2, 0); // [[0,0], [0,0]]
    -

    initializeArrayWithRange

    Initializes an array containing the numbers in the specified range where start and end are inclusive with there common difference step.

    Use Array.from(Math.ceil((end+1-start)/step)) to create an array of the desired length(the amounts of elements is equal to (end-start)/step or (end+1-start)/step for inclusive end), Array.map() to fill with the desired values in a range. You can omit start to use a default value of 0. You can omit step to use a default value of 1.

    const initializeArrayWithRange = (end, start = 0, step = 1) =>
    +

    initializeArrayWithRange

    Initializes an array containing the numbers in the specified range where start and end are inclusive with their common difference step.

    Use Array.from(Math.ceil((end+1-start)/step)) to create an array of the desired length(the amounts of elements is equal to (end-start)/step or (end+1-start)/step for inclusive end), Array.map() to fill with the desired values in a range. You can omit start to use a default value of 0. You can omit step to use a default value of 1.

    const initializeArrayWithRange = (end, start = 0, step = 1) =>
       Array.from({ length: Math.ceil((end + 1 - start) / step) }).map((v, i) => i * step + start);
     
    initializeArrayWithRange(5); // [0,1,2,3,4,5]
     initializeArrayWithRange(7, 3); // [3,4,5,6,7]
     initializeArrayWithRange(9, 0, 2); // [0,2,4,6,8]
    +

    initializeArrayWithRangeRight

    Initializes an array containing the numbers in the specified range (in reverse) where start and end are inclusive with their common difference step.

    Use Array.from(Math.ceil((end+1-start)/step)) to create an array of the desired length(the amounts of elements is equal to (end-start)/step or (end+1-start)/step for inclusive end), Array.map() to fill with the desired values in a range. You can omit start to use a default value of 0. You can omit step to use a default value of 1.

    const initializeArrayWithRangeRight = (end, start = 0, step = 1) =>
    +  Array.from({ length: Math.ceil((end + 1 - start) / step) }).map(
    +    (v, i, arr) => (arr.length - i - 1) * step + start
    +  );
    +
    initializeArrayWithRangeRight(5); // [5,4,3,2,1,0]
    +initializeArrayWithRangeRight(7, 3); // [7,6,5,4,3]
    +initializeArrayWithRangeRight(9, 0, 2); // [8,6,4,2,0]
     

    initializeArrayWithValues

    Initializes and fills an array with the specified values.

    Use Array(n) to create an array of the desired length, fill(v) to fill it with the desired values. You can omit val to use a default value of 0.

    const initializeArrayWithValues = (n, val = 0) => Array(n).fill(val);
     
    initializeArrayWithValues(5, 2); // [2,2,2,2,2]
     

    intersection

    Returns a list of elements that exist in both arrays.

    Create a Set from b, then use Array.filter() on a to only keep values contained in b.

    const intersection = (a, b) => {
    @@ -1186,6 +1193,9 @@ Foo.prototypeisFunction(x => x); // true
     

    isMap

    Checks if value is classified as a Map object.

    Use the instanceofoperator to check if the provided value is a Map object.

    const isMap = val => val instanceof Map;
     
    isMap(new Map()); // true
    +

    isNil

    Returns true if the specified value is null or undefined, false otherwise.

    Use the strict equality operator to check if the value and of val are equal to null or undefined.

    const isNil = val => val === undefined || val === null;
    +
    isNil(null); // true
    +isNil(undefined); // true
     

    isNull

    Returns true if the specified value is null, false otherwise.

    Use the strict equality operator to check if the value and of val are equal to null.

    const isNull = val => val === null;
     
    isNull(null); // true
     

    isNumber

    Checks if the given argument is a number.

    Use typeof to check if a value is classified as a number primitive.

    const isNumber = val => typeof val === 'number';
    @@ -1226,6 +1236,8 @@ Foo.prototypeShow examples
    isSymbol(Symbol('x')); // true
     

    isTypedArray

    Checks if value is classified as a TypedArray object.

    Use the instanceofoperator to check if the provided value is a TypedArray object.

    const isTypedArray = val => val instanceof TypedArray;
     
    isTypedArray(new TypedArray()); // true
    +

    isUndefined

    Returns true if the specified value is undefined, false otherwise.

    Use the strict equality operator to check if the value and of val are equal to undefined.

    const isUndefined = val => val === undefined;
    +
    isUndefined(undefined); // true
     

    isValidJSON

    Checks if the provided argument is a valid JSON.

    Use JSON.parse() and a try... catch block to check if the provided argument is a valid JSON.

    const isValidJSON = obj => {
       try {
         JSON.parse(obj);
    diff --git a/snippets/initializeArrayWithRangeRight.md b/snippets/initializeArrayWithRangeRight.md
    index 0b73c0197..608352c4d 100644
    --- a/snippets/initializeArrayWithRangeRight.md
    +++ b/snippets/initializeArrayWithRangeRight.md
    @@ -8,7 +8,9 @@ You can omit `step` to use a default value of `1`.
     
     ```js
     const initializeArrayWithRangeRight = (end, start = 0, step = 1) =>
    -  Array.from({ length: Math.ceil((end + 1 - start) / step) }).map((v, i, arr) => (arr.length - i - 1) * step + start);
    +  Array.from({ length: Math.ceil((end + 1 - start) / step) }).map(
    +    (v, i, arr) => (arr.length - i - 1) * step + start
    +  );
     ```
     
     ```js