diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 1f302a060..80717b4fd 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -4,7 +4,7 @@ ## [FEATURE] _REPLACE THIS WITH A BRIEF SUMMARY OF THE SUGGESTED SNIPPET_ -**Category:** +**Category:** ### Description diff --git a/.gitignore b/.gitignore index 6f177e3db..1672226d8 100644 --- a/.gitignore +++ b/.gitignore @@ -3,5 +3,4 @@ currentSnippet\.js *.md.temp.js .idea test.sh -dist/ test/ diff --git a/.travis.yml b/.travis.yml index 7b3a3486c..ffb9c3da1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,6 +12,7 @@ script: - npm run linter - npm run builder - npm run webber +- npm run module after_success: - chmod +x .travis/push.sh - .travis/push.sh diff --git a/.travis/push.sh b/.travis/push.sh index ac6939000..38e97512b 100755 --- a/.travis/push.sh +++ b/.travis/push.sh @@ -6,10 +6,16 @@ setup_git() { commit_website_files() { if [ $TRAVIS_EVENT_TYPE != "pull_request" ]; then if [ $TRAVIS_BRANCH == "master" ]; then - echo "Commiting to master branch..." + echo "Committing to master branch..." git checkout master git add * - git commit --message "Travis build: $TRAVIS_BUILD_NUMBER [ci skip]" + if [ $TRAVIS_EVENT_TYPE == "cron" ]; then + git commit --message "Travis build: $TRAVIS_BUILD_NUMBER [cron]" + elif [ $TRAVIS_EVENT_TYPE == "api" ]; then + git commit --message "Travis build: $TRAVIS_BUILD_NUMBER [custom]" + else + git commit --message "Travis build: $TRAVIS_BUILD_NUMBER" + fi fi fi } diff --git a/COLLABORATING.md b/COLLABORATING.md index fdf6ab673..a38c4d52d 100644 --- a/COLLABORATING.md +++ b/COLLABORATING.md @@ -14,7 +14,7 @@ As a member of the team that manages **30 seconds of code**, you have the follow ## Guidelines for merging pull requests and making changes to the project - **[Usual guidelines](https://github.com/Chalarangelo/30-seconds-of-code/blob/master/CONTRIBUTING.md) apply.** Make sure to follow them, like everybody else. -- **For a pull request to be considered ready to merge, there should be at least 2 (preferrably 3) reviews approving it for merge.** There are, however, certain exceptions: +- **For a pull request to be considered ready to merge, there should be at least 2 (preferably 3) reviews approving it for merge.** There are, however, certain exceptions: - **If a pull request only fixes typos**, there is no need to wait for a second reviewer (unless you are not absolutely certain these were not typos in the first place). - **If a pull request only clarifies a snippet's description or enforces the styleguide for an existng snippet**, you might be able to merge it without getting a second reviewer to review it, but only if you are absolutely certain about it. - **Make sure pull requests pass the Travis CI build**, otherwise try and find out what's wrong and inform the author of the pull request. diff --git a/README.md b/README.md index 2e0f09565..df585e098 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,9 @@ ![Logo](/logo.png) # 30 seconds of code -[![License](https://img.shields.io/badge/license-CC0--1.0-blue.svg)](https://github.com/Chalarangelo/30-seconds-of-code/blob/master/LICENSE) [![Gitter chat](https://img.shields.io/badge/chat-on%20gitter-4FB999.svg)](https://gitter.im/30-seconds-of-code/Lobby) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](http://makeapullrequest.com) [![Travis Build](https://travis-ci.org/Chalarangelo/30-seconds-of-code.svg?branch=master)](https://travis-ci.org/Chalarangelo/30-seconds-of-code) [![Insight.io](https://img.shields.io/badge/insight.io-Ready-brightgreen.svg)](https://insight.io/github.com/Chalarangelo/30-seconds-of-code/tree/master/?source=0) [![js-semistandard-style](https://img.shields.io/badge/code%20style-semistandard-brightgreen.svg)](https://github.com/Flet/semistandard) + +[![License](https://img.shields.io/badge/license-CC0--1.0-blue.svg)](https://github.com/Chalarangelo/30-seconds-of-code/blob/master/LICENSE) [![Gitter chat](https://img.shields.io/badge/chat-on%20gitter-4FB999.svg)](https://gitter.im/30-seconds-of-code/Lobby) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](http://makeapullrequest.com) [![Travis Build](https://travis-ci.org/Chalarangelo/30-seconds-of-code.svg?branch=master)](https://travis-ci.org/Chalarangelo/30-seconds-of-code) [![Insight.io](https://img.shields.io/badge/insight.io-Ready-brightgreen.svg)](https://insight.io/github.com/Chalarangelo/30-seconds-of-code/tree/master/?source=0) [![js-semistandard-style](https://img.shields.io/badge/code%20style-semistandard-brightgreen.svg)](https://github.com/Flet/semistandard) [![ProductHunt](https://img.shields.io/badge/producthunt-vote-orange.svg)](https://www.producthunt.com/posts/30-seconds-of-code) + > Curated collection of useful Javascript snippets that you can understand in 30 seconds or less. @@ -11,7 +13,7 @@ - Snippets are written in ES6, use the [Babel transpiler](https://babeljs.io/) to ensure backwards-compatibility. - You can import these snippets into your text editor of choice (VSCode, Atom, Sublime) using the files found in [this repo](https://github.com/Rob-Rychs/30-seconds-of-code-texteditorsnippets). - You can import these snippets into Alfred 3, using [this file](https://github.com/lslvxy/30-seconds-of-code-alfredsnippets). -- You can find a package with all the snippets on [npm](https://www.npmjs.com/package/tsoc). Bear in mind that most of these snippets are not production-ready. +- You can find a package with all the snippets on [npm](https://www.npmjs.com/package/30-seconds-of-code). Bear in mind that most of these snippets are not production-ready. ## Table of Contents @@ -100,6 +102,7 @@ * [`httpsRedirect`](#httpsredirect) * [`onUserInputChange`](#onuserinputchange) * [`redirect`](#redirect) +* [`runAsync`](#runasync) * [`scrollToTop`](#scrolltotop) * [`setStyle`](#setstyle) * [`show`](#show) @@ -129,8 +132,10 @@ * [`chainAsync`](#chainasync) * [`compose`](#compose) * [`curry`](#curry) +* [`defer`](#defer) * [`functionName`](#functionname) * [`memoize`](#memoize) +* [`once`](#once) * [`runPromisesInSeries`](#runpromisesinseries) * [`sleep`](#sleep) @@ -168,9 +173,7 @@ * [`isEven`](#iseven) * [`isPrime`](#isprime) * [`lcm`](#lcm) -* [`max`](#max) * [`median`](#median) -* [`min`](#min) * [`percentile`](#percentile) * [`powerset`](#powerset) * [`primes`](#primes) @@ -280,6 +283,17 @@ +### _Uncategorized_ + +
+View contents + +* [`geometricProgression`](#geometricprogression) +* [`maxN`](#maxn) +* [`minN`](#minn) + +
+ --- ## 🔌 Adapter @@ -853,14 +867,15 @@ 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. +Initializes an array containing the numbers in the specified range where `start` and `end` are inclusive with there common difference `step`. -Use `Array((end + 1) - start)` to create an array of the desired length, `Array.map()` to fill with the desired values in a range. +Use `Array(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 initializeArrayWithRange = (end, start = 0) => - Array.from({ length: end + 1 - start }).map((v, i) => i + start); +const initializeArrayWithRange = (end, start = 0, step = 1) => + Array.from({ length: Math.ceil((end + 1 - start) / step) }).map((v, i) => i * step + start); ```
@@ -869,6 +884,7 @@ const initializeArrayWithRange = (end, start = 0) => ```js 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] ```
@@ -1354,7 +1370,7 @@ sampleSize([1, 2, 3], 4); // [2,3,1] Randomizes the order of the values of an array, returning a new array. -Uses the Fisher-Yates algoritm to reorder the elements of the array, based on the [Lodash implementation](https://github.com/lodash/lodash/blob/b2ea6b1cd251796dcb5f9700c4911a7b6223920b/shuffle.js), but as a pure function. +Uses the Fisher-Yates algorithm to reorder the elements of the array, based on the [Lodash implementation](https://github.com/lodash/lodash/blob/b2ea6b1cd251796dcb5f9700c4911a7b6223920b/shuffle.js), but as a pure function. ```js const shuffle = ([...arr]) => { @@ -1974,6 +1990,66 @@ redirect('https://google.com');
[⬆ Back to top](#table-of-contents) +### runAsync + +Runs a function in a separate thread by using a [Web Worker](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers), allowing long running functions to not block the UI. + +Create a new `Worker` using a `Blob` object URL, the contents of which should be the stringified version of the supplied function. +Immediately post the return value of calling the function back. +Return a promise, listening for `onmessage` and `onerror` events and resolving the data posted back from the worker, or throwing an error. + +```js +const runAsync = fn => { + const blob = ` + var fn = ${fn.toString()}; + this.postMessage(fn()); + `; + const worker = new Worker( + URL.createObjectURL(new Blob([blob]), { + type: 'application/javascript; charset=utf-8' + }) + ); + return new Promise((res, rej) => { + worker.onmessage = ({ data }) => { + res(data), worker.terminate(); + }; + worker.onerror = err => { + rej(err), worker.terminate(); + }; + }); +}; +``` + +
+Examples + +```js +const longRunningFunction = () => { + let result = 0; + for (var i = 0; i < 1000; i++) { + for (var j = 0; j < 700; j++) { + for (var k = 0; k < 300; k++) { + result = result + i + j + k; + } + } + } + return result; +}; + +// NOTE: Since the function is running in a different context, closures are not supported. +// The function supplied to `runAsync` gets stringified, so everything becomes literal. +// All variables and functions must be defined inside. +runAsync(longRunningFunction).then(console.log); // 209685000000 +runAsync(() => 10 ** 3).then(console.log); // 1000 +let outsideVariable = 50; +runAsync(() => typeof outsideVariable).then(console.log); // 'undefined' +``` + +
+ +
[⬆ Back to top](#table-of-contents) + + ### scrollToTop Smooth-scrolls to the top of the page. @@ -2317,6 +2393,34 @@ curry(Math.min, 3)(10)(50)(2); // 2
[⬆ Back to top](#table-of-contents) +### defer + +Defers invoking a function until the current call stack has cleared. + +Use `setTimeout()` with a timeout of 1ms to add a new event to the browser event queue and allow the rendering engine to complete its work. Use the spread (`...`) operator to supply the function with an arbitrary number of arguments. + +```js +const defer = (fn, ...args) => setTimeout(fn, 1, ...args); +``` + +
+Examples + +```js +// Example A: +defer(console.log, 'a'), console.log('b'); // logs 'b' then 'a' + +// Example B: +document.querySelector('#someElement').innerHTML = 'Hello'; +longRunningFunction(); // the browser will not update the HTML until this has finished +defer(longRunningFunction); // the browser will update the HTML then run the function +``` + +
+ +
[⬆ Back to top](#table-of-contents) + + ### functionName Logs the name of a function. @@ -2368,6 +2472,39 @@ anagramsCached('javascript'); // returns virtually instantly since it's now cach
[⬆ Back to top](#table-of-contents) +### once + +Ensures a function is called only once. + +Utilizing a closure, use a flag, `called`, and set it to `true` once the function is called for the first time, preventing it from being called again. In order to allow the function to have its `this` context changed (such as in an event listener), the `function` keyword must be used, and the supplied function must have the context applied. +Allow the function to be supplied with an arbitrary number of arguments using the rest/spread (`...`) operator. + +```js +const once = fn => { + let called = false; + return function(...args) { + if (called) return; + called = true; + return fn.apply(this, args); + }; +}; +``` + +
+Examples + +```js +const startApp = function(event) { + console.log(this, event); // document.body, MouseEvent +}; +document.body.addEventListener('click', once(startApp)); // only runs `startApp` once upon click +``` + +
+ +
[⬆ Back to top](#table-of-contents) + + ### runPromisesInSeries Runs an array of promises in series. @@ -2914,28 +3051,6 @@ lcm([1, 3, 4], 5); // 60
[⬆ Back to top](#table-of-contents) -### max - -Returns the maximum value out of two or more numbers/arrays. - -Use `Math.max()` combined with the spread operator (`...`) to get the maximum value in the array. - -```js -const max = (...arr) => Math.max(...[].concat(...arr)); -``` - -
-Examples - -```js -max([10, 1, 5]); // 10 -``` - -
- -
[⬆ Back to top](#table-of-contents) - - ### median Returns the median of an array of numbers. @@ -2964,28 +3079,6 @@ median([0, 10, -2, 7]); // 3.5
[⬆ Back to top](#table-of-contents) -### min - -Returns the minimum value in an array. - -Use `Math.min()` combined with the spread operator (`...`) to get the minimum value in the array. - -```js -const min = arr => Math.min(...[].concat(...arr)); -``` - -
-Examples - -```js -min([10, 1, 5]); // 1 -``` - -
- -
[⬆ Back to top](#table-of-contents) - - ### percentile Uses the percentile formula to calculate how many numbers in the given array are less or equal to the given value. @@ -3129,7 +3222,7 @@ round(1.005, 2); // 1.01 ### 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. +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. @@ -3216,7 +3309,7 @@ standardDeviation([10, 2, 38, 23, 38, 23, 21], true); // 12.29899614287479 (popu ### sum -Returns the sum of an of two or more numbers/arrays. +Returns the sum of two or more numbers/arrays. Use `Array.reduce()` to add each value to an accumulator, initialized with a value of `0`. @@ -5003,6 +5096,73 @@ yesNo('Foo', true); // true
[⬆ Back to top](#table-of-contents) +--- + ## _Uncategorized_ + +### geometricProgression + +Initializes an array containing the numbers in the specified range where `start` and `end` are inclusive and the ratio between two terms is `step`. +Returns an error if `step` equals `1`. + +Use `Array.from()`, `Math.log()` and `Math.floor()` to create an array of the desired length, `Array.map()` to fill with the desired values in a range. +Omit the second argument, `start`, to use a default value of `1`. +Omit the third argument, `step`, to use a default value of `2`. + +```js +const geometricProgression = (end, start = 1, step = 2) => + Array.from({ length: Math.floor(Math.log(end / start) / Math.log(step)) + 1 }).map( + (v, i) => start * step ** i + ); +``` + +```js +geometricProgression(256); // [1, 2, 4, 8, 16, 32, 64, 128, 256] +geometricProgression(256, 3); //[3, 6, 12, 24, 48, 96, 192] +geometricProgression(256, 1, 4); //[1, 4, 16, 64, 256] +geometricProgression(256, 2, 1); //Gives error +``` + +
[⬆ back to top](#table-of-contents) + + +### maxN + +Returns the `n` maximum elements from the provided array. If `n` is greater than or equal to the provided array's length than return the original array(sorted in descending order). + +Sort's the array's shallow copy in descending order and returns the first n elements + +Skip the second argument to get a single element(in the form of a array) +```js +const maxN = (arr, n = 1) => [...arr].sort((a, b) => b - a).slice(0, n); +``` + +```js +maxN([1, 2, 3]); // [3] +maxN([1, 2, 3], 2); // [3,2] +maxN([1, 2, 3], 4); // [3,2,1] +``` + +
[⬆ back to top](#table-of-contents) + + +### minN + +Returns the `n` minimum elements from the provided array. If `n` is greater than or equal to the provided array's length than return the original array(sorted in ascending order). + +Sort's the array's shallow copy in ascending order and returns the first n elements + +Skip the second argument to get a single element(in the form of a array) +```js +const minN = (arr, n = 1) => [...arr].sort((a, b) => a - b).slice(0, n); +``` +```js +minN([1, 2, 3]); // [1] +minN([1, 2, 3], 2); // [1,2] +minN([1, 2, 3], 4); // [1,2,3] +``` + +
[⬆ back to top](#table-of-contents) + ## Collaborators diff --git a/dist/NOTICE.md b/dist/NOTICE.md new file mode 100644 index 000000000..f30f7b1d7 --- /dev/null +++ b/dist/NOTICE.md @@ -0,0 +1,15 @@ +# WARNING! + +The `_30s` module is not production ready. Do NOT use it in production websites. +It is strictly for testing purposes at this moment in time. Snippets do not have +any unit tests written and will not be reliable. + +Snippet names can and will change without notice between minor versions. + +Given the version `0.x.y`: + +* `x` indicates a snippet name change. +* `y` indicates a new snippet or fix. + +If your project is not serious and you do not care about the above issues, you will want +to use the `es5` version and also include `babel-polyfill` for widest browser support. diff --git a/dist/_30s.es5.js b/dist/_30s.es5.js new file mode 100644 index 000000000..4b4436292 --- /dev/null +++ b/dist/_30s.es5.js @@ -0,0 +1,1408 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define(factory) : + (global._30s = factory()); +}(this, (function () { 'use strict'; + +var anagrams = function anagrams(str) { + if (str.length <= 2) return str.length === 2 ? [str, str[1] + str[0]] : [str]; + return str.split('').reduce(function (acc, letter, i) { + return acc.concat(anagrams(str.slice(0, i) + str.slice(i + 1)).map(function (val) { + return letter + val; + })); + }, []); +}; + +var arrayToHtmlList = function arrayToHtmlList(arr, listID) { + return arr.map(function (item) { + return document.querySelector('#' + listID).innerHTML += '
  • ' + item + '
  • '; + }); +}; + +var average = function average() { + var _ref; + + var nums = (_ref = []).concat.apply(_ref, arguments); + return nums.reduce(function (acc, val) { + return acc + val; + }, 0) / nums.length; +}; + +var bottomVisible = function bottomVisible() { + return document.documentElement.clientHeight + window.scrollY >= (document.documentElement.scrollHeight || document.documentElement.clientHeight); +}; + +var byteSize = function byteSize(str) { + return new Blob([str]).size; +}; + +var call = function call(key) { + for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + args[_key - 1] = arguments[_key]; + } + + return function (context) { + return context[key].apply(context, args); + }; +}; + +function _toArray(arr) { return Array.isArray(arr) ? arr : Array.from(arr); } + +var capitalize = function capitalize(_ref) { + var _ref2 = _toArray(_ref), + first = _ref2[0], + rest = _ref2.slice(1); + + var lowerRest = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + return first.toUpperCase() + (lowerRest ? rest.join('').toLowerCase() : rest.join('')); +}; + +var capitalizeEveryWord = function capitalizeEveryWord(str) { + return str.replace(/\b[a-z]/g, function (char) { + return char.toUpperCase(); + }); +}; + +var chainAsync = function chainAsync(fns) { + var curr = 0; + var next = function next() { + return fns[curr++](next); + }; + next(); +}; + +var chunk = function chunk(arr, size) { + return Array.from({ length: Math.ceil(arr.length / size) }, function (v, i) { + return arr.slice(i * size, i * size + size); + }); +}; + +var clampNumber = function clampNumber(num, a, b) { + return Math.max(Math.min(num, Math.max(a, b)), Math.min(a, b)); +}; + +var cleanObj = function cleanObj(obj) { + var keysToKeep = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : []; + var childIndicator = arguments[2]; + + Object.keys(obj).forEach(function (key) { + if (key === childIndicator) { + cleanObj(obj[key], keysToKeep, childIndicator); + } else if (!keysToKeep.includes(key)) { + delete obj[key]; + } + }); + return obj; +}; + +var cloneRegExp = function cloneRegExp(regExp) { + return new RegExp(regExp.source, regExp.flags); +}; + +var coalesce = function coalesce() { + for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } + + return args.find(function (_) { + return ![undefined, null].includes(_); + }); +}; + +var coalesceFactory = function coalesceFactory(valid) { + return function () { + for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } + + return args.find(valid); + }; +}; + +var collatz = function collatz(n) { + return n % 2 == 0 ? n / 2 : 3 * n + 1; +}; + +var collectInto = function collectInto(fn) { + return function () { + for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } + + return fn(args); + }; +}; + +var compact = function compact(arr) { + return arr.filter(Boolean); +}; + +var compose = function compose() { + for (var _len = arguments.length, fns = Array(_len), _key = 0; _key < _len; _key++) { + fns[_key] = arguments[_key]; + } + + return fns.reduce(function (f, g) { + return function () { + return f(g.apply(undefined, arguments)); + }; + }); +}; + +var copyToClipboard = function copyToClipboard(str) { + var el = document.createElement('textarea'); + el.value = str; + el.setAttribute('readonly', ''); + el.style.position = 'absolute'; + el.style.left = '-9999px'; + document.body.appendChild(el); + var selected = document.getSelection().rangeCount > 0 ? document.getSelection().getRangeAt(0) : false; + el.select(); + document.execCommand('copy'); + document.body.removeChild(el); + if (selected) { + document.getSelection().removeAllRanges(); + document.getSelection().addRange(selected); + } +}; + +var countOccurrences = function countOccurrences(arr, value) { + return arr.reduce(function (a, v) { + return v === value ? a + 1 : a + 0; + }, 0); +}; + +var countVowels = function countVowels(str) { + return (str.match(/[aeiou]/gi) || []).length; +}; + +var currentURL = function currentURL() { + return window.location.href; +}; + +var curry = function curry(fn) { + for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) { + args[_key - 2] = arguments[_key]; + } + + var arity = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : fn.length; + return arity <= args.length ? fn.apply(undefined, args) : curry.bind.apply(curry, [null, fn, arity].concat(args)); +}; + +function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } + +var deepFlatten = function deepFlatten(arr) { + var _ref; + + return (_ref = []).concat.apply(_ref, _toConsumableArray(arr.map(function (v) { + return Array.isArray(v) ? deepFlatten(v) : v; + }))); +}; + +var defer = function defer(fn) { + for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + args[_key - 1] = arguments[_key]; + } + + return setTimeout.apply(undefined, [fn, 1].concat(args)); +}; + +var detectDeviceType = function detectDeviceType() { + return (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) ? 'Mobile' : 'Desktop' + ); +}; + +var difference = function difference(a, b) { + var s = new Set(b); + return a.filter(function (x) { + return !s.has(x); + }); +}; + +var differenceWith = function differenceWith(arr, val, comp) { + return arr.filter(function (a) { + return !val.find(function (b) { + return comp(a, b); + }); + }); +}; + +function _toConsumableArray$1(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } + +var digitize = function digitize(n) { + return [].concat(_toConsumableArray$1('' + n)).map(function (i) { + return parseInt(i); + }); +}; + +var distance = function distance(x0, y0, x1, y1) { + return Math.hypot(x1 - x0, y1 - y0); +}; + +function _toConsumableArray$2(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } + +var distinctValuesOfArray = function distinctValuesOfArray(arr) { + return [].concat(_toConsumableArray$2(new Set(arr))); +}; + +var dropElements = function dropElements(arr, func) { + while (arr.length > 0 && !func(arr[0])) { + arr = arr.slice(1); + }return arr; +}; + +var dropRight = function dropRight(arr) { + var n = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1; + return arr.slice(0, -n); +}; + +var elementIsVisibleInViewport = function elementIsVisibleInViewport(el) { + var partiallyVisible = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + + var _el$getBoundingClient = el.getBoundingClientRect(), + top = _el$getBoundingClient.top, + left = _el$getBoundingClient.left, + bottom = _el$getBoundingClient.bottom, + right = _el$getBoundingClient.right; + + var _window = window, + innerHeight = _window.innerHeight, + innerWidth = _window.innerWidth; + + return partiallyVisible ? (top > 0 && top < innerHeight || bottom > 0 && bottom < innerHeight) && (left > 0 && left < innerWidth || right > 0 && right < innerWidth) : top >= 0 && left >= 0 && bottom <= innerHeight && right <= innerWidth; +}; + +var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); + +var elo = function elo(_ref) { + var _ref2 = _slicedToArray(_ref, 2), + a = _ref2[0], + b = _ref2[1]; + + var kFactor = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 32; + + var expectedScore = function expectedScore(self, opponent) { + return 1 / (1 + Math.pow(10, (opponent - self) / 400)); + }; + var newRating = function newRating(rating, i) { + return rating + kFactor * (i - expectedScore(i ? a : b, i ? b : a)); + }; + return [newRating(a, 1), newRating(b, 0)]; +}; + +var escapeHTML = function escapeHTML(str) { + return str.replace(/[&<>'"]/g, function (tag) { + return { + '&': '&', + '<': '<', + '>': '>', + "'": ''', + '"': '"' + }[tag] || tag; + }); +}; + +var escapeRegExp = function escapeRegExp(str) { + return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); +}; + +var everyNth = function everyNth(arr, nth) { + return arr.filter(function (e, i) { + return i % nth === nth - 1; + }); +}; + +var extendHex = function extendHex(shortHex) { + return '#' + shortHex.slice(shortHex.startsWith('#') ? 1 : 0).split('').map(function (x) { + return x + x; + }).join(''); +}; + +var factorial = function factorial(n) { + return n < 0 ? function () { + throw new TypeError('Negative numbers are not allowed!'); + }() : n <= 1 ? 1 : n * factorial(n - 1); +}; + +var fibonacci = function fibonacci(n) { + return Array.from({ length: n }).reduce(function (acc, val, i) { + return acc.concat(i > 1 ? acc[i - 1] + acc[i - 2] : i); + }, []); +}; + +var fibonacciCountUntilNum = function fibonacciCountUntilNum(num) { + return Math.ceil(Math.log(num * Math.sqrt(5) + 1 / 2) / Math.log((Math.sqrt(5) + 1) / 2)); +}; + +var fibonacciUntilNum = function fibonacciUntilNum(num) { + var n = Math.ceil(Math.log(num * Math.sqrt(5) + 1 / 2) / Math.log((Math.sqrt(5) + 1) / 2)); + return Array.from({ length: n }).reduce(function (acc, val, i) { + return acc.concat(i > 1 ? acc[i - 1] + acc[i - 2] : i); + }, []); +}; + +var filterNonUnique = function filterNonUnique(arr) { + return arr.filter(function (i) { + return arr.indexOf(i) === arr.lastIndexOf(i); + }); +}; + +function _toConsumableArray$3(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } + +var flatten = function flatten(arr) { + var _ref; + + return (_ref = []).concat.apply(_ref, _toConsumableArray$3(arr)); +}; + +var flattenDepth = function flattenDepth(arr) { + var depth = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1; + return depth != 1 ? arr.reduce(function (a, v) { + return a.concat(Array.isArray(v) ? flattenDepth(v, depth - 1) : v); + }, []) : arr.reduce(function (a, v) { + return a.concat(v); + }, []); +}; + +var flip = function flip(fn) { + return function () { + for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } + + return fn.apply(undefined, [args.pop()].concat(args)); + }; +}; + +var fromCamelCase = function fromCamelCase(str) { + var separator = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '_'; + return str.replace(/([a-z\d])([A-Z])/g, '$1' + separator + '$2').replace(/([A-Z]+)([A-Z][a-z\d]+)/g, '$1' + separator + '$2').toLowerCase(); +}; + +var functionName = function functionName(fn) { + return console.debug(fn.name), fn; +}; + +var gcd = function gcd() { + var _ref; + + var data = (_ref = []).concat.apply(_ref, arguments); + var helperGcd = function helperGcd(x, y) { + return !y ? x : gcd(y, x % y); + }; + return data.reduce(function (a, b) { + return helperGcd(a, b); + }); +}; + +var getDaysDiffBetweenDates = function getDaysDiffBetweenDates(dateInitial, dateFinal) { + return (dateFinal - dateInitial) / (1000 * 3600 * 24); +}; + +var getScrollPosition = function getScrollPosition() { + var el = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : window; + return { + x: el.pageXOffset !== undefined ? el.pageXOffset : el.scrollLeft, + y: el.pageYOffset !== undefined ? el.pageYOffset : el.scrollTop + }; +}; + +var getStyle = function getStyle(el, ruleName) { + return getComputedStyle(el)[ruleName]; +}; + +var getType = function getType(v) { + return v === undefined ? 'undefined' : v === null ? 'null' : v.constructor.name.toLowerCase(); +}; + +var getURLParameters = function getURLParameters(url) { + return url.match(/([^?=&]+)(=([^&]*))/g).reduce(function (a, v) { + return a[v.slice(0, v.indexOf('='))] = v.slice(v.indexOf('=') + 1), a; + }, {}); +}; + +var groupBy = function groupBy(arr, func) { + return arr.map(typeof func === 'function' ? func : function (val) { + return val[func]; + }).reduce(function (acc, val, i) { + acc[val] = (acc[val] || []).concat(arr[i]); + return acc; + }, {}); +}; + +var hammingDistance = function hammingDistance(num1, num2) { + return ((num1 ^ num2).toString(2).match(/1/g) || '').length; +}; + +var hasClass = function hasClass(el, className) { + return el.classList.contains(className); +}; + +var hasFlags = function hasFlags() { + for (var _len = arguments.length, flags = Array(_len), _key = 0; _key < _len; _key++) { + flags[_key] = arguments[_key]; + } + + return flags.every(function (flag) { + return process.argv.includes(/^-{1,2}/.test(flag) ? flag : '--' + flag); + }); +}; + +var head = function head(arr) { + return arr[0]; +}; + +function _toConsumableArray$4(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } + +var hexToRGB = function hexToRGB(hex) { + var alpha = false, + h = hex.slice(hex.startsWith('#') ? 1 : 0); + if (h.length === 3) h = [].concat(_toConsumableArray$4(h)).map(function (x) { + return x + x; + }).join('');else if (h.length === 8) alpha = true; + h = parseInt(h, 16); + return 'rgb' + (alpha ? 'a' : '') + '(' + (h >>> (alpha ? 24 : 16)) + ', ' + ((h & (alpha ? 0x00ff0000 : 0x00ff00)) >>> (alpha ? 16 : 8)) + ', ' + ((h & (alpha ? 0x0000ff00 : 0x0000ff)) >>> (alpha ? 8 : 0)) + (alpha ? ', ' + (h & 0x000000ff) : '') + ')'; +}; + +var hide = function hide() { + for (var _len = arguments.length, el = Array(_len), _key = 0; _key < _len; _key++) { + el[_key] = arguments[_key]; + } + + return [].concat(el).forEach(function (e) { + return e.style.display = 'none'; + }); +}; + +var httpsRedirect = function httpsRedirect() { + if (location.protocol !== 'https:') location.replace('https://' + location.href.split('//')[1]); +}; + +var initial = function initial(arr) { + return arr.slice(0, -1); +}; + +var initialize2DArray = function initialize2DArray(w, h) { + var val = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; + return Array(h).fill().map(function () { + return Array(w).fill(val); + }); +}; + +var initializeArrayWithRange = function initializeArrayWithRange(end) { + var start = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; + return Array.from({ length: end + 1 - start }).map(function (v, i) { + return i + start; + }); +}; + +var initializeArrayWithValues = function initializeArrayWithValues(n) { + var value = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; + return Array(n).fill(value); +}; + +var inRange = function inRange(n, start) { + var end = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; + + if (end && start > end) end = [start, start = end][0]; + return end == null ? n >= 0 && n < start : n >= start && n < end; +}; + +var intersection = function intersection(a, b) { + var s = new Set(b); + return a.filter(function (x) { + return s.has(x); + }); +}; + +var invertKeyValues = function invertKeyValues(obj) { + return Object.keys(obj).reduce(function (acc, key) { + acc[obj[key]] = key; + return acc; + }, {}); +}; + +var isAbsoluteURL = function isAbsoluteURL(str) { + return (/^[a-z][a-z0-9+.-]*:/.test(str) + ); +}; + +var isArmstrongNumber = function isArmstrongNumber(digits) { + return function (arr) { + return arr.reduce(function (a, d) { + return a + Math.pow(parseInt(d), arr.length); + }, 0) == digits; + }((digits + '').split('')); +}; + +var isArray = function isArray(val) { + return !!val && Array.isArray(val); +}; + +function _toConsumableArray$5(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } + +var isArrayLike = function isArrayLike(val) { + try { + return [].concat(_toConsumableArray$5(val)), true; + } catch (e) { + return false; + } +}; + +var isBoolean = function isBoolean(val) { + return typeof val === 'boolean'; +}; + +var isDivisible = function isDivisible(dividend, divisor) { + return dividend % divisor === 0; +}; + +var isEven = function isEven(num) { + return num % 2 === 0; +}; + +var isFunction = function isFunction(val) { + return val && typeof val === 'function'; +}; + +var isNull = function isNull(val) { + return val === null; +}; + +var isNumber = function isNumber(val) { + return typeof val === 'number'; +}; + +var isPrime = function isPrime(num) { + var boundary = Math.floor(Math.sqrt(num)); + for (var i = 2; i <= boundary; i++) { + if (num % i == 0) return false; + }return num >= 2; +}; + +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; + +var isPrimitive = function isPrimitive(val) { + return !['object', 'function'].includes(typeof val === 'undefined' ? 'undefined' : _typeof(val)) || val === null; +}; + +var _typeof$1 = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; + +var isPromiseLike = function isPromiseLike(obj) { + return obj !== null && ((typeof obj === 'undefined' ? 'undefined' : _typeof$1(obj)) === 'object' || typeof obj === 'function') && typeof obj.then === 'function'; +}; + +var _slicedToArray$1 = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); + +var isSorted = function isSorted(arr) { + var direction = arr[0] > arr[1] ? -1 : 1; + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; + + try { + for (var _iterator = arr.entries()[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + var _ref = _step.value; + + var _ref2 = _slicedToArray$1(_ref, 2); + + var i = _ref2[0]; + var val = _ref2[1]; + + if (i === arr.length - 1) return direction;else if ((val - arr[i + 1]) * direction > 0) return 0; + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator.return) { + _iterator.return(); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } + } + } +}; + +var isString = function isString(val) { + return typeof val === 'string'; +}; + +var _typeof$2 = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; + +var isSymbol = function isSymbol(val) { + return (typeof val === 'undefined' ? 'undefined' : _typeof$2(val)) === 'symbol'; +}; + +var isTravisCI = function isTravisCI() { + return 'TRAVIS' in process.env && 'CI' in process.env; +}; + +var isValidJSON = function isValidJSON(obj) { + try { + JSON.parse(obj); + return true; + } catch (e) { + return false; + } +}; + +var join = function join(arr) { + var separator = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ','; + var end = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : separator; + return arr.reduce(function (acc, val, i) { + return i == arr.length - 2 ? acc + val + end : i == arr.length - 1 ? acc + val : acc + val + separator; + }, ''); +}; + +var JSONToDate = function JSONToDate(arr) { + var dt = new Date(parseInt(arr.toString().substr(6))); + return dt.getDate() + "/" + (dt.getMonth() + 1) + "/" + dt.getFullYear(); +}; + +var fs = typeof require !== "undefined" && require('fs'); +var JSONToFile = function JSONToFile(obj, filename) { + return fs.writeFile(filename + ".json", JSON.stringify(obj, null, 2)); +}; + +var last = function last(arr) { + return arr[arr.length - 1]; +}; + +var lcm = function lcm() { + var _ref; + + var gcd = function gcd(x, y) { + return !y ? x : gcd(y, x % y); + }; + var _lcm = function _lcm(x, y) { + return x * y / gcd(x, y); + }; + return (_ref = []).concat.apply(_ref, arguments).reduce(function (a, b) { + return _lcm(a, b); + }); +}; + +var lowercaseKeys = function lowercaseKeys(obj) { + return Object.keys(obj).reduce(function (acc, key) { + acc[key.toLowerCase()] = obj[key]; + return acc; + }, {}); +}; + +var mapObject = function mapObject(arr, fn) { + return function (a) { + return a = [arr, arr.map(fn)], a[0].reduce(function (acc, val, ind) { + return acc[val] = a[1][ind], acc; + }, {}); + }(); +}; + +var mask = function mask(cc) { + var num = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 4; + var mask = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '*'; + return ('' + cc).slice(0, -num).replace(/./g, mask) + ('' + cc).slice(-num); +}; + +function _toConsumableArray$6(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } + +var max = function max() { + var _ref; + + return Math.max.apply(Math, _toConsumableArray$6((_ref = []).concat.apply(_ref, arguments))); +}; + +function _toConsumableArray$7(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } + +var median = function median(arr) { + var mid = Math.floor(arr.length / 2), + nums = [].concat(_toConsumableArray$7(arr)).sort(function (a, b) { + return a - b; + }); + return arr.length % 2 !== 0 ? nums[mid] : (nums[mid - 1] + nums[mid]) / 2; +}; + +var memoize = function memoize(fn) { + var cache = Object.create(null); + return function (value) { + return cache[value] || (cache[value] = fn(value)); + }; +}; + +function _toConsumableArray$8(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } + +var min = function min(arr) { + var _ref; + + return Math.min.apply(Math, _toConsumableArray$8((_ref = []).concat.apply(_ref, _toConsumableArray$8(arr)))); +}; + +var negate = function negate(func) { + return function () { + return !func.apply(undefined, arguments); + }; +}; + +var nthElement = function nthElement(arr) { + var n = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; + return (n > 0 ? arr.slice(n, n + 1) : arr.slice(n))[0]; +}; + +var objectFromPairs = function objectFromPairs(arr) { + return arr.reduce(function (a, v) { + return a[v[0]] = v[1], a; + }, {}); +}; + +var objectToPairs = function objectToPairs(obj) { + return Object.keys(obj).map(function (k) { + return [k, obj[k]]; + }); +}; + +var once = function once(fn) { + var called = false; + return function () { + if (called) return; + called = true; + + for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } + + return fn.apply(this, args); + }; +}; + +var onUserInputChange = function onUserInputChange(callback) { + var type = 'mouse', + lastTime = 0; + var mousemoveHandler = function mousemoveHandler() { + var now = performance.now(); + if (now - lastTime < 20) type = 'mouse', callback(type), document.removeEventListener('mousemove', mousemoveHandler); + lastTime = now; + }; + document.addEventListener('touchstart', function () { + if (type === 'touch') return; + type = 'touch', callback(type), document.addEventListener('mousemove', mousemoveHandler); + }); +}; + +var _slicedToArray$2 = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); + +function _toConsumableArray$9(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } + +var orderBy = function orderBy(arr, props, orders) { + return [].concat(_toConsumableArray$9(arr)).sort(function (a, b) { + return props.reduce(function (acc, prop, i) { + if (acc === 0) { + var _ref = orders && orders[i] === 'desc' ? [b[prop], a[prop]] : [a[prop], b[prop]], + _ref2 = _slicedToArray$2(_ref, 2), + p1 = _ref2[0], + p2 = _ref2[1]; + + acc = p1 > p2 ? 1 : p1 < p2 ? -1 : 0; + } + return acc; + }, 0); + }); +}; + +var palindrome = function palindrome(str) { + var s = str.toLowerCase().replace(/[\W_]/g, ''); + return s === s.split('').reverse().join(''); +}; + +var percentile = function percentile(arr, val) { + return 100 * arr.reduce(function (acc, v) { + return acc + (v < val ? 1 : 0) + (v === val ? 0.5 : 0); + }, 0) / arr.length; +}; + +var pick = function pick(obj, arr) { + return arr.reduce(function (acc, curr) { + return curr in obj && (acc[curr] = obj[curr]), acc; + }, {}); +}; + +var pipeFunctions = function pipeFunctions() { + for (var _len = arguments.length, fns = Array(_len), _key = 0; _key < _len; _key++) { + fns[_key] = arguments[_key]; + } + + return fns.reduce(function (f, g) { + return function () { + return g(f.apply(undefined, arguments)); + }; + }); +}; + +var powerset = function powerset(arr) { + return arr.reduce(function (a, v) { + return a.concat(a.map(function (r) { + return [v].concat(r); + })); + }, [[]]); +}; + +var prettyBytes = function prettyBytes(num) { + var precision = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 3; + var addSpace = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true; + + var UNITS = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; + if (Math.abs(num) < 1) return num + (addSpace ? ' ' : '') + UNITS[0]; + var exponent = Math.min(Math.floor(Math.log10(num < 0 ? -num : num) / 3), UNITS.length - 1); + var n = Number(((num < 0 ? -num : num) / Math.pow(1000, exponent)).toPrecision(precision)); + return (num < 0 ? '-' : '') + n + (addSpace ? ' ' : '') + UNITS[exponent]; +}; + +var primes = function primes(num) { + var arr = Array.from({ length: num - 1 }).map(function (x, i) { + return i + 2; + }), + sqroot = Math.floor(Math.sqrt(num)), + numsTillSqroot = Array.from({ length: sqroot - 1 }).map(function (x, i) { + return i + 2; + }); + numsTillSqroot.forEach(function (x) { + return arr = arr.filter(function (y) { + return y % x !== 0 || y == x; + }); + }); + return arr; +}; + +var promisify = function promisify(func) { + return function () { + for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } + + return new Promise(function (resolve, reject) { + return func.apply(undefined, args.concat([function (err, result) { + return err ? reject(err) : resolve(result); + }])); + }); + }; +}; + +var pull = function pull(arr) { + for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + args[_key - 1] = arguments[_key]; + } + + var argState = Array.isArray(args[0]) ? args[0] : args; + var pulled = arr.filter(function (v, i) { + return !argState.includes(v); + }); + arr.length = 0; + pulled.forEach(function (v) { + return arr.push(v); + }); +}; + +var pullAtIndex = function pullAtIndex(arr, pullArr) { + var removed = []; + var pulled = arr.map(function (v, i) { + return pullArr.includes(i) ? removed.push(v) : v; + }).filter(function (v, i) { + return !pullArr.includes(i); + }); + arr.length = 0; + pulled.forEach(function (v) { + return arr.push(v); + }); + return removed; +}; + +var pullAtValue = function pullAtValue(arr, pullArr) { + var removed = [], + pushToRemove = arr.forEach(function (v, i) { + return pullArr.includes(v) ? removed.push(v) : v; + }), + mutateTo = arr.filter(function (v, i) { + return !pullArr.includes(v); + }); + arr.length = 0; + mutateTo.forEach(function (v) { + return arr.push(v); + }); + return removed; +}; + +function _toConsumableArray$10(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } + +function _toArray$1(arr) { return Array.isArray(arr) ? arr : Array.from(arr); } + +var quickSort = function quickSort(_ref, desc) { + var _ref2 = _toArray$1(_ref), + n = _ref2[0], + nums = _ref2.slice(1); + + return isNaN(n) ? [] : [].concat(_toConsumableArray$10(quickSort(nums.filter(function (v) { + return desc ? v > n : v <= n; + }), desc)), [n], _toConsumableArray$10(quickSort(nums.filter(function (v) { + return !desc ? v > n : v <= n; + }), desc))); +}; + +var randomHexColorCode = function randomHexColorCode() { + var n = (Math.random() * 0xfffff | 0).toString(16); + return '#' + (n.length !== 6 ? (Math.random() * 0xf | 0).toString(16) + n : n); +}; + +var randomIntegerInRange = function randomIntegerInRange(min, max) { + return Math.floor(Math.random() * (max - min + 1)) + min; +}; + +var randomNumberInRange = function randomNumberInRange(min, max) { + return Math.random() * (max - min) + min; +}; + +var fs$1 = typeof require !== "undefined" && require('fs'); +var readFileLines = function readFileLines(filename) { + return fs$1.readFileSync(filename).toString('UTF8').split('\n'); +}; + +var redirect = function redirect(url) { + var asLink = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; + return asLink ? window.location.href = url : window.location.replace(url); +}; + +var reducedFilter = function reducedFilter(data, keys, fn) { + return data.filter(fn).map(function (el) { + return keys.reduce(function (acc, key) { + acc[key] = el[key]; + return acc; + }, {}); + }); +}; + +var remove = function remove(arr, func) { + return Array.isArray(arr) ? arr.filter(func).reduce(function (acc, val) { + arr.splice(arr.indexOf(val), 1); + return acc.concat(val); + }, []) : []; +}; + +var repeatString = function repeatString() { + var str = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ''; + var num = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 2; + + return num >= 0 ? str.repeat(num) : str; +}; + +var reverseString = function reverseString(str) { + return str.split('').reverse().join(''); +}; + +var RGBToHex = function RGBToHex(r, g, b) { + return ((r << 16) + (g << 8) + b).toString(16).padStart(6, '0'); +}; + +var round = function round(n) { + var decimals = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; + return Number(Math.round(n + "e" + decimals) + "e-" + decimals); +}; + +var runAsync = function runAsync(fn) { + var blob = '\n var fn = ' + fn.toString() + ';\n this.postMessage(fn());\n '; + var worker = new Worker(URL.createObjectURL(new Blob([blob]), { + type: 'application/javascript; charset=utf-8' + })); + return new Promise(function (res, rej) { + worker.onmessage = function (_ref) { + var data = _ref.data; + + res(data), worker.terminate(); + }; + worker.onerror = function (err) { + rej(err), worker.terminate(); + }; + }); +}; + +var runPromisesInSeries = function runPromisesInSeries(ps) { + return ps.reduce(function (p, next) { + return p.then(next); + }, Promise.resolve()); +}; + +var sample = function sample(arr) { + return arr[Math.floor(Math.random() * arr.length)]; +}; + +function _toArray$2(arr) { return Array.isArray(arr) ? arr : Array.from(arr); } + +var sampleSize = function sampleSize(_ref) { + var _ref2 = _toArray$2(_ref), + arr = _ref2.slice(0); + + var n = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1; + + var m = arr.length; + while (m) { + var i = Math.floor(Math.random() * m--); + var _ref3 = [arr[i], arr[m]]; + arr[m] = _ref3[0]; + arr[i] = _ref3[1]; + } + return arr.slice(0, n); +}; + +var scrollToTop = function scrollToTop() { + var c = document.documentElement.scrollTop || document.body.scrollTop; + if (c > 0) { + window.requestAnimationFrame(scrollToTop); + window.scrollTo(0, c - c / 8); + } +}; + +var sdbm = function sdbm(str) { + var arr = str.split(''); + return arr.reduce(function (hashCode, currentVal) { + return hashCode = currentVal.charCodeAt(0) + (hashCode << 6) + (hashCode << 16) - hashCode; + }, 0); +}; + +var select = function select(from, selector) { + return selector.split('.').reduce(function (prev, cur) { + return prev && prev[cur]; + }, from); +}; + +var setStyle = function setStyle(el, ruleName, value) { + return el.style[ruleName] = value; +}; + +var shallowClone = function shallowClone(obj) { + return Object.assign({}, obj); +}; + +var show = function show() { + for (var _len = arguments.length, el = Array(_len), _key = 0; _key < _len; _key++) { + el[_key] = arguments[_key]; + } + + return [].concat(el).forEach(function (e) { + return e.style.display = ''; + }); +}; + +function _toArray$3(arr) { return Array.isArray(arr) ? arr : Array.from(arr); } + +var shuffle = function shuffle(_ref) { + var _ref2 = _toArray$3(_ref), + arr = _ref2.slice(0); + + var m = arr.length; + while (m) { + var i = Math.floor(Math.random() * m--); + var _ref3 = [arr[i], arr[m]]; + arr[m] = _ref3[0]; + arr[i] = _ref3[1]; + } + return arr; +}; + +var similarity = function similarity(arr, values) { + return arr.filter(function (v) { + return values.includes(v); + }); +}; + +var _typeof$3 = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; + +var size = function size(value) { + return Array.isArray(value) ? value.length : value && (typeof value === 'undefined' ? 'undefined' : _typeof$3(value)) === 'object' ? value.size || value.length || Object.keys(value).length : typeof value === 'string' ? new Blob([value]).size : 0; +}; + +var sleep = function sleep(ms) { + return new Promise(function (resolve) { + return setTimeout(resolve, ms); + }); +}; + +var solveRPN = function solveRPN(rpn) { + var OPERATORS = { + '*': function _(a, b) { + return a * b; + }, + '+': function _(a, b) { + return a + b; + }, + '-': function _(a, b) { + return a - b; + }, + '/': function _(a, b) { + return a / b; + }, + '**': function _(a, b) { + return Math.pow(a, b); + } + }; + var _ref = [[], rpn.replace(/\^/g, '**').split(/\s+/g).filter(function (el) { + return !/\s+/.test(el) && el !== ''; + })], + stack = _ref[0], + solve = _ref[1]; + + solve.forEach(function (symbol) { + if (!isNaN(parseFloat(symbol)) && isFinite(symbol)) { + stack.push(symbol); + } else if (Object.keys(OPERATORS).includes(symbol)) { + var _ref2 = [stack.pop(), stack.pop()], + a = _ref2[0], + b = _ref2[1]; + + 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'; +}; + +var sortCharactersInString = function sortCharactersInString(str) { + return str.split('').sort(function (a, b) { + return a.localeCompare(b); + }).join(''); +}; + +var sortedIndex = function sortedIndex(arr, n) { + var isDescending = arr[0] > arr[arr.length - 1]; + var index = arr.findIndex(function (el) { + return isDescending ? n >= el : n <= el; + }); + return index === -1 ? arr.length : index; +}; + +var speechSynthesis = function speechSynthesis(message) { + var msg = new SpeechSynthesisUtterance(message); + msg.voice = window.speechSynthesis.getVoices()[0]; + window.speechSynthesis.speak(msg); +}; + +var splitLines = function splitLines(str) { + return str.split(/\r?\n/); +}; + +function _toConsumableArray$11(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } + +var spreadOver = function spreadOver(fn) { + return function (argsArr) { + return fn.apply(undefined, _toConsumableArray$11(argsArr)); + }; +}; + +var standardDeviation = function standardDeviation(arr) { + var usePopulation = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + + var mean = arr.reduce(function (acc, val) { + return acc + val; + }, 0) / arr.length; + return Math.sqrt(arr.reduce(function (acc, val) { + return acc.concat(Math.pow(val - mean, 2)); + }, []).reduce(function (acc, val) { + return acc + val; + }, 0) / (arr.length - (usePopulation ? 0 : 1))); +}; + +var sum = function sum() { + var _ref; + + return (_ref = []).concat.apply(_ref, arguments).reduce(function (acc, val) { + return acc + val; + }, 0); +}; + +var sumPower = function sumPower(end) { + var power = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 2; + var start = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1; + return Array(end + 1 - start).fill(0).map(function (x, i) { + return Math.pow(i + start, power); + }).reduce(function (a, b) { + return a + b; + }, 0); +}; + +function _toConsumableArray$12(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } + +var symmetricDifference = function symmetricDifference(a, b) { + var sA = new Set(a), + sB = new Set(b); + return [].concat(_toConsumableArray$12(a.filter(function (x) { + return !sB.has(x); + })), _toConsumableArray$12(b.filter(function (x) { + return !sA.has(x); + }))); +}; + +var tail = function tail(arr) { + return arr.length > 1 ? arr.slice(1) : arr; +}; + +var take = function take(arr) { + var n = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1; + return arr.slice(0, n); +}; + +var takeRight = function takeRight(arr) { + var n = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1; + return arr.slice(arr.length - n, arr.length); +}; + +var timeTaken = function timeTaken(callback) { + console.time('timeTaken'); + var r = callback(); + console.timeEnd('timeTaken'); + return r; +}; + +var toCamelCase = function toCamelCase(str) { + var s = str && str.match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g).map(function (x) { + return x.slice(0, 1).toUpperCase() + x.slice(1).toLowerCase(); + }).join(''); + return s.slice(0, 1).toLowerCase() + s.slice(1); +}; + +var toDecimalMark = function toDecimalMark(num) { + return num.toLocaleString('en-US'); +}; + +var toEnglishDate = function toEnglishDate(time) { + try { + return new Date(time).toISOString().split('T')[0].replace(/-/g, '/'); + } catch (e) {} +}; + +var toggleClass = function toggleClass(el, className) { + return el.classList.toggle(className); +}; + +var toKebabCase = function toKebabCase(str) { + return str && str.match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g).map(function (x) { + return x.toLowerCase(); + }).join('-'); +}; + +var tomorrow = function tomorrow() { + return new Date(new Date().getTime() + 86400000).toISOString().split('T')[0]; +}; + +var toOrdinalSuffix = function toOrdinalSuffix(num) { + var int = parseInt(num), + digits = [int % 10, int % 100], + ordinals = ['st', 'nd', 'rd', 'th'], + oPattern = [1, 2, 3, 4], + tPattern = [11, 12, 13, 14, 15, 16, 17, 18, 19]; + return oPattern.includes(digits[0]) && !tPattern.includes(digits[1]) ? int + ordinals[digits[0] - 1] : int + ordinals[3]; +}; + +var toSnakeCase = function toSnakeCase(str) { + return str && str.match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g).map(function (x) { + return x.toLowerCase(); + }).join('_'); +}; + +var truncateString = function truncateString(str, num) { + return str.length > num ? str.slice(0, num > 3 ? num - 3 : num) + '...' : str; +}; + +var truthCheckCollection = function truthCheckCollection(collection, pre) { + return collection.every(function (obj) { + return obj[pre]; + }); +}; + +var unescapeHTML = function unescapeHTML(str) { + return str.replace(/&|<|>|'|"/g, function (tag) { + return { + '&': '&', + '<': '<', + '>': '>', + ''': "'", + '"': '"' + }[tag] || tag; + }); +}; + +function _toConsumableArray$13(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } + +var union = function union(a, b) { + return Array.from(new Set([].concat(_toConsumableArray$13(a), _toConsumableArray$13(b)))); +}; + +var untildify = function untildify(str) { + return str.replace(/^~($|\/|\\)/, (typeof require !== "undefined" && require('os').homedir()) + "$1"); +}; + +var UUIDGeneratorBrowser = function UUIDGeneratorBrowser() { + return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, function (c) { + return (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16); + }); +}; + +var crypto$1 = typeof require !== "undefined" && require('crypto'); +var UUIDGeneratorNode = function UUIDGeneratorNode() { + return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, function (c) { + return (c ^ crypto$1.randomBytes(1)[0] & 15 >> c / 4).toString(16); + }); +}; + +var validateNumber = function validateNumber(n) { + return !isNaN(parseFloat(n)) && isFinite(n) && Number(n) == n; +}; + +var without = function without(arr) { + for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + args[_key - 1] = arguments[_key]; + } + + return arr.filter(function (v) { + return !args.includes(v); + }); +}; + +var words = function words(str) { + var pattern = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : /[^a-zA-Z-]+/; + return str.split(pattern).filter(Boolean); +}; + +var yesNo = function yesNo(val) { + var def = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + return (/^(y|yes)$/i.test(val) ? true : /^(n|no)$/i.test(val) ? false : def + ); +}; + +function _toConsumableArray$14(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } + +var zip = function zip() { + for (var _len = arguments.length, arrays = Array(_len), _key = 0; _key < _len; _key++) { + arrays[_key] = arguments[_key]; + } + + var maxLength = Math.max.apply(Math, _toConsumableArray$14(arrays.map(function (x) { + return x.length; + }))); + return Array.from({ length: maxLength }).map(function (_, i) { + return Array.from({ length: arrays.length }, function (_, k) { + return arrays[k][i]; + }); + }); +}; + +var zipObject = function zipObject(props, values) { + return props.reduce(function (obj, prop, index) { + return obj[prop] = values[index], obj; + }, {}); +}; + +var imports = { anagrams: anagrams, arrayToHtmlList: arrayToHtmlList, average: average, bottomVisible: bottomVisible, byteSize: byteSize, call: call, capitalize: capitalize, capitalizeEveryWord: capitalizeEveryWord, chainAsync: chainAsync, chunk: chunk, clampNumber: clampNumber, cleanObj: cleanObj, cloneRegExp: cloneRegExp, coalesce: coalesce, coalesceFactory: coalesceFactory, collatz: collatz, collectInto: collectInto, compact: compact, compose: compose, copyToClipboard: copyToClipboard, countOccurrences: countOccurrences, countVowels: countVowels, currentURL: currentURL, curry: curry, deepFlatten: deepFlatten, defer: defer, detectDeviceType: detectDeviceType, difference: difference, differenceWith: differenceWith, digitize: digitize, distance: distance, distinctValuesOfArray: distinctValuesOfArray, dropElements: dropElements, dropRight: dropRight, elementIsVisibleInViewport: elementIsVisibleInViewport, elo: elo, escapeHTML: escapeHTML, escapeRegExp: escapeRegExp, everyNth: everyNth, extendHex: extendHex, factorial: factorial, fibonacci: fibonacci, fibonacciCountUntilNum: fibonacciCountUntilNum, fibonacciUntilNum: fibonacciUntilNum, filterNonUnique: filterNonUnique, flatten: flatten, flattenDepth: flattenDepth, flip: flip, fromCamelCase: fromCamelCase, functionName: functionName, gcd: gcd, getDaysDiffBetweenDates: getDaysDiffBetweenDates, getScrollPosition: getScrollPosition, getStyle: getStyle, getType: getType, getURLParameters: getURLParameters, groupBy: groupBy, hammingDistance: hammingDistance, hasClass: hasClass, hasFlags: hasFlags, head: head, hexToRGB: hexToRGB, hide: hide, httpsRedirect: httpsRedirect, initial: initial, initialize2DArray: initialize2DArray, initializeArrayWithRange: initializeArrayWithRange, initializeArrayWithValues: initializeArrayWithValues, inRange: inRange, intersection: intersection, invertKeyValues: invertKeyValues, isAbsoluteURL: isAbsoluteURL, isArmstrongNumber: isArmstrongNumber, isArray: isArray, isArrayLike: isArrayLike, isBoolean: isBoolean, isDivisible: isDivisible, isEven: isEven, isFunction: isFunction, isNull: isNull, isNumber: isNumber, isPrime: isPrime, isPrimitive: isPrimitive, isPromiseLike: isPromiseLike, isSorted: isSorted, isString: isString, isSymbol: isSymbol, isTravisCI: isTravisCI, isValidJSON: isValidJSON, join: join, JSONToDate: JSONToDate, JSONToFile: JSONToFile, last: last, lcm: lcm, lowercaseKeys: lowercaseKeys, mapObject: mapObject, mask: mask, max: max, median: median, memoize: memoize, min: min, negate: negate, nthElement: nthElement, objectFromPairs: objectFromPairs, objectToPairs: objectToPairs, once: once, onUserInputChange: onUserInputChange, orderBy: orderBy, palindrome: palindrome, percentile: percentile, pick: pick, pipeFunctions: pipeFunctions, powerset: powerset, prettyBytes: prettyBytes, primes: primes, promisify: promisify, pull: pull, pullAtIndex: pullAtIndex, pullAtValue: pullAtValue, quickSort: quickSort, randomHexColorCode: randomHexColorCode, randomIntegerInRange: randomIntegerInRange, randomNumberInRange: randomNumberInRange, readFileLines: readFileLines, redirect: redirect, reducedFilter: reducedFilter, remove: remove, repeatString: repeatString, reverseString: reverseString, RGBToHex: RGBToHex, round: round, runAsync: runAsync, runPromisesInSeries: runPromisesInSeries, sample: sample, sampleSize: sampleSize, scrollToTop: scrollToTop, sdbm: sdbm, select: select, setStyle: setStyle, shallowClone: shallowClone, show: show, shuffle: shuffle, similarity: similarity, size: size, sleep: sleep, solveRPN: solveRPN, sortCharactersInString: sortCharactersInString, sortedIndex: sortedIndex, speechSynthesis: speechSynthesis, splitLines: splitLines, spreadOver: spreadOver, standardDeviation: standardDeviation, sum: sum, sumPower: sumPower, symmetricDifference: symmetricDifference, tail: tail, take: take, takeRight: takeRight, timeTaken: timeTaken, toCamelCase: toCamelCase, toDecimalMark: toDecimalMark, toEnglishDate: toEnglishDate, toggleClass: toggleClass, toKebabCase: toKebabCase, tomorrow: tomorrow, toOrdinalSuffix: toOrdinalSuffix, toSnakeCase: toSnakeCase, truncateString: truncateString, truthCheckCollection: truthCheckCollection, unescapeHTML: unescapeHTML, union: union, untildify: untildify, UUIDGeneratorBrowser: UUIDGeneratorBrowser, UUIDGeneratorNode: UUIDGeneratorNode, 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 new file mode 100644 index 000000000..808d1c793 --- /dev/null +++ b/dist/_30s.es5.min.js @@ -0,0 +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){if(Array.isArray(a)){for(var b=0,c=Array(a.length);b=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(){var a,b=(a=[]).concat.apply(a,arguments);return b.reduce(function(a,b){return a+b},0)/b.length},bottomVisible:function(){return document.documentElement.clientHeight+window.scrollY>=(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(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=D(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':E(a))},isTravisCI:function(){return'TRAVIS'in process.env&&'CI'in process.env},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))})},orderBy:function(a,c,d){return[].concat(k(a)).sort(function(e,a){return c.reduce(function(b,c,f){if(0===b){var g=d&&'desc'===d[f]?[a[c],e[c]]:[e[c],a[c]],h=G(g,2),i=h[0],j=h[1];b=i>j?1:iMath.abs(a))return a+(c?' ':'')+d[0];var e=x(t(Math.log10(0>a?-a:a)/3),d.length-1),f=+((0>a?-a:a)/w(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=t(u(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;de:a<=e}),c)),[e],l(a(f.filter(function(a){return c?a<=e:a>e}),c)))},randomHexColorCode:function(){var a=(0|1048575*Math.random()).toString(16);return'#'+(6===a.length?a:(0|15*Math.random()).toString(16)+a)},randomIntegerInRange:function(a,b){return t(Math.random()*(b-a+1))+a},randomNumberInRange:function(a,b){return Math.random()*(b-a)+a},readFileLines:function(a){return H.readFileSync(a).toString('UTF8').split('\n')},redirect:function(a){var b=1a[a.length-1],d=a.findIndex(function(a){return c?b>=a:b<=a});return-1===d?a.length:d},speechSynthesis:function(a){var b=new SpeechSynthesisUtterance(a);b.voice=window.speechSynthesis.getVoices()[0],window.speechSynthesis.speak(b)},splitLines:function(a){return a.split(/\r?\n/)},spreadOver:function(a){return function(b){return a.apply(void 0,p(b))}},standardDeviation:function(a){var b=1b?a.slice(0,3',"'":'\'',""":'"'}[a]||a})},union:function(c,a){return Array.from(new Set([].concat(r(c),r(a))))},untildify:function(a){return a.replace(/^~($|\/|\\)/,('undefined'!=typeof require&&require('os').homedir())+'$1')},UUIDGeneratorBrowser:function(){return'10000000-1000-4000-8000-100000000000'.replace(/[018]/g,function(a){return(a^crypto.getRandomValues(new Uint8Array(1))[0]&15>>a/4).toString(16)})},UUIDGeneratorNode:function(){return'10000000-1000-4000-8000-100000000000'.replace(/[018]/g,function(a){return(a^J.randomBytes(1)[0]&15>>a/4).toString(16)})},validateNumber:function(a){return!isNaN(parseFloat(a))&&isFinite(a)&&+a==a},without:function(a){for(var b=arguments.length,c=Array(1 { + if (str.length <= 2) return str.length === 2 ? [str, str[1] + str[0]] : [str]; + return str + .split('') + .reduce( + (acc, letter, i) => + acc.concat(anagrams(str.slice(0, i) + str.slice(i + 1)).map(val => letter + val)), + [] + ); +}; + +const arrayToHtmlList = (arr, listID) => + arr.map(item => (document.querySelector('#' + listID).innerHTML += `
  • ${item}
  • `)); + +const average = (...arr) => { + const nums = [].concat(...arr); + return nums.reduce((acc, val) => acc + val, 0) / nums.length; +}; + +const bottomVisible = () => + document.documentElement.clientHeight + window.scrollY >= + (document.documentElement.scrollHeight || document.documentElement.clientHeight); + +const byteSize = str => new Blob([str]).size; + +const call = (key, ...args) => context => context[key](...args); + +const capitalize = ([first, ...rest], lowerRest = false) => + first.toUpperCase() + (lowerRest ? rest.join('').toLowerCase() : rest.join('')); + +const capitalizeEveryWord = str => str.replace(/\b[a-z]/g, char => char.toUpperCase()); + +const chainAsync = fns => { + let curr = 0; + const next = () => fns[curr++](next); + next(); +}; + +const chunk = (arr, size) => + Array.from({ length: Math.ceil(arr.length / size) }, (v, i) => + arr.slice(i * size, i * size + size) + ); + +const clampNumber = (num, a, b) => Math.max(Math.min(num, Math.max(a, b)), Math.min(a, b)); + +const cleanObj = (obj, keysToKeep = [], childIndicator) => { + Object.keys(obj).forEach(key => { + if (key === childIndicator) { + cleanObj(obj[key], keysToKeep, childIndicator); + } else if (!keysToKeep.includes(key)) { + delete obj[key]; + } + }); + return obj; +}; + +const cloneRegExp = regExp => new RegExp(regExp.source, regExp.flags); + +const coalesce = (...args) => args.find(_ => ![undefined, null].includes(_)); + +const coalesceFactory = valid => (...args) => args.find(valid); + +const collatz = n => (n % 2 == 0 ? n / 2 : 3 * n + 1); + +const collectInto = fn => (...args) => fn(args); + +const compact = arr => arr.filter(Boolean); + +const compose = (...fns) => fns.reduce((f, g) => (...args) => f(g(...args))); + +const copyToClipboard = str => { + const el = document.createElement('textarea'); + el.value = str; + el.setAttribute('readonly', ''); + el.style.position = 'absolute'; + el.style.left = '-9999px'; + document.body.appendChild(el); + const selected = + document.getSelection().rangeCount > 0 ? document.getSelection().getRangeAt(0) : false; + el.select(); + document.execCommand('copy'); + document.body.removeChild(el); + if (selected) { + document.getSelection().removeAllRanges(); + document.getSelection().addRange(selected); + } +}; + +const countOccurrences = (arr, value) => arr.reduce((a, v) => (v === value ? a + 1 : a + 0), 0); + +const countVowels = str => (str.match(/[aeiou]/gi) || []).length; + +const currentURL = () => window.location.href; + +const curry = (fn, arity = fn.length, ...args) => + arity <= args.length ? fn(...args) : curry.bind(null, fn, arity, ...args); + +const deepFlatten = arr => [].concat(...arr.map(v => (Array.isArray(v) ? deepFlatten(v) : v))); + +const defer = (fn, ...args) => setTimeout(fn, 1, ...args); + +const detectDeviceType = () => + /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) + ? 'Mobile' + : 'Desktop'; + +const difference = (a, b) => { + const s = new Set(b); + return a.filter(x => !s.has(x)); +}; + +const differenceWith = (arr, val, comp) => arr.filter(a => !val.find(b => comp(a, b))); + +const digitize = n => [...('' + n)].map(i => parseInt(i)); + +const distance = (x0, y0, x1, y1) => Math.hypot(x1 - x0, y1 - y0); + +const distinctValuesOfArray = arr => [...new Set(arr)]; + +const dropElements = (arr, func) => { + while (arr.length > 0 && !func(arr[0])) arr = arr.slice(1); + return arr; +}; + +const dropRight = (arr, n = 1) => arr.slice(0, -n); + +const elementIsVisibleInViewport = (el, partiallyVisible = false) => { + const { top, left, bottom, right } = el.getBoundingClientRect(); + const { innerHeight, innerWidth } = window; + return partiallyVisible + ? ((top > 0 && top < innerHeight) || (bottom > 0 && bottom < innerHeight)) && + ((left > 0 && left < innerWidth) || (right > 0 && right < innerWidth)) + : top >= 0 && left >= 0 && bottom <= innerHeight && right <= innerWidth; +}; + +const elo = ([a, b], kFactor = 32) => { + const expectedScore = (self, opponent) => 1 / (1 + 10 ** ((opponent - self) / 400)); + const newRating = (rating, i) => rating + kFactor * (i - expectedScore(i ? a : b, i ? b : a)); + return [newRating(a, 1), newRating(b, 0)]; +}; + +const escapeHTML = str => + str.replace( + /[&<>'"]/g, + tag => + ({ + '&': '&', + '<': '<', + '>': '>', + "'": ''', + '"': '"' + }[tag] || tag) + ); + +const escapeRegExp = str => str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); + +const everyNth = (arr, nth) => arr.filter((e, i) => i % nth === nth - 1); + +const extendHex = shortHex => + '#' + + shortHex + .slice(shortHex.startsWith('#') ? 1 : 0) + .split('') + .map(x => x + x) + .join(''); + +const factorial = n => + n < 0 + ? (() => { + throw new TypeError('Negative numbers are not allowed!'); + })() + : n <= 1 ? 1 : n * factorial(n - 1); + +const fibonacci = n => + Array.from({ length: n }).reduce( + (acc, val, i) => acc.concat(i > 1 ? acc[i - 1] + acc[i - 2] : i), + [] + ); + +const fibonacciCountUntilNum = num => + Math.ceil(Math.log(num * Math.sqrt(5) + 1 / 2) / Math.log((Math.sqrt(5) + 1) / 2)); + +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), + [] + ); +}; + +const filterNonUnique = arr => arr.filter(i => arr.indexOf(i) === arr.lastIndexOf(i)); + +const flatten = arr => [].concat(...arr); + +const flattenDepth = (arr, depth = 1) => + depth != 1 + ? arr.reduce((a, v) => a.concat(Array.isArray(v) ? flattenDepth(v, depth - 1) : v), []) + : arr.reduce((a, v) => a.concat(v), []); + +const flip = fn => (...args) => fn(args.pop(), ...args); + +const fromCamelCase = (str, separator = '_') => + str + .replace(/([a-z\d])([A-Z])/g, '$1' + separator + '$2') + .replace(/([A-Z]+)([A-Z][a-z\d]+)/g, '$1' + separator + '$2') + .toLowerCase(); + +const functionName = fn => (console.debug(fn.name), fn); + +const gcd = (...arr) => { + let data = [].concat(...arr); + const helperGcd = (x, y) => (!y ? x : gcd(y, x % y)); + return data.reduce((a, b) => helperGcd(a, b)); +}; + +const getDaysDiffBetweenDates = (dateInitial, dateFinal) => + (dateFinal - dateInitial) / (1000 * 3600 * 24); + +const getScrollPosition = (el = window) => ({ + x: el.pageXOffset !== undefined ? el.pageXOffset : el.scrollLeft, + y: el.pageYOffset !== undefined ? el.pageYOffset : el.scrollTop +}); + +const getStyle = (el, ruleName) => getComputedStyle(el)[ruleName]; + +const getType = v => + v === undefined ? 'undefined' : v === null ? 'null' : v.constructor.name.toLowerCase(); + +const getURLParameters = url => + url + .match(/([^?=&]+)(=([^&]*))/g) + .reduce((a, v) => (a[v.slice(0, v.indexOf('='))] = v.slice(v.indexOf('=') + 1), a), {}); + +const groupBy = (arr, func) => + arr.map(typeof func === 'function' ? func : val => val[func]).reduce((acc, val, i) => { + acc[val] = (acc[val] || []).concat(arr[i]); + return acc; + }, {}); + +const hammingDistance = (num1, num2) => ((num1 ^ num2).toString(2).match(/1/g) || '').length; + +const hasClass = (el, className) => el.classList.contains(className); + +const hasFlags = (...flags) => + flags.every(flag => process.argv.includes(/^-{1,2}/.test(flag) ? flag : '--' + flag)); + +const head = arr => arr[0]; + +const hexToRGB = hex => { + let alpha = false, + h = hex.slice(hex.startsWith('#') ? 1 : 0); + if (h.length === 3) h = [...h].map(x => x + x).join(''); + else if (h.length === 8) alpha = true; + h = parseInt(h, 16); + return ( + 'rgb' + + (alpha ? 'a' : '') + + '(' + + (h >>> (alpha ? 24 : 16)) + + ', ' + + ((h & (alpha ? 0x00ff0000 : 0x00ff00)) >>> (alpha ? 16 : 8)) + + ', ' + + ((h & (alpha ? 0x0000ff00 : 0x0000ff)) >>> (alpha ? 8 : 0)) + + (alpha ? `, ${h & 0x000000ff}` : '') + + ')' + ); +}; + +const hide = (...el) => [...el].forEach(e => (e.style.display = 'none')); + +const httpsRedirect = () => { + if (location.protocol !== 'https:') location.replace('https://' + location.href.split('//')[1]); +}; + +const initial = arr => arr.slice(0, -1); + +const initialize2DArray = (w, h, val = null) => + Array(h) + .fill() + .map(() => Array(w).fill(val)); + +const initializeArrayWithRange = (end, start = 0) => + Array.from({ length: end + 1 - start }).map((v, i) => i + start); + +const initializeArrayWithValues = (n, value = 0) => Array(n).fill(value); + +const inRange = (n, start, end = null) => { + if (end && start > end) end = [start, (start = end)][0]; + return end == null ? n >= 0 && n < start : n >= start && n < end; +}; + +const intersection = (a, b) => { + const s = new Set(b); + return a.filter(x => s.has(x)); +}; + +const invertKeyValues = obj => + Object.keys(obj).reduce((acc, key) => { + acc[obj[key]] = key; + return acc; + }, {}); + +const isAbsoluteURL = str => /^[a-z][a-z0-9+.-]*:/.test(str); + +const isArmstrongNumber = digits => + (arr => arr.reduce((a, d) => a + parseInt(d) ** arr.length, 0) == digits)( + (digits + '').split('') + ); + +const isArray = val => !!val && Array.isArray(val); + +const isArrayLike = val => { + try { + return [...val], true; + } catch (e) { + return false; + } +}; + +const isBoolean = val => typeof val === 'boolean'; + +const isDivisible = (dividend, divisor) => dividend % divisor === 0; + +const isEven = num => num % 2 === 0; + +const isFunction = val => val && typeof val === 'function'; + +const isNull = val => val === null; + +const isNumber = val => typeof val === 'number'; + +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 isPrimitive = val => !['object', 'function'].includes(typeof val) || val === null; + +const isPromiseLike = obj => + obj !== null && + (typeof obj === 'object' || typeof obj === 'function') && + typeof obj.then === 'function'; + +const isSorted = arr => { + const direction = arr[0] > arr[1] ? -1 : 1; + for (let [i, val] of arr.entries()) + if (i === arr.length - 1) return direction; + else if ((val - arr[i + 1]) * direction > 0) return 0; +}; + +const isString = val => typeof val === 'string'; + +const isSymbol = val => typeof val === 'symbol'; + +const isTravisCI = () => 'TRAVIS' in process.env && 'CI' in process.env; + +const isValidJSON = obj => { + try { + JSON.parse(obj); + return true; + } catch (e) { + return false; + } +}; + +const join = (arr, separator = ',', end = separator) => + arr.reduce( + (acc, val, i) => + i == arr.length - 2 + ? acc + val + end + : i == arr.length - 1 ? acc + val : acc + val + separator, + '' + ); + +const JSONToDate = arr => { + const dt = new Date(parseInt(arr.toString().substr(6))); + return `${dt.getDate()}/${dt.getMonth() + 1}/${dt.getFullYear()}`; +}; + +const fs = typeof require !== "undefined" && require('fs'); +const JSONToFile = (obj, filename) => + fs.writeFile(`${filename}.json`, JSON.stringify(obj, null, 2)); + +const last = arr => arr[arr.length - 1]; + +const lcm = (...arr) => { + const gcd = (x, y) => (!y ? x : gcd(y, x % y)); + const _lcm = (x, y) => x * y / gcd(x, y); + return [].concat(...arr).reduce((a, b) => _lcm(a, b)); +}; + +const lowercaseKeys = obj => + Object.keys(obj).reduce((acc, key) => { + acc[key.toLowerCase()] = obj[key]; + return acc; + }, {}); + +const mapObject = (arr, fn) => + (a => ( + a = [arr, arr.map(fn)], a[0].reduce((acc, val, ind) => (acc[val] = a[1][ind], acc), {})))(); + +const mask = (cc, num = 4, mask = '*') => + ('' + cc).slice(0, -num).replace(/./g, mask) + ('' + cc).slice(-num); + +const max = (...arr) => Math.max(...[].concat(...arr)); + +const median = arr => { + const mid = Math.floor(arr.length / 2), + nums = [...arr].sort((a, b) => a - b); + return arr.length % 2 !== 0 ? nums[mid] : (nums[mid - 1] + nums[mid]) / 2; +}; + +const memoize = fn => { + const cache = Object.create(null); + return value => cache[value] || (cache[value] = fn(value)); +}; + +const min = arr => Math.min(...[].concat(...arr)); + +const negate = func => (...args) => !func(...args); + +const nthElement = (arr, n = 0) => (n > 0 ? arr.slice(n, n + 1) : arr.slice(n))[0]; + +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 once = fn => { + let called = false; + return function(...args) { + if (called) return; + called = true; + return fn.apply(this, args); + }; +}; + +const onUserInputChange = callback => { + let type = 'mouse', + lastTime = 0; + const mousemoveHandler = () => { + const now = performance.now(); + if (now - lastTime < 20) + type = 'mouse', callback(type), document.removeEventListener('mousemove', mousemoveHandler); + lastTime = now; + }; + document.addEventListener('touchstart', () => { + if (type === 'touch') return; + type = 'touch', callback(type), document.addEventListener('mousemove', mousemoveHandler); + }); +}; + +const orderBy = (arr, props, orders) => + [...arr].sort((a, b) => + props.reduce((acc, prop, i) => { + if (acc === 0) { + const [p1, p2] = orders && orders[i] === 'desc' ? [b[prop], a[prop]] : [a[prop], b[prop]]; + acc = p1 > p2 ? 1 : p1 < p2 ? -1 : 0; + } + return acc; + }, 0) + ); + +const palindrome = str => { + const s = str.toLowerCase().replace(/[\W_]/g, ''); + return ( + s === + s + .split('') + .reverse() + .join('') + ); +}; + +const percentile = (arr, val) => + 100 * arr.reduce((acc, v) => acc + (v < val ? 1 : 0) + (v === val ? 0.5 : 0), 0) / arr.length; + +const pick = (obj, arr) => + arr.reduce((acc, curr) => (curr in obj && (acc[curr] = obj[curr]), acc), {}); + +const pipeFunctions = (...fns) => fns.reduce((f, g) => (...args) => g(f(...args))); + +const powerset = arr => arr.reduce((a, v) => a.concat(a.map(r => [v].concat(r))), [[]]); + +const prettyBytes = (num, precision = 3, addSpace = true) => { + const UNITS = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; + if (Math.abs(num) < 1) return num + (addSpace ? ' ' : '') + UNITS[0]; + const exponent = Math.min(Math.floor(Math.log10(num < 0 ? -num : num) / 3), UNITS.length - 1); + const n = Number(((num < 0 ? -num : num) / 1000 ** exponent).toPrecision(precision)); + return (num < 0 ? '-' : '') + n + (addSpace ? ' ' : '') + UNITS[exponent]; +}; + +const primes = num => { + let arr = Array.from({ length: num - 1 }).map((x, i) => i + 2), + sqroot = Math.floor(Math.sqrt(num)), + numsTillSqroot = Array.from({ length: sqroot - 1 }).map((x, i) => i + 2); + numsTillSqroot.forEach(x => (arr = arr.filter(y => y % x !== 0 || y == x))); + return arr; +}; + +const promisify = func => (...args) => + new Promise((resolve, reject) => + func(...args, (err, result) => (err ? reject(err) : resolve(result))) + ); + +const pull = (arr, ...args) => { + let argState = Array.isArray(args[0]) ? args[0] : args; + let pulled = arr.filter((v, i) => !argState.includes(v)); + arr.length = 0; + pulled.forEach(v => arr.push(v)); +}; + +const pullAtIndex = (arr, pullArr) => { + let removed = []; + let pulled = arr + .map((v, i) => (pullArr.includes(i) ? removed.push(v) : v)) + .filter((v, i) => !pullArr.includes(i)); + arr.length = 0; + pulled.forEach(v => arr.push(v)); + return removed; +}; + +const pullAtValue = (arr, pullArr) => { + let removed = [], + pushToRemove = arr.forEach((v, i) => (pullArr.includes(v) ? removed.push(v) : v)), + mutateTo = arr.filter((v, i) => !pullArr.includes(v)); + arr.length = 0; + mutateTo.forEach(v => arr.push(v)); + return removed; +}; + +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) + ]; + +const randomHexColorCode = () => { + let n = ((Math.random() * 0xfffff) | 0).toString(16); + return '#' + (n.length !== 6 ? ((Math.random() * 0xf) | 0).toString(16) + n : n); +}; + +const randomIntegerInRange = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min; + +const randomNumberInRange = (min, max) => Math.random() * (max - min) + min; + +const fs$1 = typeof require !== "undefined" && require('fs'); +const readFileLines = filename => + fs$1 + .readFileSync(filename) + .toString('UTF8') + .split('\n'); + +const redirect = (url, asLink = true) => + asLink ? (window.location.href = url) : window.location.replace(url); + +const reducedFilter = (data, keys, fn) => + data.filter(fn).map(el => + keys.reduce((acc, key) => { + acc[key] = el[key]; + return acc; + }, {}) + ); + +const remove = (arr, func) => + Array.isArray(arr) + ? arr.filter(func).reduce((acc, val) => { + arr.splice(arr.indexOf(val), 1); + return acc.concat(val); + }, []) + : []; + +const repeatString = (str = '', num = 2) => { + return num >= 0 ? str.repeat(num) : str; +}; + +const reverseString = str => + str + .split('') + .reverse() + .join(''); + +const RGBToHex = (r, g, b) => ((r << 16) + (g << 8) + b).toString(16).padStart(6, '0'); + +const round = (n, decimals = 0) => Number(`${Math.round(`${n}e${decimals}`)}e-${decimals}`); + +const runAsync = fn => { + const blob = ` + var fn = ${fn.toString()}; + this.postMessage(fn()); + `; + const worker = new Worker( + URL.createObjectURL(new Blob([blob]), { + type: 'application/javascript; charset=utf-8' + }) + ); + return new Promise((res, rej) => { + worker.onmessage = ({ data }) => { + res(data), worker.terminate(); + }; + worker.onerror = err => { + rej(err), worker.terminate(); + }; + }); +}; + +const runPromisesInSeries = ps => ps.reduce((p, next) => p.then(next), Promise.resolve()); + +const sample = arr => arr[Math.floor(Math.random() * arr.length)]; + +const sampleSize = ([...arr], n = 1) => { + let m = arr.length; + while (m) { + const i = Math.floor(Math.random() * m--); + [arr[m], arr[i]] = [arr[i], arr[m]]; + } + return arr.slice(0, n); +}; + +const scrollToTop = () => { + const c = document.documentElement.scrollTop || document.body.scrollTop; + if (c > 0) { + window.requestAnimationFrame(scrollToTop); + window.scrollTo(0, c - c / 8); + } +}; + +const sdbm = str => { + let arr = str.split(''); + return arr.reduce( + (hashCode, currentVal) => + (hashCode = currentVal.charCodeAt(0) + (hashCode << 6) + (hashCode << 16) - hashCode), + 0 + ); +}; + +const select = (from, selector) => + selector.split('.').reduce((prev, cur) => prev && prev[cur], from); + +const setStyle = (el, ruleName, value) => (el.style[ruleName] = value); + +const shallowClone = obj => Object.assign({}, obj); + +const show = (...el) => [...el].forEach(e => (e.style.display = '')); + +const shuffle = ([...arr]) => { + let m = arr.length; + while (m) { + const i = Math.floor(Math.random() * m--); + [arr[m], arr[i]] = [arr[i], arr[m]]; + } + return arr; +}; + +const similarity = (arr, values) => arr.filter(v => values.includes(v)); + +const size = value => + Array.isArray(value) + ? value.length + : value && typeof value === 'object' + ? value.size || value.length || Object.keys(value).length + : typeof value === 'string' ? new Blob([value]).size : 0; + +const sleep = ms => new Promise(resolve => setTimeout(resolve, ms)); + +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`; +}; + +const sortCharactersInString = str => + str + .split('') + .sort((a, b) => a.localeCompare(b)) + .join(''); + +const sortedIndex = (arr, n) => { + const isDescending = arr[0] > arr[arr.length - 1]; + const index = arr.findIndex(el => (isDescending ? n >= el : n <= el)); + return index === -1 ? arr.length : index; +}; + +const speechSynthesis = message => { + const msg = new SpeechSynthesisUtterance(message); + msg.voice = window.speechSynthesis.getVoices()[0]; + window.speechSynthesis.speak(msg); +}; + +const splitLines = str => str.split(/\r?\n/); + +const spreadOver = fn => argsArr => fn(...argsArr); + +const standardDeviation = (arr, usePopulation = false) => { + const mean = arr.reduce((acc, val) => acc + val, 0) / arr.length; + return Math.sqrt( + arr.reduce((acc, val) => acc.concat((val - mean) ** 2), []).reduce((acc, val) => acc + val, 0) / + (arr.length - (usePopulation ? 0 : 1)) + ); +}; + +const sum = (...arr) => [].concat(...arr).reduce((acc, val) => acc + val, 0); + +const sumPower = (end, power = 2, start = 1) => + Array(end + 1 - start) + .fill(0) + .map((x, i) => (i + start) ** power) + .reduce((a, b) => a + b, 0); + +const symmetricDifference = (a, b) => { + const sA = new Set(a), + sB = new Set(b); + return [...a.filter(x => !sB.has(x)), ...b.filter(x => !sA.has(x))]; +}; + +const tail = arr => (arr.length > 1 ? arr.slice(1) : arr); + +const take = (arr, n = 1) => arr.slice(0, n); + +const takeRight = (arr, n = 1) => arr.slice(arr.length - n, arr.length); + +const timeTaken = callback => { + console.time('timeTaken'); + const r = callback(); + console.timeEnd('timeTaken'); + return r; +}; + +const toCamelCase = str => { + let s = + str && + str + .match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g) + .map(x => x.slice(0, 1).toUpperCase() + x.slice(1).toLowerCase()) + .join(''); + return s.slice(0, 1).toLowerCase() + s.slice(1); +}; + +const toDecimalMark = num => num.toLocaleString('en-US'); + +const toEnglishDate = time => { + try { + return new Date(time) + .toISOString() + .split('T')[0] + .replace(/-/g, '/'); + } catch (e) {} +}; + +const toggleClass = (el, className) => el.classList.toggle(className); + +const toKebabCase = str => + str && + str + .match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g) + .map(x => x.toLowerCase()) + .join('-'); + +const tomorrow = () => new Date(new Date().getTime() + 86400000).toISOString().split('T')[0]; + +const toOrdinalSuffix = num => { + const int = parseInt(num), + digits = [int % 10, int % 100], + ordinals = ['st', 'nd', 'rd', 'th'], + oPattern = [1, 2, 3, 4], + tPattern = [11, 12, 13, 14, 15, 16, 17, 18, 19]; + return oPattern.includes(digits[0]) && !tPattern.includes(digits[1]) + ? int + ordinals[digits[0] - 1] + : int + ordinals[3]; +}; + +const toSnakeCase = str => + str && + str + .match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g) + .map(x => x.toLowerCase()) + .join('_'); + +const truncateString = (str, num) => + str.length > num ? str.slice(0, num > 3 ? num - 3 : num) + '...' : str; + +const truthCheckCollection = (collection, pre) => collection.every(obj => obj[pre]); + +const unescapeHTML = str => + str.replace( + /&|<|>|'|"/g, + tag => + ({ + '&': '&', + '<': '<', + '>': '>', + ''': "'", + '"': '"' + }[tag] || tag) + ); + +const union = (a, b) => Array.from(new Set([...a, ...b])); + +const untildify = str => str.replace(/^~($|\/|\\)/, `${typeof require !== "undefined" && require('os').homedir()}$1`); + +const UUIDGeneratorBrowser = () => + ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c => + (c ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4)))).toString(16) + ); + +const crypto$1 = typeof require !== "undefined" && require('crypto'); +const UUIDGeneratorNode = () => + ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c => + (c ^ (crypto$1.randomBytes(1)[0] & (15 >> (c / 4)))).toString(16) + ); + +const validateNumber = n => !isNaN(parseFloat(n)) && isFinite(n) && Number(n) == n; + +const without = (arr, ...args) => arr.filter(v => !args.includes(v)); + +const words = (str, pattern = /[^a-zA-Z-]+/) => str.split(pattern).filter(Boolean); + +const yesNo = (val, def = false) => + /^(y|yes)$/i.test(val) ? true : /^(n|no)$/i.test(val) ? false : def; + +const zip = (...arrays) => { + const maxLength = Math.max(...arrays.map(x => x.length)); + return Array.from({ length: maxLength }).map((_, i) => { + return Array.from({ length: arrays.length }, (_, k) => arrays[k][i]); + }); +}; + +const zipObject = (props, values) => + props.reduce((obj, prop, index) => (obj[prop] = values[index], obj), {}); + +var imports = {anagrams,arrayToHtmlList,average,bottomVisible,byteSize,call,capitalize,capitalizeEveryWord,chainAsync,chunk,clampNumber,cleanObj,cloneRegExp,coalesce,coalesceFactory,collatz,collectInto,compact,compose,copyToClipboard,countOccurrences,countVowels,currentURL,curry,deepFlatten,defer,detectDeviceType,difference,differenceWith,digitize,distance,distinctValuesOfArray,dropElements,dropRight,elementIsVisibleInViewport,elo,escapeHTML,escapeRegExp,everyNth,extendHex,factorial,fibonacci,fibonacciCountUntilNum,fibonacciUntilNum,filterNonUnique,flatten,flattenDepth,flip,fromCamelCase,functionName,gcd,getDaysDiffBetweenDates,getScrollPosition,getStyle,getType,getURLParameters,groupBy,hammingDistance,hasClass,hasFlags,head,hexToRGB,hide,httpsRedirect,initial,initialize2DArray,initializeArrayWithRange,initializeArrayWithValues,inRange,intersection,invertKeyValues,isAbsoluteURL,isArmstrongNumber,isArray,isArrayLike,isBoolean,isDivisible,isEven,isFunction,isNull,isNumber,isPrime,isPrimitive,isPromiseLike,isSorted,isString,isSymbol,isTravisCI,isValidJSON,join,JSONToDate,JSONToFile,last,lcm,lowercaseKeys,mapObject,mask,max,median,memoize,min,negate,nthElement,objectFromPairs,objectToPairs,once,onUserInputChange,orderBy,palindrome,percentile,pick,pipeFunctions,powerset,prettyBytes,primes,promisify,pull,pullAtIndex,pullAtValue,quickSort,randomHexColorCode,randomIntegerInRange,randomNumberInRange,readFileLines,redirect,reducedFilter,remove,repeatString,reverseString,RGBToHex,round,runAsync,runPromisesInSeries,sample,sampleSize,scrollToTop,sdbm,select,setStyle,shallowClone,show,shuffle,similarity,size,sleep,solveRPN,sortCharactersInString,sortedIndex,speechSynthesis,splitLines,spreadOver,standardDeviation,sum,sumPower,symmetricDifference,tail,take,takeRight,timeTaken,toCamelCase,toDecimalMark,toEnglishDate,toggleClass,toKebabCase,tomorrow,toOrdinalSuffix,toSnakeCase,truncateString,truthCheckCollection,unescapeHTML,union,untildify,UUIDGeneratorBrowser,UUIDGeneratorNode,validateNumber,without,words,yesNo,zip,zipObject,} + +export default imports; diff --git a/dist/_30s.js b/dist/_30s.js new file mode 100644 index 000000000..e53943229 --- /dev/null +++ b/dist/_30s.js @@ -0,0 +1,867 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define(factory) : + (global._30s = factory()); +}(this, (function () { 'use strict'; + +const anagrams = str => { + if (str.length <= 2) return str.length === 2 ? [str, str[1] + str[0]] : [str]; + return str + .split('') + .reduce( + (acc, letter, i) => + acc.concat(anagrams(str.slice(0, i) + str.slice(i + 1)).map(val => letter + val)), + [] + ); +}; + +const arrayToHtmlList = (arr, listID) => + arr.map(item => (document.querySelector('#' + listID).innerHTML += `
  • ${item}
  • `)); + +const average = (...arr) => { + const nums = [].concat(...arr); + return nums.reduce((acc, val) => acc + val, 0) / nums.length; +}; + +const bottomVisible = () => + document.documentElement.clientHeight + window.scrollY >= + (document.documentElement.scrollHeight || document.documentElement.clientHeight); + +const byteSize = str => new Blob([str]).size; + +const call = (key, ...args) => context => context[key](...args); + +const capitalize = ([first, ...rest], lowerRest = false) => + first.toUpperCase() + (lowerRest ? rest.join('').toLowerCase() : rest.join('')); + +const capitalizeEveryWord = str => str.replace(/\b[a-z]/g, char => char.toUpperCase()); + +const chainAsync = fns => { + let curr = 0; + const next = () => fns[curr++](next); + next(); +}; + +const chunk = (arr, size) => + Array.from({ length: Math.ceil(arr.length / size) }, (v, i) => + arr.slice(i * size, i * size + size) + ); + +const clampNumber = (num, a, b) => Math.max(Math.min(num, Math.max(a, b)), Math.min(a, b)); + +const cleanObj = (obj, keysToKeep = [], childIndicator) => { + Object.keys(obj).forEach(key => { + if (key === childIndicator) { + cleanObj(obj[key], keysToKeep, childIndicator); + } else if (!keysToKeep.includes(key)) { + delete obj[key]; + } + }); + return obj; +}; + +const cloneRegExp = regExp => new RegExp(regExp.source, regExp.flags); + +const coalesce = (...args) => args.find(_ => ![undefined, null].includes(_)); + +const coalesceFactory = valid => (...args) => args.find(valid); + +const collatz = n => (n % 2 == 0 ? n / 2 : 3 * n + 1); + +const collectInto = fn => (...args) => fn(args); + +const compact = arr => arr.filter(Boolean); + +const compose = (...fns) => fns.reduce((f, g) => (...args) => f(g(...args))); + +const copyToClipboard = str => { + const el = document.createElement('textarea'); + el.value = str; + el.setAttribute('readonly', ''); + el.style.position = 'absolute'; + el.style.left = '-9999px'; + document.body.appendChild(el); + const selected = + document.getSelection().rangeCount > 0 ? document.getSelection().getRangeAt(0) : false; + el.select(); + document.execCommand('copy'); + document.body.removeChild(el); + if (selected) { + document.getSelection().removeAllRanges(); + document.getSelection().addRange(selected); + } +}; + +const countOccurrences = (arr, value) => arr.reduce((a, v) => (v === value ? a + 1 : a + 0), 0); + +const countVowels = str => (str.match(/[aeiou]/gi) || []).length; + +const currentURL = () => window.location.href; + +const curry = (fn, arity = fn.length, ...args) => + arity <= args.length ? fn(...args) : curry.bind(null, fn, arity, ...args); + +const deepFlatten = arr => [].concat(...arr.map(v => (Array.isArray(v) ? deepFlatten(v) : v))); + +const defer = (fn, ...args) => setTimeout(fn, 1, ...args); + +const detectDeviceType = () => + /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) + ? 'Mobile' + : 'Desktop'; + +const difference = (a, b) => { + const s = new Set(b); + return a.filter(x => !s.has(x)); +}; + +const differenceWith = (arr, val, comp) => arr.filter(a => !val.find(b => comp(a, b))); + +const digitize = n => [...('' + n)].map(i => parseInt(i)); + +const distance = (x0, y0, x1, y1) => Math.hypot(x1 - x0, y1 - y0); + +const distinctValuesOfArray = arr => [...new Set(arr)]; + +const dropElements = (arr, func) => { + while (arr.length > 0 && !func(arr[0])) arr = arr.slice(1); + return arr; +}; + +const dropRight = (arr, n = 1) => arr.slice(0, -n); + +const elementIsVisibleInViewport = (el, partiallyVisible = false) => { + const { top, left, bottom, right } = el.getBoundingClientRect(); + const { innerHeight, innerWidth } = window; + return partiallyVisible + ? ((top > 0 && top < innerHeight) || (bottom > 0 && bottom < innerHeight)) && + ((left > 0 && left < innerWidth) || (right > 0 && right < innerWidth)) + : top >= 0 && left >= 0 && bottom <= innerHeight && right <= innerWidth; +}; + +const elo = ([a, b], kFactor = 32) => { + const expectedScore = (self, opponent) => 1 / (1 + 10 ** ((opponent - self) / 400)); + const newRating = (rating, i) => rating + kFactor * (i - expectedScore(i ? a : b, i ? b : a)); + return [newRating(a, 1), newRating(b, 0)]; +}; + +const escapeHTML = str => + str.replace( + /[&<>'"]/g, + tag => + ({ + '&': '&', + '<': '<', + '>': '>', + "'": ''', + '"': '"' + }[tag] || tag) + ); + +const escapeRegExp = str => str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); + +const everyNth = (arr, nth) => arr.filter((e, i) => i % nth === nth - 1); + +const extendHex = shortHex => + '#' + + shortHex + .slice(shortHex.startsWith('#') ? 1 : 0) + .split('') + .map(x => x + x) + .join(''); + +const factorial = n => + n < 0 + ? (() => { + throw new TypeError('Negative numbers are not allowed!'); + })() + : n <= 1 ? 1 : n * factorial(n - 1); + +const fibonacci = n => + Array.from({ length: n }).reduce( + (acc, val, i) => acc.concat(i > 1 ? acc[i - 1] + acc[i - 2] : i), + [] + ); + +const fibonacciCountUntilNum = num => + Math.ceil(Math.log(num * Math.sqrt(5) + 1 / 2) / Math.log((Math.sqrt(5) + 1) / 2)); + +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), + [] + ); +}; + +const filterNonUnique = arr => arr.filter(i => arr.indexOf(i) === arr.lastIndexOf(i)); + +const flatten = arr => [].concat(...arr); + +const flattenDepth = (arr, depth = 1) => + depth != 1 + ? arr.reduce((a, v) => a.concat(Array.isArray(v) ? flattenDepth(v, depth - 1) : v), []) + : arr.reduce((a, v) => a.concat(v), []); + +const flip = fn => (...args) => fn(args.pop(), ...args); + +const fromCamelCase = (str, separator = '_') => + str + .replace(/([a-z\d])([A-Z])/g, '$1' + separator + '$2') + .replace(/([A-Z]+)([A-Z][a-z\d]+)/g, '$1' + separator + '$2') + .toLowerCase(); + +const functionName = fn => (console.debug(fn.name), fn); + +const gcd = (...arr) => { + let data = [].concat(...arr); + const helperGcd = (x, y) => (!y ? x : gcd(y, x % y)); + return data.reduce((a, b) => helperGcd(a, b)); +}; + +const getDaysDiffBetweenDates = (dateInitial, dateFinal) => + (dateFinal - dateInitial) / (1000 * 3600 * 24); + +const getScrollPosition = (el = window) => ({ + x: el.pageXOffset !== undefined ? el.pageXOffset : el.scrollLeft, + y: el.pageYOffset !== undefined ? el.pageYOffset : el.scrollTop +}); + +const getStyle = (el, ruleName) => getComputedStyle(el)[ruleName]; + +const getType = v => + v === undefined ? 'undefined' : v === null ? 'null' : v.constructor.name.toLowerCase(); + +const getURLParameters = url => + url + .match(/([^?=&]+)(=([^&]*))/g) + .reduce((a, v) => (a[v.slice(0, v.indexOf('='))] = v.slice(v.indexOf('=') + 1), a), {}); + +const groupBy = (arr, func) => + arr.map(typeof func === 'function' ? func : val => val[func]).reduce((acc, val, i) => { + acc[val] = (acc[val] || []).concat(arr[i]); + return acc; + }, {}); + +const hammingDistance = (num1, num2) => ((num1 ^ num2).toString(2).match(/1/g) || '').length; + +const hasClass = (el, className) => el.classList.contains(className); + +const hasFlags = (...flags) => + flags.every(flag => process.argv.includes(/^-{1,2}/.test(flag) ? flag : '--' + flag)); + +const head = arr => arr[0]; + +const hexToRGB = hex => { + let alpha = false, + h = hex.slice(hex.startsWith('#') ? 1 : 0); + if (h.length === 3) h = [...h].map(x => x + x).join(''); + else if (h.length === 8) alpha = true; + h = parseInt(h, 16); + return ( + 'rgb' + + (alpha ? 'a' : '') + + '(' + + (h >>> (alpha ? 24 : 16)) + + ', ' + + ((h & (alpha ? 0x00ff0000 : 0x00ff00)) >>> (alpha ? 16 : 8)) + + ', ' + + ((h & (alpha ? 0x0000ff00 : 0x0000ff)) >>> (alpha ? 8 : 0)) + + (alpha ? `, ${h & 0x000000ff}` : '') + + ')' + ); +}; + +const hide = (...el) => [...el].forEach(e => (e.style.display = 'none')); + +const httpsRedirect = () => { + if (location.protocol !== 'https:') location.replace('https://' + location.href.split('//')[1]); +}; + +const initial = arr => arr.slice(0, -1); + +const initialize2DArray = (w, h, val = null) => + Array(h) + .fill() + .map(() => Array(w).fill(val)); + +const initializeArrayWithRange = (end, start = 0) => + Array.from({ length: end + 1 - start }).map((v, i) => i + start); + +const initializeArrayWithValues = (n, value = 0) => Array(n).fill(value); + +const inRange = (n, start, end = null) => { + if (end && start > end) end = [start, (start = end)][0]; + return end == null ? n >= 0 && n < start : n >= start && n < end; +}; + +const intersection = (a, b) => { + const s = new Set(b); + return a.filter(x => s.has(x)); +}; + +const invertKeyValues = obj => + Object.keys(obj).reduce((acc, key) => { + acc[obj[key]] = key; + return acc; + }, {}); + +const isAbsoluteURL = str => /^[a-z][a-z0-9+.-]*:/.test(str); + +const isArmstrongNumber = digits => + (arr => arr.reduce((a, d) => a + parseInt(d) ** arr.length, 0) == digits)( + (digits + '').split('') + ); + +const isArray = val => !!val && Array.isArray(val); + +const isArrayLike = val => { + try { + return [...val], true; + } catch (e) { + return false; + } +}; + +const isBoolean = val => typeof val === 'boolean'; + +const isDivisible = (dividend, divisor) => dividend % divisor === 0; + +const isEven = num => num % 2 === 0; + +const isFunction = val => val && typeof val === 'function'; + +const isNull = val => val === null; + +const isNumber = val => typeof val === 'number'; + +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 isPrimitive = val => !['object', 'function'].includes(typeof val) || val === null; + +const isPromiseLike = obj => + obj !== null && + (typeof obj === 'object' || typeof obj === 'function') && + typeof obj.then === 'function'; + +const isSorted = arr => { + const direction = arr[0] > arr[1] ? -1 : 1; + for (let [i, val] of arr.entries()) + if (i === arr.length - 1) return direction; + else if ((val - arr[i + 1]) * direction > 0) return 0; +}; + +const isString = val => typeof val === 'string'; + +const isSymbol = val => typeof val === 'symbol'; + +const isTravisCI = () => 'TRAVIS' in process.env && 'CI' in process.env; + +const isValidJSON = obj => { + try { + JSON.parse(obj); + return true; + } catch (e) { + return false; + } +}; + +const join = (arr, separator = ',', end = separator) => + arr.reduce( + (acc, val, i) => + i == arr.length - 2 + ? acc + val + end + : i == arr.length - 1 ? acc + val : acc + val + separator, + '' + ); + +const JSONToDate = arr => { + const dt = new Date(parseInt(arr.toString().substr(6))); + return `${dt.getDate()}/${dt.getMonth() + 1}/${dt.getFullYear()}`; +}; + +const fs = typeof require !== "undefined" && require('fs'); +const JSONToFile = (obj, filename) => + fs.writeFile(`${filename}.json`, JSON.stringify(obj, null, 2)); + +const last = arr => arr[arr.length - 1]; + +const lcm = (...arr) => { + const gcd = (x, y) => (!y ? x : gcd(y, x % y)); + const _lcm = (x, y) => x * y / gcd(x, y); + return [].concat(...arr).reduce((a, b) => _lcm(a, b)); +}; + +const lowercaseKeys = obj => + Object.keys(obj).reduce((acc, key) => { + acc[key.toLowerCase()] = obj[key]; + return acc; + }, {}); + +const mapObject = (arr, fn) => + (a => ( + a = [arr, arr.map(fn)], a[0].reduce((acc, val, ind) => (acc[val] = a[1][ind], acc), {})))(); + +const mask = (cc, num = 4, mask = '*') => + ('' + cc).slice(0, -num).replace(/./g, mask) + ('' + cc).slice(-num); + +const max = (...arr) => Math.max(...[].concat(...arr)); + +const median = arr => { + const mid = Math.floor(arr.length / 2), + nums = [...arr].sort((a, b) => a - b); + return arr.length % 2 !== 0 ? nums[mid] : (nums[mid - 1] + nums[mid]) / 2; +}; + +const memoize = fn => { + const cache = Object.create(null); + return value => cache[value] || (cache[value] = fn(value)); +}; + +const min = arr => Math.min(...[].concat(...arr)); + +const negate = func => (...args) => !func(...args); + +const nthElement = (arr, n = 0) => (n > 0 ? arr.slice(n, n + 1) : arr.slice(n))[0]; + +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 once = fn => { + let called = false; + return function(...args) { + if (called) return; + called = true; + return fn.apply(this, args); + }; +}; + +const onUserInputChange = callback => { + let type = 'mouse', + lastTime = 0; + const mousemoveHandler = () => { + const now = performance.now(); + if (now - lastTime < 20) + type = 'mouse', callback(type), document.removeEventListener('mousemove', mousemoveHandler); + lastTime = now; + }; + document.addEventListener('touchstart', () => { + if (type === 'touch') return; + type = 'touch', callback(type), document.addEventListener('mousemove', mousemoveHandler); + }); +}; + +const orderBy = (arr, props, orders) => + [...arr].sort((a, b) => + props.reduce((acc, prop, i) => { + if (acc === 0) { + const [p1, p2] = orders && orders[i] === 'desc' ? [b[prop], a[prop]] : [a[prop], b[prop]]; + acc = p1 > p2 ? 1 : p1 < p2 ? -1 : 0; + } + return acc; + }, 0) + ); + +const palindrome = str => { + const s = str.toLowerCase().replace(/[\W_]/g, ''); + return ( + s === + s + .split('') + .reverse() + .join('') + ); +}; + +const percentile = (arr, val) => + 100 * arr.reduce((acc, v) => acc + (v < val ? 1 : 0) + (v === val ? 0.5 : 0), 0) / arr.length; + +const pick = (obj, arr) => + arr.reduce((acc, curr) => (curr in obj && (acc[curr] = obj[curr]), acc), {}); + +const pipeFunctions = (...fns) => fns.reduce((f, g) => (...args) => g(f(...args))); + +const powerset = arr => arr.reduce((a, v) => a.concat(a.map(r => [v].concat(r))), [[]]); + +const prettyBytes = (num, precision = 3, addSpace = true) => { + const UNITS = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; + if (Math.abs(num) < 1) return num + (addSpace ? ' ' : '') + UNITS[0]; + const exponent = Math.min(Math.floor(Math.log10(num < 0 ? -num : num) / 3), UNITS.length - 1); + const n = Number(((num < 0 ? -num : num) / 1000 ** exponent).toPrecision(precision)); + return (num < 0 ? '-' : '') + n + (addSpace ? ' ' : '') + UNITS[exponent]; +}; + +const primes = num => { + let arr = Array.from({ length: num - 1 }).map((x, i) => i + 2), + sqroot = Math.floor(Math.sqrt(num)), + numsTillSqroot = Array.from({ length: sqroot - 1 }).map((x, i) => i + 2); + numsTillSqroot.forEach(x => (arr = arr.filter(y => y % x !== 0 || y == x))); + return arr; +}; + +const promisify = func => (...args) => + new Promise((resolve, reject) => + func(...args, (err, result) => (err ? reject(err) : resolve(result))) + ); + +const pull = (arr, ...args) => { + let argState = Array.isArray(args[0]) ? args[0] : args; + let pulled = arr.filter((v, i) => !argState.includes(v)); + arr.length = 0; + pulled.forEach(v => arr.push(v)); +}; + +const pullAtIndex = (arr, pullArr) => { + let removed = []; + let pulled = arr + .map((v, i) => (pullArr.includes(i) ? removed.push(v) : v)) + .filter((v, i) => !pullArr.includes(i)); + arr.length = 0; + pulled.forEach(v => arr.push(v)); + return removed; +}; + +const pullAtValue = (arr, pullArr) => { + let removed = [], + pushToRemove = arr.forEach((v, i) => (pullArr.includes(v) ? removed.push(v) : v)), + mutateTo = arr.filter((v, i) => !pullArr.includes(v)); + arr.length = 0; + mutateTo.forEach(v => arr.push(v)); + return removed; +}; + +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) + ]; + +const randomHexColorCode = () => { + let n = ((Math.random() * 0xfffff) | 0).toString(16); + return '#' + (n.length !== 6 ? ((Math.random() * 0xf) | 0).toString(16) + n : n); +}; + +const randomIntegerInRange = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min; + +const randomNumberInRange = (min, max) => Math.random() * (max - min) + min; + +const fs$1 = typeof require !== "undefined" && require('fs'); +const readFileLines = filename => + fs$1 + .readFileSync(filename) + .toString('UTF8') + .split('\n'); + +const redirect = (url, asLink = true) => + asLink ? (window.location.href = url) : window.location.replace(url); + +const reducedFilter = (data, keys, fn) => + data.filter(fn).map(el => + keys.reduce((acc, key) => { + acc[key] = el[key]; + return acc; + }, {}) + ); + +const remove = (arr, func) => + Array.isArray(arr) + ? arr.filter(func).reduce((acc, val) => { + arr.splice(arr.indexOf(val), 1); + return acc.concat(val); + }, []) + : []; + +const repeatString = (str = '', num = 2) => { + return num >= 0 ? str.repeat(num) : str; +}; + +const reverseString = str => + str + .split('') + .reverse() + .join(''); + +const RGBToHex = (r, g, b) => ((r << 16) + (g << 8) + b).toString(16).padStart(6, '0'); + +const round = (n, decimals = 0) => Number(`${Math.round(`${n}e${decimals}`)}e-${decimals}`); + +const runAsync = fn => { + const blob = ` + var fn = ${fn.toString()}; + this.postMessage(fn()); + `; + const worker = new Worker( + URL.createObjectURL(new Blob([blob]), { + type: 'application/javascript; charset=utf-8' + }) + ); + return new Promise((res, rej) => { + worker.onmessage = ({ data }) => { + res(data), worker.terminate(); + }; + worker.onerror = err => { + rej(err), worker.terminate(); + }; + }); +}; + +const runPromisesInSeries = ps => ps.reduce((p, next) => p.then(next), Promise.resolve()); + +const sample = arr => arr[Math.floor(Math.random() * arr.length)]; + +const sampleSize = ([...arr], n = 1) => { + let m = arr.length; + while (m) { + const i = Math.floor(Math.random() * m--); + [arr[m], arr[i]] = [arr[i], arr[m]]; + } + return arr.slice(0, n); +}; + +const scrollToTop = () => { + const c = document.documentElement.scrollTop || document.body.scrollTop; + if (c > 0) { + window.requestAnimationFrame(scrollToTop); + window.scrollTo(0, c - c / 8); + } +}; + +const sdbm = str => { + let arr = str.split(''); + return arr.reduce( + (hashCode, currentVal) => + (hashCode = currentVal.charCodeAt(0) + (hashCode << 6) + (hashCode << 16) - hashCode), + 0 + ); +}; + +const select = (from, selector) => + selector.split('.').reduce((prev, cur) => prev && prev[cur], from); + +const setStyle = (el, ruleName, value) => (el.style[ruleName] = value); + +const shallowClone = obj => Object.assign({}, obj); + +const show = (...el) => [...el].forEach(e => (e.style.display = '')); + +const shuffle = ([...arr]) => { + let m = arr.length; + while (m) { + const i = Math.floor(Math.random() * m--); + [arr[m], arr[i]] = [arr[i], arr[m]]; + } + return arr; +}; + +const similarity = (arr, values) => arr.filter(v => values.includes(v)); + +const size = value => + Array.isArray(value) + ? value.length + : value && typeof value === 'object' + ? value.size || value.length || Object.keys(value).length + : typeof value === 'string' ? new Blob([value]).size : 0; + +const sleep = ms => new Promise(resolve => setTimeout(resolve, ms)); + +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`; +}; + +const sortCharactersInString = str => + str + .split('') + .sort((a, b) => a.localeCompare(b)) + .join(''); + +const sortedIndex = (arr, n) => { + const isDescending = arr[0] > arr[arr.length - 1]; + const index = arr.findIndex(el => (isDescending ? n >= el : n <= el)); + return index === -1 ? arr.length : index; +}; + +const speechSynthesis = message => { + const msg = new SpeechSynthesisUtterance(message); + msg.voice = window.speechSynthesis.getVoices()[0]; + window.speechSynthesis.speak(msg); +}; + +const splitLines = str => str.split(/\r?\n/); + +const spreadOver = fn => argsArr => fn(...argsArr); + +const standardDeviation = (arr, usePopulation = false) => { + const mean = arr.reduce((acc, val) => acc + val, 0) / arr.length; + return Math.sqrt( + arr.reduce((acc, val) => acc.concat((val - mean) ** 2), []).reduce((acc, val) => acc + val, 0) / + (arr.length - (usePopulation ? 0 : 1)) + ); +}; + +const sum = (...arr) => [].concat(...arr).reduce((acc, val) => acc + val, 0); + +const sumPower = (end, power = 2, start = 1) => + Array(end + 1 - start) + .fill(0) + .map((x, i) => (i + start) ** power) + .reduce((a, b) => a + b, 0); + +const symmetricDifference = (a, b) => { + const sA = new Set(a), + sB = new Set(b); + return [...a.filter(x => !sB.has(x)), ...b.filter(x => !sA.has(x))]; +}; + +const tail = arr => (arr.length > 1 ? arr.slice(1) : arr); + +const take = (arr, n = 1) => arr.slice(0, n); + +const takeRight = (arr, n = 1) => arr.slice(arr.length - n, arr.length); + +const timeTaken = callback => { + console.time('timeTaken'); + const r = callback(); + console.timeEnd('timeTaken'); + return r; +}; + +const toCamelCase = str => { + let s = + str && + str + .match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g) + .map(x => x.slice(0, 1).toUpperCase() + x.slice(1).toLowerCase()) + .join(''); + return s.slice(0, 1).toLowerCase() + s.slice(1); +}; + +const toDecimalMark = num => num.toLocaleString('en-US'); + +const toEnglishDate = time => { + try { + return new Date(time) + .toISOString() + .split('T')[0] + .replace(/-/g, '/'); + } catch (e) {} +}; + +const toggleClass = (el, className) => el.classList.toggle(className); + +const toKebabCase = str => + str && + str + .match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g) + .map(x => x.toLowerCase()) + .join('-'); + +const tomorrow = () => new Date(new Date().getTime() + 86400000).toISOString().split('T')[0]; + +const toOrdinalSuffix = num => { + const int = parseInt(num), + digits = [int % 10, int % 100], + ordinals = ['st', 'nd', 'rd', 'th'], + oPattern = [1, 2, 3, 4], + tPattern = [11, 12, 13, 14, 15, 16, 17, 18, 19]; + return oPattern.includes(digits[0]) && !tPattern.includes(digits[1]) + ? int + ordinals[digits[0] - 1] + : int + ordinals[3]; +}; + +const toSnakeCase = str => + str && + str + .match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g) + .map(x => x.toLowerCase()) + .join('_'); + +const truncateString = (str, num) => + str.length > num ? str.slice(0, num > 3 ? num - 3 : num) + '...' : str; + +const truthCheckCollection = (collection, pre) => collection.every(obj => obj[pre]); + +const unescapeHTML = str => + str.replace( + /&|<|>|'|"/g, + tag => + ({ + '&': '&', + '<': '<', + '>': '>', + ''': "'", + '"': '"' + }[tag] || tag) + ); + +const union = (a, b) => Array.from(new Set([...a, ...b])); + +const untildify = str => str.replace(/^~($|\/|\\)/, `${typeof require !== "undefined" && require('os').homedir()}$1`); + +const UUIDGeneratorBrowser = () => + ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c => + (c ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4)))).toString(16) + ); + +const crypto$1 = typeof require !== "undefined" && require('crypto'); +const UUIDGeneratorNode = () => + ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c => + (c ^ (crypto$1.randomBytes(1)[0] & (15 >> (c / 4)))).toString(16) + ); + +const validateNumber = n => !isNaN(parseFloat(n)) && isFinite(n) && Number(n) == n; + +const without = (arr, ...args) => arr.filter(v => !args.includes(v)); + +const words = (str, pattern = /[^a-zA-Z-]+/) => str.split(pattern).filter(Boolean); + +const yesNo = (val, def = false) => + /^(y|yes)$/i.test(val) ? true : /^(n|no)$/i.test(val) ? false : def; + +const zip = (...arrays) => { + const maxLength = Math.max(...arrays.map(x => x.length)); + return Array.from({ length: maxLength }).map((_, i) => { + return Array.from({ length: arrays.length }, (_, k) => arrays[k][i]); + }); +}; + +const zipObject = (props, values) => + props.reduce((obj, prop, index) => (obj[prop] = values[index], obj), {}); + +var imports = {anagrams,arrayToHtmlList,average,bottomVisible,byteSize,call,capitalize,capitalizeEveryWord,chainAsync,chunk,clampNumber,cleanObj,cloneRegExp,coalesce,coalesceFactory,collatz,collectInto,compact,compose,copyToClipboard,countOccurrences,countVowels,currentURL,curry,deepFlatten,defer,detectDeviceType,difference,differenceWith,digitize,distance,distinctValuesOfArray,dropElements,dropRight,elementIsVisibleInViewport,elo,escapeHTML,escapeRegExp,everyNth,extendHex,factorial,fibonacci,fibonacciCountUntilNum,fibonacciUntilNum,filterNonUnique,flatten,flattenDepth,flip,fromCamelCase,functionName,gcd,getDaysDiffBetweenDates,getScrollPosition,getStyle,getType,getURLParameters,groupBy,hammingDistance,hasClass,hasFlags,head,hexToRGB,hide,httpsRedirect,initial,initialize2DArray,initializeArrayWithRange,initializeArrayWithValues,inRange,intersection,invertKeyValues,isAbsoluteURL,isArmstrongNumber,isArray,isArrayLike,isBoolean,isDivisible,isEven,isFunction,isNull,isNumber,isPrime,isPrimitive,isPromiseLike,isSorted,isString,isSymbol,isTravisCI,isValidJSON,join,JSONToDate,JSONToFile,last,lcm,lowercaseKeys,mapObject,mask,max,median,memoize,min,negate,nthElement,objectFromPairs,objectToPairs,once,onUserInputChange,orderBy,palindrome,percentile,pick,pipeFunctions,powerset,prettyBytes,primes,promisify,pull,pullAtIndex,pullAtValue,quickSort,randomHexColorCode,randomIntegerInRange,randomNumberInRange,readFileLines,redirect,reducedFilter,remove,repeatString,reverseString,RGBToHex,round,runAsync,runPromisesInSeries,sample,sampleSize,scrollToTop,sdbm,select,setStyle,shallowClone,show,shuffle,similarity,size,sleep,solveRPN,sortCharactersInString,sortedIndex,speechSynthesis,splitLines,spreadOver,standardDeviation,sum,sumPower,symmetricDifference,tail,take,takeRight,timeTaken,toCamelCase,toDecimalMark,toEnglishDate,toggleClass,toKebabCase,tomorrow,toOrdinalSuffix,toSnakeCase,truncateString,truthCheckCollection,unescapeHTML,union,untildify,UUIDGeneratorBrowser,UUIDGeneratorNode,validateNumber,without,words,yesNo,zip,zipObject,} + +return imports; + +}))); diff --git a/dist/_30s.min.js b/dist/_30s.min.js new file mode 100644 index 000000000..53c87c5d9 --- /dev/null +++ b/dist/_30s.min.js @@ -0,0 +1,4 @@ +(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.floor,b=Math.sqrt,c=Math.log,d=Math.min,e=Math.max,f=Math.ceil;const g=(a)=>2>=a.length?2===a.length?[a,a[1]+a[0]]:[a]:a.split('').reduce((b,c,d)=>b.concat(g(a.slice(0,d)+a.slice(d+1)).map((a)=>c+a)),[]),h=(a,b=[],c)=>(Object.keys(a).forEach((d)=>{d===c?h(a[d],b,c):!b.includes(d)&&delete a[d]}),a),i=(a,b=a.length,...c)=>b<=c.length?a(...c):i.bind(null,a,b,...c),j=(a)=>[].concat(...a.map((a)=>Array.isArray(a)?j(a):a)),k=(a)=>0>a?(()=>{throw new TypeError('Negative numbers are not allowed!')})():1>=a?1:a*k(a-1),l=(a,b=1)=>1==b?a.reduce((b,a)=>b.concat(a),[]):a.reduce((c,a)=>c.concat(Array.isArray(a)?l(a,b-1):a),[]),m=(...a)=>{let b=[].concat(...a);const c=(a,b)=>b?m(b,a%b):a;return b.reduce((d,a)=>c(d,a))},n='undefined'!=typeof require&&require('fs'),o=([a,...b],c)=>isNaN(a)?[]:[...o(b.filter((b)=>c?b>a:b<=a),c),a,...o(b.filter((b)=>c?b<=a:b>a),c)],p='undefined'!=typeof require&&require('fs'),q=()=>{const a=document.documentElement.scrollTop||document.body.scrollTop;0a.map((a)=>document.querySelector('#'+b).innerHTML+=`
  • ${a}
  • `),average:(...a)=>{const b=[].concat(...a);return b.reduce((a,b)=>a+b,0)/b.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:f(a.length/b)},(c,d)=>a.slice(d*b,d*b+b)),clampNumber:(c,f,a)=>e(d(c,e(f,a)),d(f,a)),cleanObj:h,cloneRegExp:(a)=>new RegExp(a.source,a.flags),coalesce:(...a)=>a.find((a)=>![void 0,null].includes(a)),coalesceFactory:(a)=>(...b)=>b.find(a),collatz:(a)=>0==a%2?a/2:3*a+1,collectInto:(a)=>(...b)=>a(b),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.reduce((c,a)=>a===b?c+1:c+0,0),countVowels:(a)=>(a.match(/[aeiou]/gi)||[]).length,currentURL:()=>window.location.href,curry:i,deepFlatten:j,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)=>!b.find((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?(0{const d=(a,b)=>1/(1+10**((b-a)/400)),e=(e,f)=>e+b*(f-d(f?c:a,f?a:c));return[e(c,1),e(a,0)]},escapeHTML:(a)=>a.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:k,fibonacci:(a)=>Array.from({length:a}).reduce((a,b,c)=>a.concat(1f(c(2.23606797749979*a+1/2)/0.48121182505960347),fibonacciUntilNum:(a)=>{let b=f(c(2.23606797749979*a+1/2)/0.48121182505960347);return Array.from({length:b}).reduce((a,b,c)=>a.concat(1a.filter((b)=>a.indexOf(b)===a.lastIndexOf(b)),flatten:(a)=>[].concat(...a),flattenDepth:l,flip:(a)=>(...b)=>a(b.pop(),...b),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),gcd:m,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'),httpsRedirect:()=>{'https:'!==location.protocol&&location.replace('https://'+location.href.split('//')[1])},initial:(a)=>a.slice(0,-1),initialize2DArray:(a,b,c=null)=>Array(b).fill().map(()=>Array(a).fill(c)),initializeArrayWithRange:(a,b=0)=>Array.from({length:a+1-b}).map((a,c)=>c+b),initializeArrayWithValues:(a,b=0)=>Array(a).fill(b),inRange:(a,b,c=null)=>(c&&b>c&&(c=b),null==c?0<=a&&a=b&&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),isArmstrongNumber:(a)=>((b)=>b.reduce((c,a)=>c+parseInt(a)**b.length,0)==a)((a+'').split('')),isArray:(a)=>!!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)=>a&&'function'==typeof a,isNull:(a)=>null===a,isNumber:(a)=>'number'==typeof a,isPrime:(c)=>{const d=a(b(c));for(var e=2;e<=d;e++)if(0==c%e)return!1;return 2<=c},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,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,''),JSONToDate:(a)=>{const b=new Date(parseInt(a.toString().substr(6)));return`${b.getDate()}/${b.getMonth()+1}/${b.getFullYear()}`},JSONToFile:(a,b)=>n.writeFile(`${b}.json`,JSON.stringify(a,null,2)),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[].concat(...a).reduce((d,a)=>c(d,a))},lowercaseKeys:(a)=>Object.keys(a).reduce((b,c)=>(b[c.toLowerCase()]=a[c],b),{}),mapObject:(b,c)=>((d)=>(d=[b,b.map(c)],d[0].reduce((a,b,c)=>(a[b]=d[1][c],a),{})))(),mask:(a,b=4,c='*')=>(''+a).slice(0,-b).replace(/./g,c)+(''+a).slice(-b),max:(...a)=>e(...[].concat(...a)),median:(b)=>{const c=a(b.length/2),d=[...b].sort((c,a)=>c-a);return 0==b.length%2?(d[c-1]+d[c])/2:d[c]},memoize:(a)=>{const b=Object.create(null);return(c)=>b[c]||(b[c]=a(c))},min:(a)=>d(...[].concat(...a)),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]]),once:(a)=>{let b=!1;return function(...c){if(!b)return b=!0,a.apply(this,c)}},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))})},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('')},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))),powerset:(a)=>a.reduce((b,a)=>b.concat(b.map((b)=>[a].concat(b))),[[]]),prettyBytes:(b,c=3,e=!0)=>{const f=['B','KB','MB','GB','TB','PB','EB','ZB','YB'];if(1>Math.abs(b))return b+(e?' ':'')+f[0];const g=d(a(Math.log10(0>b?-b:b)/3),f.length-1),h=+((0>b?-b:b)/1e3**g).toPrecision(c);return(0>b?'-':'')+h+(e?' ':'')+f[g]},primes:(c)=>{let d=Array.from({length:c-1}).map((a,b)=>b+2),e=a(b(c)),f=Array.from({length:e-1}).map((a,b)=>b+2);return f.forEach((a)=>d=d.filter((b)=>0!=b%a||b==a)),d},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},quickSort:o,randomHexColorCode:()=>{let a=(0|1048575*Math.random()).toString(16);return'#'+(6===a.length?a:(0|15*Math.random()).toString(16)+a)},randomIntegerInRange:(b,c)=>a(Math.random()*(c-b+1))+b,randomNumberInRange:(a,b)=>Math.random()*(b-a)+a,readFileLines:(a)=>p.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)),[]):[],repeatString:(a='',b=2)=>0<=b?a.repeat(b):a,reverseString:(a)=>a.split('').reverse().join(''),RGBToHex:(a,c,d)=>((a<<16)+(c<<8)+d).toString(16).padStart(6,'0'),round:(a,b=0)=>+`${Math.round(`${a}e${b}`)}e-${b}`,runAsync:(a)=>{const b=` + var fn = ${a.toString()}; + this.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:(b)=>b[a(Math.random()*b.length)],sampleSize:([...b],c=1)=>{for(let d=b.length;d;){const c=a(Math.random()*d--);[b[d],b[c]]=[b[c],b[d]]}return b.slice(0,c)},scrollToTop:q,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.split('.').reduce((a,b)=>a&&a[b],a),setStyle:(a,b,c)=>a.style[b]=c,shallowClone:(a)=>Object.assign({},a),show:(...a)=>[...a].forEach((a)=>a.style.display=''),shuffle:([...b])=>{for(let c=b.length;c;){const d=a(Math.random()*c--);[b[c],b[d]]=[b[d],b[c]]}return b},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)),solveRPN:(a)=>{const c={"*":(c,a)=>c*a,"+":(c,a)=>c+a,"-":(c,a)=>c-a,"/":(c,a)=>c/a,"**":(c,a)=>c**a},[d,b]=[[],a.replace(/\^/g,'**').split(/\s+/g).filter((a)=>!/\s+/.test(a)&&''!==a)];if(b.forEach((e)=>{if(!isNaN(parseFloat(e))&&isFinite(e))d.push(e);else if(Object.keys(c).includes(e)){const[f,a]=[d.pop(),d.pop()];d.push(c[e](parseFloat(a),parseFloat(f)))}else throw`${e} is not a recognized symbol`}),1===d.length)return d.pop();throw`${a} is not a proper RPN. Please check it and try again`},sortCharactersInString:(a)=>a.split('').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},speechSynthesis:(a)=>{const b=new SpeechSynthesisUtterance(a);b.voice=window.speechSynthesis.getVoices()[0],window.speechSynthesis.speak(b)},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)=>[].concat(...a).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'),toEnglishDate:(a)=>{try{return new Date(a).toISOString().split('T')[0].replace(/-/g,'/')}catch(a){}},toggleClass:(a,b)=>a.classList.toggle(b),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('-'),tomorrow:()=>new Date(new Date().getTime()+8.64e7).toISOString().split('T')[0],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]},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('_'),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`),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^r.randomBytes(1)[0]&15>>a/4).toString(16)),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=e(...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/docs/index.html b/docs/index.html index bf8aeebab..404494945 100644 --- a/docs/index.html +++ b/docs/index.html @@ -59,7 +59,7 @@ wrapper.appendChild(box); box.appendChild(el); }); - }

     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);
    +    }

     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 ]
    @@ -152,10 +152,11 @@ groupBy(['one', 'two', 'three'], 'length'); // {3: ['one', 'two'], 5: ['three']}
         .fill()
         .map(() => Array(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.

    Use Array((end + 1) - start) to create an array of the desired length, Array.map() to fill with the desired values in a range. You can omit start to use a default value of 0.

    const initializeArrayWithRange = (end, start = 0) =>
    -  Array.from({ length: end + 1 - start }).map((v, i) => i + start);
    +

    initializeArrayWithRange

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

    Use Array(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]
     

    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 value to use a default value of 0.

    const initializeArrayWithValues = (n, value = 0) => Array(n).fill(value);
     
    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) => {
    @@ -289,7 +290,7 @@ reducedFilter(data, ['id', 'name'], item => item.age > 24); // [{ id: 2, n
     };
     
    sampleSize([1, 2, 3], 2); // [3,1]
     sampleSize([1, 2, 3], 4); // [2,3,1]
    -

    shuffle

    Randomizes the order of the values of an array, returning a new array.

    Uses the Fisher-Yates algoritm to reorder the elements of the array, based on the Lodash implementation, but as a pure function.

    const shuffle = ([...arr]) => {
    +

    shuffle

    Randomizes the order of the values of an array, returning a new array.

    Uses the Fisher-Yates algorithm to reorder the elements of the array, based on the Lodash implementation, but as a pure function.

    const shuffle = ([...arr]) => {
       let m = arr.length;
       while (m) {
         const i = Math.floor(Math.random() * m--);
    @@ -418,6 +419,44 @@ elementIsVisibleInViewport(el, true); // true // (partially visible)
     

    redirect

    Redirects to a specified URL.

    Use window.location.href or window.location.replace() to redirect to url. Pass a second argument to simulate a link click (true - default) or an HTTP redirect (false).

    const redirect = (url, asLink = true) =>
       asLink ? (window.location.href = url) : window.location.replace(url);
     
    redirect('https://google.com');
    +

    runAsync

    Runs a function in a separate thread by using a Web Worker, allowing long running functions to not block the UI.

    Create a new Worker using a Blob object URL, the contents of which should be the stringified version of the supplied function. Immediately post the return value of calling the function back. Return a promise, listening for onmessage and onerror events and resolving the data posted back from the worker, or throwing an error.

    const runAsync = fn => {
    +  const blob = `
    +    var fn = ${fn.toString()};
    +    this.postMessage(fn());
    +  `;
    +  const worker = new Worker(
    +    URL.createObjectURL(new Blob([blob]), {
    +      type: 'application/javascript; charset=utf-8'
    +    })
    +  );
    +  return new Promise((res, rej) => {
    +    worker.onmessage = ({ data }) => {
    +      res(data), worker.terminate();
    +    };
    +    worker.onerror = err => {
    +      rej(err), worker.terminate();
    +    };
    +  });
    +};
    +
    const longRunningFunction = () => {
    +  let result = 0;
    +  for (var i = 0; i < 1000; i++) {
    +    for (var j = 0; j < 700; j++) {
    +      for (var k = 0; k < 300; k++) {
    +        result = result + i + j + k;
    +      }
    +    }
    +  }
    +  return result;
    +};
    +
    +// NOTE: Since the function is running in a different context, closures are not supported.
    +// The function supplied to `runAsync` gets stringified, so everything becomes literal.
    +// All variables and functions must be defined inside.
    +runAsync(longRunningFunction).then(console.log); // 209685000000
    +runAsync(() => 10 ** 3).then(console.log); // 1000
    +let outsideVariable = 50;
    +runAsync(() => typeof outsideVariable).then(console.log); // 'undefined'
     

    scrollToTop

    Smooth-scrolls to the top of the page.

    Get distance from top using document.documentElement.scrollTop or document.body.scrollTop. Scroll by a fraction of the distance from the top. Use window.requestAnimationFrame() to animate the scrolling.

    const scrollToTop = () => {
       const c = document.documentElement.scrollTop || document.body.scrollTop;
       if (c > 0) {
    @@ -489,6 +528,14 @@ multiplyAndAdd5(5, 2); // 15
       arity <= args.length ? fn(...args) : curry.bind(null, fn, arity, ...args);
     
    curry(Math.pow)(2)(10); // 1024
     curry(Math.min, 3)(10)(50)(2); // 2
    +

    defer

    Defers invoking a function until the current call stack has cleared.

    Use setTimeout() with a timeout of 1ms to add a new event to the browser event queue and allow the rendering engine to complete its work. Use the spread (...) operator to supply the function with an arbitrary number of arguments.

    const defer = (fn, ...args) => setTimeout(fn, 1, ...args);
    +
    // Example A:
    +defer(console.log, 'a'), console.log('b'); // logs 'b' then 'a'
    +
    +// Example B:
    +document.querySelector('#someElement').innerHTML = 'Hello';
    +longRunningFunction(); // the browser will not update the HTML until this has finished
    +defer(longRunningFunction); // the browser will update the HTML then run the function
     

    functionName

    Logs the name of a function.

    Use console.debug() and the name property of the passed method to log the method's name to the debug channel of the console.

    const functionName = fn => (console.debug(fn.name), fn);
     
    functionName(Math.max); // max (logged in debug channel of console)
     

    memoize

    Returns the memoized (cached) function.

    Use Object.create(null) to create an empty object without Object.prototype (so that those properties are not resolved if the input value is something like 'hasOwnProperty'). Return a function which takes a single argument to be supplied to the memoized function by first checking if the function's output for that specific input value is already cached, or store and return it if not.

    const memoize = fn => {
    @@ -499,6 +546,18 @@ curry(Math.min, 3)(10)(50)(2); // 2
     const anagramsCached = memoize(anagrams);
     anagramsCached('javascript'); // takes a long time
     anagramsCached('javascript'); // returns virtually instantly since it's now cached
    +

    once

    Ensures a function is called only once.

    Utilizing a closure, use a flag, called, and set it to true once the function is called for the first time, preventing it from being called again. In order to allow the function to have its this context changed (such as in an event listener), the function keyword must be used, and the supplied function must have the context applied. Allow the function to be supplied with an arbitrary number of arguments using the rest/spread (...) operator.

    const once = fn => {
    +  let called = false;
    +  return function(...args) {
    +    if (called) return;
    +    called = true;
    +    return fn.apply(this, args);
    +  };
    +};
    +
    const startApp = function(event) {
    +  console.log(this, event); // document.body, MouseEvent
    +};
    +document.body.addEventListener('click', once(startApp)); // only runs `startApp` once upon click
     

    runPromisesInSeries

    Runs an array of promises in series.

    Use Array.reduce() to create a promise chain, where each promise returns the next promise when resolved.

    const runPromisesInSeries = ps => ps.reduce((p, next) => p.then(next), Promise.resolve());
     
    const delay = d => new Promise(r => setTimeout(r, d));
     runPromisesInSeries([() => delay(1000), () => delay(2000)]); // //executes each promise sequentially, taking a total of 3 seconds to complete
    @@ -602,8 +661,6 @@ isPrime(12); // false
     };
     
    lcm(12, 7); // 84
     lcm([1, 3, 4], 5); // 60
    -

    max

    Returns the maximum value out of two or more numbers/arrays.

    Use Math.max() combined with the spread operator (...) to get the maximum value in the array.

    const max = (...arr) => Math.max(...[].concat(...arr));
    -
    max([10, 1, 5]); // 10
     

    median

    Returns the median of an array of numbers.

    Find the middle of the array, use Array.sort() to sort the values. Return the number at the midpoint if length is odd, otherwise the average of the two middle numbers.

    const median = arr => {
       const mid = Math.floor(arr.length / 2),
         nums = [...arr].sort((a, b) => a - b);
    @@ -611,8 +668,6 @@ lcm([1, 3, 4], 5); // 60
     };
     
    median([5, 6, 50, 1, -5]); // 5
     median([0, 10, -2, 7]); // 3.5
    -

    min

    Returns the minimum value in an array.

    Use Math.min() combined with the spread operator (...) to get the minimum value in the array.

    const min = arr => Math.min(...[].concat(...arr));
    -
    min([10, 1, 5]); // 1
     

    percentile

    Uses the percentile formula to calculate how many numbers in the given array are less or equal to the given value.

    Use Array.reduce() to calculate how many numbers are below the value and how many are the same value and apply the percentile formula.

    const percentile = (arr, val) =>
       100 * arr.reduce((acc, v) => acc + (v < val ? 1 : 0) + (v === val ? 0.5 : 0), 0) / arr.length;
     
    percentile([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 6); // 55
    @@ -632,7 +687,7 @@ median([0, 10, -2, 7]); // 3.5
     
    randomNumberInRange(2, 10); // 6.0211363285087005
     

    round

    Rounds a number to a specified amount of digits.

    Use Math.round() and template literals to round the number to the specified number of digits. Omit the second argument, decimals to round to an integer.

    const round = (n, decimals = 0) => Number(`${Math.round(`${n}e${decimals}`)}e-${decimals}`);
     
    round(1.005, 2); // 1.01
    -

    solveRPN

    Solves the given mathematical expression in reverse polish notation. Throws appropriate errors if there are unrecognized symbols or the expression is wrong.

    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.

    const solveRPN = rpn => {
    +

    solveRPN

    Solves the given mathematical expression in 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.

    const solveRPN = rpn => {
       const OPERATORS = {
         '*': (a, b) => a * b,
         '+': (a, b) => a + b,
    @@ -674,7 +729,7 @@ solveRPN('2 3 ^'); //8
     };
     
    standardDeviation([10, 2, 38, 23, 38, 23, 21]); // 13.284434142114991 (sample)
     standardDeviation([10, 2, 38, 23, 38, 23, 21], true); // 12.29899614287479 (population)
    -

    sum

    Returns the sum of an of two or more numbers/arrays.

    Use Array.reduce() to add each value to an accumulator, initialized with a value of 0.

    const sum = (...arr) => [].concat(...arr).reduce((acc, val) => acc + val, 0);
    +

    sum

    Returns the sum of two or more numbers/arrays.

    Use Array.reduce() to add each value to an accumulator, initialized with a value of 0.

    const sum = (...arr) => [].concat(...arr).reduce((acc, val) => acc + val, 0);
     
    sum([1, 2, 3, 4]); // 10
     

    sumPower

    Returns the sum of the powers of all the numbers from start to end (both inclusive).

    Use Array.fill() to create an array of all the numbers in the target range, Array.map() and the exponent operator (**) to raise them to power and Array.reduce() to add them together. Omit the second argument, power, to use a default power of 2. Omit the third argument, start, to use a default starting value of 1.

    const sumPower = (end, power = 2, start = 1) =>
       Array(end + 1 - start)
    @@ -1097,4 +1152,20 @@ console.log(sdbm('age')); // 808122783
     yesNo('yes'); // true
     yesNo('No'); // false
     yesNo('Foo', true); // true
    +

    Uncategorized

    geometricProgression

    Initializes an array containing the numbers in the specified range where start and end are inclusive and the ratio between two terms is step. Returns an error if step equals 1.

    Use Array.from(), Math.log() and Math.floor() to create an array of the desired length, Array.map() to fill with the desired values in a range. Omit the second argument, start, to use a default value of 1. Omit the third argument, step, to use a default value of 2.

    const geometricProgression = (end, start = 1, step = 2) =>
    +  Array.from({ length: Math.floor(Math.log(end / start) / Math.log(step)) + 1 }).map(
    +    (v, i) => start * step ** i
    +  );
    +
    geometricProgression(256); // [1, 2, 4, 8, 16, 32, 64, 128, 256]
    +geometricProgression(256, 3); //[3, 6, 12, 24, 48, 96, 192]
    +geometricProgression(256, 1, 4); //[1, 4, 16, 64, 256]
    +geometricProgression(256, 2, 1); //Gives error
    +

    maxN

    Returns the n maximum elements from the provided array. If n is greater than or equal to the provided array's length than return the original array(sorted in descending order).

    Sort's the array's shallow copy in descending order and returns the first n elements

    Skip the second argument to get a single element(in the form of a array)

    const maxN = (arr, n = 1) => [...arr].sort((a, b) => b - a).slice(0, n);
    +
    maxN([1, 2, 3]); // [3]
    +maxN([1, 2, 3], 2); // [3,2]
    +maxN([1, 2, 3], 4); // [3,2,1]
    +

    minN

    Returns the n minimum elements from the provided array. If n is greater than or equal to the provided array's length than return the original array(sorted in ascending order).

    Sort's the array's shallow copy in ascending order and returns the first n elements

    Skip the second argument to get a single element(in the form of a array)

    const minN = (arr, n = 1) => [...arr].sort((a, b) => a - b).slice(0, n);
    +
    minN([1, 2, 3]); // [1]
    +minN([1, 2, 3], 2); // [1,2]
    +minN([1, 2, 3], 4); // [1,2,3]
     

    \ No newline at end of file diff --git a/package.json b/package.json index 75cbf472f..4efd5558a 100644 --- a/package.json +++ b/package.json @@ -24,8 +24,8 @@ "tagger": "node ./scripts/tag.js", "webber": "node ./scripts/web.js", "tdd": "node ./scripts/tdd.js", - "test": "tape test/**/*.test.js | tap-spec", - "module": "node ./scripts/module.js" + "module": "node ./scripts/module.js", + "test": "tape test/**/*.test.js | tap-spec" }, "repository": { "type": "git", diff --git a/scripts/build.js b/scripts/build.js index 879b8e9bf..1b9a464a6 100644 --- a/scripts/build.js +++ b/scripts/build.js @@ -6,7 +6,12 @@ const fs = require('fs-extra'); const path = require('path'); const chalk = require('chalk'); - +// Load helper functions (these are from existing snippets in 30 seconds of code!) +const isTravisCI = () => 'TRAVIS' in process.env && 'CI' in process.env; +if(isTravisCI() && /^Travis build: \d+/g.test(process.env['TRAVIS_COMMIT_MESSAGE'])) { + console.log(`${chalk.green('NOBUILD')} README build terminated, parent commit is a Travis build!`); + process.exit(0); +} const SNIPPETS_PATH = './snippets'; const STATIC_PARTS_PATH = './static-parts'; diff --git a/scripts/lint.js b/scripts/lint.js index 833ef3dbd..d8140b8a4 100644 --- a/scripts/lint.js +++ b/scripts/lint.js @@ -9,7 +9,12 @@ const fs = require('fs-extra'); const cp = require('child_process'); const path = require('path'); const chalk = require('chalk'); - +// Load helper functions (these are from existing snippets in 30 seconds of code!) +const isTravisCI = () => 'TRAVIS' in process.env && 'CI' in process.env; +if(isTravisCI() && /^Travis build: \d+/g.test(process.env['TRAVIS_COMMIT_MESSAGE'])) { + console.log(`${chalk.green('NOBUILD')} Linting terminated, parent commit is a Travis build!`); + process.exit(0); +} const SNIPPETS_PATH = './snippets'; const TEMP_PATH = './temp'; diff --git a/scripts/module.js b/scripts/module.js new file mode 100644 index 000000000..9d5f73cdb --- /dev/null +++ b/scripts/module.js @@ -0,0 +1,80 @@ +/* + Builds the `_30s` module. +*/ +// Load modules +const fs = require('fs-extra'); +const cp = require('child_process'); +const path = require('path'); +const chalk = require('chalk'); +// Load helper functions (these are from existing snippets in 30 seconds of code!) +const isTravisCI = () => 'TRAVIS' in process.env && 'CI' in process.env; +if(isTravisCI() && process.env['TRAVIS_EVENT_TYPE'] !== 'cron' && process.env['TRAVIS_EVENT_TYPE'] !== 'api') { + console.log(`${chalk.green('NOBUILD')} Module build terminated, not a cron job or a custom build!`); + process.exit(0); +} +// Set variables for paths +const SNIPPETS_PATH = './snippets'; +const TEMP_PATH = './temp'; +const IMPORTS = './imports.js'; +// Regex for selecting code blocks +const codeRE = /```\s*js([\s\S]*?)```/; +// Start the timer of the script +console.time('Module'); +// Load tag data from the database and snippets from their folder +try { + const tagDatabase = fs.readFileSync('tag_database', 'utf8'); + const snippets = fs.readdirSync(SNIPPETS_PATH); + // Create `temp` folder if it doesn't already exist. + if (!fs.existsSync(TEMP_PATH)) { + fs.mkdirSync(TEMP_PATH); + } + // Write `imports.js` + fs.writeFileSync(IMPORTS, ''); + let exportStr = 'export default {'; + // Read all snippets and store them appropriately + for (const snippet of snippets) { + const snippetData = fs.readFileSync( + path.join(SNIPPETS_PATH, snippet), + 'utf8' + ); + const snippetName = snippet.replace('.md', ''); + // Check if a snippet is Node-only + const isNodeSnippet = tagDatabase + .slice(tagDatabase.indexOf(snippetName) + snippetName.length + 1) + .split('\n')[0] + .includes('node'); + // Read `imports.js` and write the data + const importData = fs.readFileSync(IMPORTS); + fs.writeFileSync( + IMPORTS, + importData + `\nimport { ${snippetName} } from './temp/${snippetName}.js'` + ); + exportStr += `${snippetName},`; + // Find the code in each snippet + const code = snippetData.match(codeRE)[1].replace('\n', ''); + // Store the data to be written + const toWrite = isNodeSnippet + ? `${code + .replace('const ' + snippetName, 'export const ' + snippetName) + // Prevents errors from being thrown in browser environment + .replace('require(', 'typeof require !== "undefined" && require(')}` + : `export ${code}`; + // Write data to the proper file + fs.writeFileSync(`${TEMP_PATH}/${snippetName}.js`, toWrite); + } + // Write to the proper files and start the `rollup` script + exportStr += '}'; + fs.appendFileSync(IMPORTS, `\n${exportStr}`); + cp.execSync('node ./scripts/rollup.js'); + // Clean up temporary data + fs.removeSync(TEMP_PATH); + fs.unlink(IMPORTS); + // Log a success message + console.log(`${chalk.green('SUCCESS!')} Snippet module built!`); + // Log the time taken + console.timeEnd('Module'); +} catch (err) { + // Handle errors (hopefully not!) + console.log(`${chalk.red('ERROR!')} During module creation: ${err}`); + process.exit(1); +} diff --git a/scripts/rollup.js b/scripts/rollup.js new file mode 100644 index 000000000..4fe1951a6 --- /dev/null +++ b/scripts/rollup.js @@ -0,0 +1,62 @@ +/* + Part of the process for building the `_30s` module. +*/ +// Load modules +const fs = require('fs-extra'); +const { rollup } = require('rollup'); +const babel = require('rollup-plugin-babel'); +const minify = require('rollup-plugin-babel-minify'); +// Set variables for paths +const INPUT_FILE = './imports.js'; +const MODULE_NAME = '_30s'; +const DIST = './dist'; +// Create `dist` folder if not existing +if (!fs.existsSync(DIST)) fs.mkdirSync(DIST); +// Setup babel and minification +const es5 = babel({ presets: [['env', { modules: false }]] }); +const min = minify({ comments: false }); +// Create the bundles +(async () => { + const bundle = await rollup({ input: INPUT_FILE }); + const bundleES5 = await rollup({ input: INPUT_FILE, plugins: [es5] }); + const bundleMin = await rollup({ input: INPUT_FILE, plugins: [min] }); + const bundleES5Min = await rollup({ + input: INPUT_FILE, + plugins: [es5, min] + }); + + // UMD ES2017 + await bundle.write({ + file: `${DIST}/${MODULE_NAME}.js`, + name: MODULE_NAME, + format: 'umd' + }); + + // UMD ES2017 minified + await bundleMin.write({ + file: `${DIST}/${MODULE_NAME}.min.js`, + name: MODULE_NAME, + format: 'umd' + }); + + // UMD ES5 + await bundleES5.write({ + file: `${DIST}/${MODULE_NAME}.es5.js`, + name: MODULE_NAME, + format: 'umd' + }); + + // UMD ES5 min + await bundleES5Min.write({ + file: `${DIST}/${MODULE_NAME}.es5.min.js`, + name: MODULE_NAME, + format: 'umd' + }); + + // ESM ES2017 + await bundle.write({ + file: `${DIST}/${MODULE_NAME}.esm.js`, + name: MODULE_NAME, + format: 'es' + }); +})(); diff --git a/scripts/tag.js b/scripts/tag.js index 2c8ed9b0a..bf57fd7cf 100644 --- a/scripts/tag.js +++ b/scripts/tag.js @@ -6,6 +6,12 @@ const fs = require('fs-extra'), path = require('path'), chalk = require('chalk'); +// Load helper functions (these are from existing snippets in 30 seconds of code!) +const isTravisCI = () => 'TRAVIS' in process.env && 'CI' in process.env; +if(isTravisCI() && /^Travis build: \d+/g.test(process.env['TRAVIS_COMMIT_MESSAGE'])) { + console.log(`${chalk.green('NOBUILD')} Tagging terminated, parent commit is a Travis build!`); + process.exit(0); +} // Set variables for paths const snippetsPath = './snippets'; // Set variables for script diff --git a/scripts/web.js b/scripts/web.js index ac72efc54..68b0319e0 100644 --- a/scripts/web.js +++ b/scripts/web.js @@ -8,6 +8,12 @@ const fs = require('fs-extra'), chalk = require('chalk'), md = require('markdown-it')(), minify = require('html-minifier').minify; + // Load helper functions (these are from existing snippets in 30 seconds of code!) +const isTravisCI = () => 'TRAVIS' in process.env && 'CI' in process.env; +if(isTravisCI() && /^Travis build: \d+/g.test(process.env['TRAVIS_COMMIT_MESSAGE'])) { + console.log(`${chalk.green('NOBUILD')} index build terminated, parent commit is a Travis build!`); + process.exit(0); +} // Compile the mini.css framework and custom CSS styles, using `node-sass`. const sass = require('node-sass'); sass.render( diff --git a/snippets/defer.md b/snippets/defer.md new file mode 100644 index 000000000..7403d4c36 --- /dev/null +++ b/snippets/defer.md @@ -0,0 +1,19 @@ +### defer + +Defers invoking a function until the current call stack has cleared. + +Use `setTimeout()` with a timeout of 1ms to add a new event to the browser event queue and allow the rendering engine to complete its work. Use the spread (`...`) operator to supply the function with an arbitrary number of arguments. + +```js +const defer = (fn, ...args) => setTimeout(fn, 1, ...args); +``` + +```js +// Example A: +defer(console.log, 'a'), console.log('b'); // logs 'b' then 'a' + +// Example B: +document.querySelector('#someElement').innerHTML = 'Hello'; +longRunningFunction(); // the browser will not update the HTML until this has finished +defer(longRunningFunction); // the browser will update the HTML then run the function +``` diff --git a/snippets/geometricProgression.md b/snippets/geometricProgression.md new file mode 100644 index 000000000..3f6c2719b --- /dev/null +++ b/snippets/geometricProgression.md @@ -0,0 +1,22 @@ +### geometricProgression + +Initializes an array containing the numbers in the specified range where `start` and `end` are inclusive and the ratio between two terms is `step`. +Returns an error if `step` equals `1`. + +Use `Array.from()`, `Math.log()` and `Math.floor()` to create an array of the desired length, `Array.map()` to fill with the desired values in a range. +Omit the second argument, `start`, to use a default value of `1`. +Omit the third argument, `step`, to use a default value of `2`. + +```js +const geometricProgression = (end, start = 1, step = 2) => + Array.from({ length: Math.floor(Math.log(end / start) / Math.log(step)) + 1 }).map( + (v, i) => start * step ** i + ); +``` + +```js +geometricProgression(256); // [1, 2, 4, 8, 16, 32, 64, 128, 256] +geometricProgression(256, 3); //[3, 6, 12, 24, 48, 96, 192] +geometricProgression(256, 1, 4); //[1, 4, 16, 64, 256] +geometricProgression(256, 2, 1); //Gives error +``` diff --git a/snippets/initializeArrayWithRange.md b/snippets/initializeArrayWithRange.md index 22b126ad8..2b59153b1 100644 --- a/snippets/initializeArrayWithRange.md +++ b/snippets/initializeArrayWithRange.md @@ -1,16 +1,18 @@ ### initializeArrayWithRange -Initializes an array containing the numbers in the specified range where `start` and `end` are inclusive. +Initializes an array containing the numbers in the specified range where `start` and `end` are inclusive with there common difference `step`. -Use `Array((end + 1) - start)` to create an array of the desired length, `Array.map()` to fill with the desired values in a range. +Use `Array(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 initializeArrayWithRange = (end, start = 0) => - Array.from({ length: end + 1 - start }).map((v, i) => i + start); +const initializeArrayWithRange = (end, start = 0, step = 1) => + Array.from({ length: Math.ceil((end + 1 - start) / step) }).map((v, i) => i * step + start); ``` ```js 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] ``` diff --git a/snippets/max.md b/snippets/max.md deleted file mode 100644 index 4d6fe2826..000000000 --- a/snippets/max.md +++ /dev/null @@ -1,13 +0,0 @@ -### max - -Returns the maximum value out of two or more numbers/arrays. - -Use `Math.max()` combined with the spread operator (`...`) to get the maximum value in the array. - -```js -const max = (...arr) => Math.max(...[].concat(...arr)); -``` - -```js -max([10, 1, 5]); // 10 -``` diff --git a/snippets/maxN.md b/snippets/maxN.md new file mode 100644 index 000000000..efc9e5052 --- /dev/null +++ b/snippets/maxN.md @@ -0,0 +1,16 @@ +### maxN + +Returns the `n` maximum elements from the provided array. If `n` is greater than or equal to the provided array's length than return the original array(sorted in descending order). + +Sort's the array's shallow copy in descending order and returns the first n elements + +Skip the second argument to get a single element(in the form of a array) +```js +const maxN = (arr, n = 1) => [...arr].sort((a, b) => b - a).slice(0, n); +``` + +```js +maxN([1, 2, 3]); // [3] +maxN([1, 2, 3], 2); // [3,2] +maxN([1, 2, 3], 4); // [3,2,1] +``` diff --git a/snippets/min.md b/snippets/min.md deleted file mode 100644 index c7799694a..000000000 --- a/snippets/min.md +++ /dev/null @@ -1,13 +0,0 @@ -### min - -Returns the minimum value in an array. - -Use `Math.min()` combined with the spread operator (`...`) to get the minimum value in the array. - -```js -const min = arr => Math.min(...[].concat(...arr)); -``` - -```js -min([10, 1, 5]); // 1 -``` diff --git a/snippets/minN.md b/snippets/minN.md new file mode 100644 index 000000000..2cee5b091 --- /dev/null +++ b/snippets/minN.md @@ -0,0 +1,15 @@ +### minN + +Returns the `n` minimum elements from the provided array. If `n` is greater than or equal to the provided array's length than return the original array(sorted in ascending order). + +Sort's the array's shallow copy in ascending order and returns the first n elements + +Skip the second argument to get a single element(in the form of a array) +```js +const minN = (arr, n = 1) => [...arr].sort((a, b) => a - b).slice(0, n); +``` +```js +minN([1, 2, 3]); // [1] +minN([1, 2, 3], 2); // [1,2] +minN([1, 2, 3], 4); // [1,2,3] +``` diff --git a/snippets/once.md b/snippets/once.md new file mode 100644 index 000000000..92ef9c7be --- /dev/null +++ b/snippets/once.md @@ -0,0 +1,24 @@ +### once + +Ensures a function is called only once. + +Utilizing a closure, use a flag, `called`, and set it to `true` once the function is called for the first time, preventing it from being called again. In order to allow the function to have its `this` context changed (such as in an event listener), the `function` keyword must be used, and the supplied function must have the context applied. +Allow the function to be supplied with an arbitrary number of arguments using the rest/spread (`...`) operator. + +```js +const once = fn => { + let called = false; + return function(...args) { + if (called) return; + called = true; + return fn.apply(this, args); + }; +}; +``` + +```js +const startApp = function(event) { + console.log(this, event); // document.body, MouseEvent +}; +document.body.addEventListener('click', once(startApp)); // only runs `startApp` once upon click +``` diff --git a/snippets/runAsync.md b/snippets/runAsync.md new file mode 100644 index 000000000..8ab34943e --- /dev/null +++ b/snippets/runAsync.md @@ -0,0 +1,51 @@ +### runAsync + +Runs a function in a separate thread by using a [Web Worker](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers), allowing long running functions to not block the UI. + +Create a new `Worker` using a `Blob` object URL, the contents of which should be the stringified version of the supplied function. +Immediately post the return value of calling the function back. +Return a promise, listening for `onmessage` and `onerror` events and resolving the data posted back from the worker, or throwing an error. + +```js +const runAsync = fn => { + const blob = ` + var fn = ${fn.toString()}; + this.postMessage(fn()); + `; + const worker = new Worker( + URL.createObjectURL(new Blob([blob]), { + type: 'application/javascript; charset=utf-8' + }) + ); + return new Promise((res, rej) => { + worker.onmessage = ({ data }) => { + res(data), worker.terminate(); + }; + worker.onerror = err => { + rej(err), worker.terminate(); + }; + }); +}; +``` + +```js +const longRunningFunction = () => { + let result = 0; + for (var i = 0; i < 1000; i++) { + for (var j = 0; j < 700; j++) { + for (var k = 0; k < 300; k++) { + result = result + i + j + k; + } + } + } + return result; +}; + +// NOTE: Since the function is running in a different context, closures are not supported. +// The function supplied to `runAsync` gets stringified, so everything becomes literal. +// All variables and functions must be defined inside. +runAsync(longRunningFunction).then(console.log); // 209685000000 +runAsync(() => 10 ** 3).then(console.log); // 1000 +let outsideVariable = 50; +runAsync(() => typeof outsideVariable).then(console.log); // 'undefined' +``` diff --git a/snippets/shuffle.md b/snippets/shuffle.md index 2b6229634..a9e1c64aa 100644 --- a/snippets/shuffle.md +++ b/snippets/shuffle.md @@ -2,7 +2,7 @@ Randomizes the order of the values of an array, returning a new array. -Uses the Fisher-Yates algoritm to reorder the elements of the array, based on the [Lodash implementation](https://github.com/lodash/lodash/blob/b2ea6b1cd251796dcb5f9700c4911a7b6223920b/shuffle.js), but as a pure function. +Uses the Fisher-Yates algorithm to reorder the elements of the array, based on the [Lodash implementation](https://github.com/lodash/lodash/blob/b2ea6b1cd251796dcb5f9700c4911a7b6223920b/shuffle.js), but as a pure function. ```js const shuffle = ([...arr]) => { diff --git a/snippets/solveRPN.md b/snippets/solveRPN.md index 099be512a..87a1fee3f 100644 --- a/snippets/solveRPN.md +++ b/snippets/solveRPN.md @@ -1,7 +1,7 @@ ### 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. +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. diff --git a/snippets/sum.md b/snippets/sum.md index c6894b6a8..a69aa3d4f 100644 --- a/snippets/sum.md +++ b/snippets/sum.md @@ -1,6 +1,6 @@ ### sum -Returns the sum of an of two or more numbers/arrays. +Returns the sum of two or more numbers/arrays. Use `Array.reduce()` to add each value to an accumulator, initialized with a value of `0`. diff --git a/static-parts/README-start.md b/static-parts/README-start.md index f6a95a986..a3a94d299 100644 --- a/static-parts/README-start.md +++ b/static-parts/README-start.md @@ -1,7 +1,9 @@ ![Logo](/logo.png) # 30 seconds of code -[![License](https://img.shields.io/badge/license-CC0--1.0-blue.svg)](https://github.com/Chalarangelo/30-seconds-of-code/blob/master/LICENSE) [![Gitter chat](https://img.shields.io/badge/chat-on%20gitter-4FB999.svg)](https://gitter.im/30-seconds-of-code/Lobby) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](http://makeapullrequest.com) [![Travis Build](https://travis-ci.org/Chalarangelo/30-seconds-of-code.svg?branch=master)](https://travis-ci.org/Chalarangelo/30-seconds-of-code) [![Insight.io](https://img.shields.io/badge/insight.io-Ready-brightgreen.svg)](https://insight.io/github.com/Chalarangelo/30-seconds-of-code/tree/master/?source=0) [![js-semistandard-style](https://img.shields.io/badge/code%20style-semistandard-brightgreen.svg)](https://github.com/Flet/semistandard) + +[![License](https://img.shields.io/badge/license-CC0--1.0-blue.svg)](https://github.com/Chalarangelo/30-seconds-of-code/blob/master/LICENSE) [![Gitter chat](https://img.shields.io/badge/chat-on%20gitter-4FB999.svg)](https://gitter.im/30-seconds-of-code/Lobby) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](http://makeapullrequest.com) [![Travis Build](https://travis-ci.org/Chalarangelo/30-seconds-of-code.svg?branch=master)](https://travis-ci.org/Chalarangelo/30-seconds-of-code) [![Insight.io](https://img.shields.io/badge/insight.io-Ready-brightgreen.svg)](https://insight.io/github.com/Chalarangelo/30-seconds-of-code/tree/master/?source=0) [![js-semistandard-style](https://img.shields.io/badge/code%20style-semistandard-brightgreen.svg)](https://github.com/Flet/semistandard) [![ProductHunt](https://img.shields.io/badge/producthunt-vote-orange.svg)](https://www.producthunt.com/posts/30-seconds-of-code) + > Curated collection of useful Javascript snippets that you can understand in 30 seconds or less. @@ -11,6 +13,6 @@ - Snippets are written in ES6, use the [Babel transpiler](https://babeljs.io/) to ensure backwards-compatibility. - You can import these snippets into your text editor of choice (VSCode, Atom, Sublime) using the files found in [this repo](https://github.com/Rob-Rychs/30-seconds-of-code-texteditorsnippets). - You can import these snippets into Alfred 3, using [this file](https://github.com/lslvxy/30-seconds-of-code-alfredsnippets). -- You can find a package with all the snippets on [npm](https://www.npmjs.com/package/tsoc). Bear in mind that most of these snippets are not production-ready. +- You can find a package with all the snippets on [npm](https://www.npmjs.com/package/30-seconds-of-code). Bear in mind that most of these snippets are not production-ready. ## Table of Contents diff --git a/tag_database b/tag_database index 86132bbfc..e8c53adce 100644 --- a/tag_database +++ b/tag_database @@ -23,6 +23,7 @@ countVowels:string currentURL:browser curry:function deepFlatten:array +defer:function detectDeviceType:browser difference:array differenceWith:array @@ -48,6 +49,7 @@ flip:adapter fromCamelCase:string functionName:function gcd:math +geometricProgression:uncategorized getDaysDiffBetweenDates:date getScrollPosition:browser getStyle:browser @@ -94,14 +96,15 @@ lcm:math lowercaseKeys:object mapObject:array mask:string -max:math +maxN:uncategorized median:math memoize:function -min:math +minN:uncategorized negate:logic nthElement:array objectFromPairs:object objectToPairs:object +once:function onUserInputChange:browser orderBy:object palindrome:string @@ -127,6 +130,7 @@ repeatString:string reverseString:string RGBToHex:utility round:math +runAsync:browser runPromisesInSeries:function sample:array sampleSize:array diff --git a/yarn.lock b/yarn.lock index b4d7dfd07..c7dec9cb4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,6 +2,10 @@ # yarn lockfile v1 +"@comandeer/babel-plugin-banner@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@comandeer/babel-plugin-banner/-/babel-plugin-banner-1.0.0.tgz#40bcce0bbee084b5b02545a33635d053c248356f" + abbrev@1: version "1.1.1" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" @@ -140,7 +144,7 @@ aws4@^1.2.1, aws4@^1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e" -babel-code-frame@^6.16.0: +babel-code-frame@^6.16.0, babel-code-frame@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" dependencies: @@ -148,6 +152,625 @@ babel-code-frame@^6.16.0: esutils "^2.0.2" js-tokens "^3.0.2" +babel-core@^6.21.0, babel-core@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.26.0.tgz#af32f78b31a6fcef119c87b0fd8d9753f03a0bb8" + dependencies: + babel-code-frame "^6.26.0" + babel-generator "^6.26.0" + babel-helpers "^6.24.1" + babel-messages "^6.23.0" + babel-register "^6.26.0" + babel-runtime "^6.26.0" + babel-template "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + convert-source-map "^1.5.0" + debug "^2.6.8" + json5 "^0.5.1" + lodash "^4.17.4" + minimatch "^3.0.4" + path-is-absolute "^1.0.1" + private "^0.1.7" + slash "^1.0.0" + source-map "^0.5.6" + +babel-generator@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.26.0.tgz#ac1ae20070b79f6e3ca1d3269613053774f20dc5" + dependencies: + babel-messages "^6.23.0" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + detect-indent "^4.0.0" + jsesc "^1.3.0" + lodash "^4.17.4" + source-map "^0.5.6" + trim-right "^1.0.1" + +babel-helper-builder-binary-assignment-operator-visitor@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz#cce4517ada356f4220bcae8a02c2b346f9a56664" + dependencies: + babel-helper-explode-assignable-expression "^6.24.1" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-call-delegate@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz#ece6aacddc76e41c3461f88bfc575bd0daa2df8d" + dependencies: + babel-helper-hoist-variables "^6.24.1" + babel-runtime "^6.22.0" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-define-map@^6.24.1: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz#a5f56dab41a25f97ecb498c7ebaca9819f95be5f" + dependencies: + babel-helper-function-name "^6.24.1" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + lodash "^4.17.4" + +babel-helper-evaluate-path@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/babel-helper-evaluate-path/-/babel-helper-evaluate-path-0.2.0.tgz#0bb2eb01996c0cef53c5e8405e999fe4a0244c08" + +babel-helper-explode-assignable-expression@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz#f25b82cf7dc10433c55f70592d5746400ac22caa" + dependencies: + babel-runtime "^6.22.0" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-flip-expressions@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/babel-helper-flip-expressions/-/babel-helper-flip-expressions-0.2.0.tgz#160d2090a3d9f9c64a750905321a0bc218f884ec" + +babel-helper-function-name@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz#d3475b8c03ed98242a25b48351ab18399d3580a9" + dependencies: + babel-helper-get-function-arity "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-get-function-arity@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz#8f7782aa93407c41d3aa50908f89b031b1b6853d" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-hoist-variables@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz#1ecb27689c9d25513eadbc9914a73f5408be7a76" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-is-nodes-equiv@^0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/babel-helper-is-nodes-equiv/-/babel-helper-is-nodes-equiv-0.0.1.tgz#34e9b300b1479ddd98ec77ea0bbe9342dfe39684" + +babel-helper-is-void-0@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/babel-helper-is-void-0/-/babel-helper-is-void-0-0.2.0.tgz#6ed0ada8a9b1c5b6e88af6b47c1b3b5c080860eb" + +babel-helper-mark-eval-scopes@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/babel-helper-mark-eval-scopes/-/babel-helper-mark-eval-scopes-0.2.0.tgz#7648aaf2ec92aae9b09a20ad91e8df5e1fcc94b2" + +babel-helper-optimise-call-expression@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz#f7a13427ba9f73f8f4fa993c54a97882d1244257" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-regex@^6.24.1: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz#325c59f902f82f24b74faceed0363954f6495e72" + dependencies: + babel-runtime "^6.26.0" + babel-types "^6.26.0" + lodash "^4.17.4" + +babel-helper-remap-async-to-generator@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz#5ec581827ad723fecdd381f1c928390676e4551b" + dependencies: + babel-helper-function-name "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-remove-or-void@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/babel-helper-remove-or-void/-/babel-helper-remove-or-void-0.2.0.tgz#8e46ad5b30560d57d7510b3fd93f332ee7c67386" + +babel-helper-replace-supers@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz#bf6dbfe43938d17369a213ca8a8bf74b6a90ab1a" + dependencies: + babel-helper-optimise-call-expression "^6.24.1" + babel-messages "^6.23.0" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-to-multiple-sequence-expressions@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/babel-helper-to-multiple-sequence-expressions/-/babel-helper-to-multiple-sequence-expressions-0.2.0.tgz#d1a419634c6cb301f27858c659167cfee0a9d318" + +babel-helpers@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helpers/-/babel-helpers-6.24.1.tgz#3471de9caec388e5c850e597e58a26ddf37602b2" + dependencies: + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-messages@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-check-es2015-constants@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz#35157b101426fd2ffd3da3f75c7d1e91835bbf8a" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-minify-builtins@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/babel-plugin-minify-builtins/-/babel-plugin-minify-builtins-0.2.0.tgz#317f824b0907210b6348671bb040ca072e2e0c82" + dependencies: + babel-helper-evaluate-path "^0.2.0" + +babel-plugin-minify-constant-folding@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/babel-plugin-minify-constant-folding/-/babel-plugin-minify-constant-folding-0.2.0.tgz#8c70b528b2eb7c13e94d95c8789077d4cdbc3970" + dependencies: + babel-helper-evaluate-path "^0.2.0" + +babel-plugin-minify-dead-code-elimination@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/babel-plugin-minify-dead-code-elimination/-/babel-plugin-minify-dead-code-elimination-0.2.0.tgz#e8025ee10a1e5e4f202633a6928ce892c33747e3" + dependencies: + babel-helper-evaluate-path "^0.2.0" + babel-helper-mark-eval-scopes "^0.2.0" + babel-helper-remove-or-void "^0.2.0" + lodash.some "^4.6.0" + +babel-plugin-minify-flip-comparisons@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/babel-plugin-minify-flip-comparisons/-/babel-plugin-minify-flip-comparisons-0.2.0.tgz#0c9c8e93155c8f09dedad8118b634c259f709ef5" + dependencies: + babel-helper-is-void-0 "^0.2.0" + +babel-plugin-minify-guarded-expressions@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/babel-plugin-minify-guarded-expressions/-/babel-plugin-minify-guarded-expressions-0.2.0.tgz#8a8c950040fce3e258a12e6eb21eab94ad7235ab" + dependencies: + babel-helper-flip-expressions "^0.2.0" + +babel-plugin-minify-infinity@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/babel-plugin-minify-infinity/-/babel-plugin-minify-infinity-0.2.0.tgz#30960c615ddbc657c045bb00a1d8eb4af257cf03" + +babel-plugin-minify-mangle-names@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/babel-plugin-minify-mangle-names/-/babel-plugin-minify-mangle-names-0.2.0.tgz#719892297ff0106a6ec1a4b0fc062f1f8b6a8529" + dependencies: + babel-helper-mark-eval-scopes "^0.2.0" + +babel-plugin-minify-numeric-literals@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/babel-plugin-minify-numeric-literals/-/babel-plugin-minify-numeric-literals-0.2.0.tgz#5746e851700167a380c05e93f289a7070459a0d1" + +babel-plugin-minify-replace@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/babel-plugin-minify-replace/-/babel-plugin-minify-replace-0.2.0.tgz#3c1f06bc4e6d3e301eacb763edc1be611efc39b0" + +babel-plugin-minify-simplify@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/babel-plugin-minify-simplify/-/babel-plugin-minify-simplify-0.2.0.tgz#21ceec4857100c5476d7cef121f351156e5c9bc0" + dependencies: + babel-helper-flip-expressions "^0.2.0" + babel-helper-is-nodes-equiv "^0.0.1" + babel-helper-to-multiple-sequence-expressions "^0.2.0" + +babel-plugin-minify-type-constructors@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/babel-plugin-minify-type-constructors/-/babel-plugin-minify-type-constructors-0.2.0.tgz#7f3b6458be0863cfd59e9985bed6d134aa7a2e17" + dependencies: + babel-helper-is-void-0 "^0.2.0" + +babel-plugin-syntax-async-functions@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz#cad9cad1191b5ad634bf30ae0872391e0647be95" + +babel-plugin-syntax-exponentiation-operator@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz#9ee7e8337290da95288201a6a57f4170317830de" + +babel-plugin-syntax-trailing-function-commas@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz#ba0360937f8d06e40180a43fe0d5616fff532cf3" + +babel-plugin-transform-async-to-generator@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz#6536e378aff6cb1d5517ac0e40eb3e9fc8d08761" + dependencies: + babel-helper-remap-async-to-generator "^6.24.1" + babel-plugin-syntax-async-functions "^6.8.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-arrow-functions@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz#452692cb711d5f79dc7f85e440ce41b9f244d221" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-block-scoped-functions@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz#bbc51b49f964d70cb8d8e0b94e820246ce3a6141" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-block-scoping@^6.23.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz#d70f5299c1308d05c12f463813b0a09e73b1895f" + dependencies: + babel-runtime "^6.26.0" + babel-template "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + lodash "^4.17.4" + +babel-plugin-transform-es2015-classes@^6.23.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz#5a4c58a50c9c9461e564b4b2a3bfabc97a2584db" + dependencies: + babel-helper-define-map "^6.24.1" + babel-helper-function-name "^6.24.1" + babel-helper-optimise-call-expression "^6.24.1" + babel-helper-replace-supers "^6.24.1" + babel-messages "^6.23.0" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-computed-properties@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz#6fe2a8d16895d5634f4cd999b6d3480a308159b3" + dependencies: + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-destructuring@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz#997bb1f1ab967f682d2b0876fe358d60e765c56d" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-duplicate-keys@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz#73eb3d310ca969e3ef9ec91c53741a6f1576423e" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-for-of@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz#f47c95b2b613df1d3ecc2fdb7573623c75248691" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-function-name@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz#834c89853bc36b1af0f3a4c5dbaa94fd8eacaa8b" + dependencies: + babel-helper-function-name "^6.24.1" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-literals@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz#4f54a02d6cd66cf915280019a31d31925377ca2e" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-modules-amd@^6.22.0, babel-plugin-transform-es2015-modules-amd@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz#3b3e54017239842d6d19c3011c4bd2f00a00d154" + dependencies: + babel-plugin-transform-es2015-modules-commonjs "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-modules-commonjs@^6.23.0, babel-plugin-transform-es2015-modules-commonjs@^6.24.1: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.0.tgz#0d8394029b7dc6abe1a97ef181e00758dd2e5d8a" + dependencies: + babel-plugin-transform-strict-mode "^6.24.1" + babel-runtime "^6.26.0" + babel-template "^6.26.0" + babel-types "^6.26.0" + +babel-plugin-transform-es2015-modules-systemjs@^6.23.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz#ff89a142b9119a906195f5f106ecf305d9407d23" + dependencies: + babel-helper-hoist-variables "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-modules-umd@^6.23.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz#ac997e6285cd18ed6176adb607d602344ad38468" + dependencies: + babel-plugin-transform-es2015-modules-amd "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-object-super@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz#24cef69ae21cb83a7f8603dad021f572eb278f8d" + dependencies: + babel-helper-replace-supers "^6.24.1" + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-parameters@^6.23.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz#57ac351ab49caf14a97cd13b09f66fdf0a625f2b" + dependencies: + babel-helper-call-delegate "^6.24.1" + babel-helper-get-function-arity "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-shorthand-properties@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz#24f875d6721c87661bbd99a4622e51f14de38aa0" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-spread@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz#d6d68a99f89aedc4536c81a542e8dd9f1746f8d1" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-sticky-regex@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz#00c1cdb1aca71112cdf0cf6126c2ed6b457ccdbc" + dependencies: + babel-helper-regex "^6.24.1" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-template-literals@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz#a84b3450f7e9f8f1f6839d6d687da84bb1236d8d" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-typeof-symbol@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz#dec09f1cddff94b52ac73d505c84df59dcceb372" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-unicode-regex@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz#d38b12f42ea7323f729387f18a7c5ae1faeb35e9" + dependencies: + babel-helper-regex "^6.24.1" + babel-runtime "^6.22.0" + regexpu-core "^2.0.0" + +babel-plugin-transform-exponentiation-operator@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz#2ab0c9c7f3098fa48907772bb813fe41e8de3a0e" + dependencies: + babel-helper-builder-binary-assignment-operator-visitor "^6.24.1" + babel-plugin-syntax-exponentiation-operator "^6.8.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-inline-consecutive-adds@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-inline-consecutive-adds/-/babel-plugin-transform-inline-consecutive-adds-0.2.0.tgz#15dae78921057f4004f8eafd79e15ddc5f12f426" + +babel-plugin-transform-member-expression-literals@^6.8.5: + version "6.8.5" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-member-expression-literals/-/babel-plugin-transform-member-expression-literals-6.8.5.tgz#e06ae305cf48d819822e93a70d79269f04d89eec" + +babel-plugin-transform-merge-sibling-variables@^6.8.6: + version "6.8.6" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-merge-sibling-variables/-/babel-plugin-transform-merge-sibling-variables-6.8.6.tgz#6d21efa5ee4981f71657fae716f9594bb2622aef" + +babel-plugin-transform-minify-booleans@^6.8.3: + version "6.8.3" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-minify-booleans/-/babel-plugin-transform-minify-booleans-6.8.3.tgz#5906ed776d3718250519abf1bace44b0b613ddf9" + +babel-plugin-transform-property-literals@^6.8.5: + version "6.8.5" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-property-literals/-/babel-plugin-transform-property-literals-6.8.5.tgz#67ed5930b34805443452c8b9690c7ebe1e206c40" + dependencies: + esutils "^2.0.2" + +babel-plugin-transform-regenerator@^6.22.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz#e0703696fbde27f0a3efcacf8b4dca2f7b3a8f2f" + dependencies: + regenerator-transform "^0.10.0" + +babel-plugin-transform-regexp-constructors@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-regexp-constructors/-/babel-plugin-transform-regexp-constructors-0.2.0.tgz#6aa5dd0acc515db4be929bbcec4ed4c946c534a3" + +babel-plugin-transform-remove-console@^6.8.5: + version "6.8.5" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-remove-console/-/babel-plugin-transform-remove-console-6.8.5.tgz#fde9d2d3d725530b0fadd8d31078402410386810" + +babel-plugin-transform-remove-debugger@^6.8.5: + version "6.8.5" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-remove-debugger/-/babel-plugin-transform-remove-debugger-6.8.5.tgz#809584d412bf918f071fdf41e1fdb15ea89cdcd5" + +babel-plugin-transform-remove-undefined@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-remove-undefined/-/babel-plugin-transform-remove-undefined-0.2.0.tgz#94f052062054c707e8d094acefe79416b63452b1" + dependencies: + babel-helper-evaluate-path "^0.2.0" + +babel-plugin-transform-simplify-comparison-operators@^6.8.5: + version "6.8.5" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-simplify-comparison-operators/-/babel-plugin-transform-simplify-comparison-operators-6.8.5.tgz#a838786baf40cc33a93b95ae09e05591227e43bf" + +babel-plugin-transform-strict-mode@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz#d5faf7aa578a65bbe591cf5edae04a0c67020758" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-undefined-to-void@^6.8.3: + version "6.8.3" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-undefined-to-void/-/babel-plugin-transform-undefined-to-void-6.8.3.tgz#fc52707f6ee1ddc71bb91b0d314fbefdeef9beb4" + +babel-preset-env@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/babel-preset-env/-/babel-preset-env-1.6.1.tgz#a18b564cc9b9afdf4aae57ae3c1b0d99188e6f48" + dependencies: + babel-plugin-check-es2015-constants "^6.22.0" + babel-plugin-syntax-trailing-function-commas "^6.22.0" + babel-plugin-transform-async-to-generator "^6.22.0" + babel-plugin-transform-es2015-arrow-functions "^6.22.0" + babel-plugin-transform-es2015-block-scoped-functions "^6.22.0" + babel-plugin-transform-es2015-block-scoping "^6.23.0" + babel-plugin-transform-es2015-classes "^6.23.0" + babel-plugin-transform-es2015-computed-properties "^6.22.0" + babel-plugin-transform-es2015-destructuring "^6.23.0" + babel-plugin-transform-es2015-duplicate-keys "^6.22.0" + babel-plugin-transform-es2015-for-of "^6.23.0" + babel-plugin-transform-es2015-function-name "^6.22.0" + babel-plugin-transform-es2015-literals "^6.22.0" + babel-plugin-transform-es2015-modules-amd "^6.22.0" + babel-plugin-transform-es2015-modules-commonjs "^6.23.0" + babel-plugin-transform-es2015-modules-systemjs "^6.23.0" + babel-plugin-transform-es2015-modules-umd "^6.23.0" + babel-plugin-transform-es2015-object-super "^6.22.0" + babel-plugin-transform-es2015-parameters "^6.23.0" + babel-plugin-transform-es2015-shorthand-properties "^6.22.0" + babel-plugin-transform-es2015-spread "^6.22.0" + babel-plugin-transform-es2015-sticky-regex "^6.22.0" + babel-plugin-transform-es2015-template-literals "^6.22.0" + babel-plugin-transform-es2015-typeof-symbol "^6.23.0" + babel-plugin-transform-es2015-unicode-regex "^6.22.0" + babel-plugin-transform-exponentiation-operator "^6.22.0" + babel-plugin-transform-regenerator "^6.22.0" + browserslist "^2.1.2" + invariant "^2.2.2" + semver "^5.3.0" + +babel-preset-minify@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/babel-preset-minify/-/babel-preset-minify-0.2.0.tgz#006566552d9b83834472273f306c0131062a0acc" + dependencies: + babel-plugin-minify-builtins "^0.2.0" + babel-plugin-minify-constant-folding "^0.2.0" + babel-plugin-minify-dead-code-elimination "^0.2.0" + babel-plugin-minify-flip-comparisons "^0.2.0" + babel-plugin-minify-guarded-expressions "^0.2.0" + babel-plugin-minify-infinity "^0.2.0" + babel-plugin-minify-mangle-names "^0.2.0" + babel-plugin-minify-numeric-literals "^0.2.0" + babel-plugin-minify-replace "^0.2.0" + babel-plugin-minify-simplify "^0.2.0" + babel-plugin-minify-type-constructors "^0.2.0" + babel-plugin-transform-inline-consecutive-adds "^0.2.0" + babel-plugin-transform-member-expression-literals "^6.8.5" + babel-plugin-transform-merge-sibling-variables "^6.8.6" + babel-plugin-transform-minify-booleans "^6.8.3" + babel-plugin-transform-property-literals "^6.8.5" + babel-plugin-transform-regexp-constructors "^0.2.0" + babel-plugin-transform-remove-console "^6.8.5" + babel-plugin-transform-remove-debugger "^6.8.5" + babel-plugin-transform-remove-undefined "^0.2.0" + babel-plugin-transform-simplify-comparison-operators "^6.8.5" + babel-plugin-transform-undefined-to-void "^6.8.3" + lodash.isplainobject "^4.0.6" + +babel-register@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.26.0.tgz#6ed021173e2fcb486d7acb45c6009a856f647071" + dependencies: + babel-core "^6.26.0" + babel-runtime "^6.26.0" + core-js "^2.5.0" + home-or-tmp "^2.0.0" + lodash "^4.17.4" + mkdirp "^0.5.1" + source-map-support "^0.4.15" + +babel-runtime@^6.18.0, babel-runtime@^6.22.0, babel-runtime@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" + dependencies: + core-js "^2.4.0" + regenerator-runtime "^0.11.0" + +babel-template@^6.24.1, babel-template@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.26.0.tgz#de03e2d16396b069f46dd9fff8521fb1a0e35e02" + dependencies: + babel-runtime "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + lodash "^4.17.4" + +babel-traverse@^6.24.1, babel-traverse@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee" + dependencies: + babel-code-frame "^6.26.0" + babel-messages "^6.23.0" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + debug "^2.6.8" + globals "^9.18.0" + invariant "^2.2.2" + lodash "^4.17.4" + +babel-types@^6.19.0, babel-types@^6.24.1, babel-types@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497" + dependencies: + babel-runtime "^6.26.0" + esutils "^2.0.2" + lodash "^4.17.4" + to-fast-properties "^1.0.3" + +babylon@^6.18.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" + balanced-match@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" @@ -189,6 +812,13 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" +browserslist@^2.1.2: + version "2.10.2" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-2.10.2.tgz#0838eec4b3db2d860cee13bf6c0691e7e8133822" + dependencies: + caniuse-lite "^1.0.30000784" + electron-to-chromium "^1.3.30" + builtin-modules@^1.0.0, builtin-modules@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" @@ -225,6 +855,10 @@ camelcase@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a" +caniuse-lite@^1.0.30000784: + version "1.0.30000784" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000784.tgz#129ced74e9a1280a441880b6cd2bce30ef59e6c0" + caseless@~0.11.0: version "0.11.0" resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.11.0.tgz#715b96ea9841593cc33067923f5ec60ebda4f7d7" @@ -327,6 +961,14 @@ contains-path@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a" +convert-source-map@^1.5.0: + version "1.5.1" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.1.tgz#b8278097b9bc229365de5c62cf5fcaed8b5599e5" + +core-js@^2.4.0, core-js@^2.5.0: + version "2.5.3" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.3.tgz#8acc38345824f16d8365b7c9b4259168e8ed603e" + core-util-is@1.0.2, core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" @@ -432,6 +1074,12 @@ delegates@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" +detect-indent@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208" + dependencies: + repeating "^2.0.0" + doctrine@1.5.0, doctrine@^1.2.2: version "1.5.0" resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa" @@ -451,6 +1099,16 @@ ecc-jsbn@~0.1.1: dependencies: jsbn "~0.1.0" +electron-releases@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/electron-releases/-/electron-releases-2.1.0.tgz#c5614bf811f176ce3c836e368a0625782341fd4e" + +electron-to-chromium@^1.3.30: + version "1.3.30" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.30.tgz#9666f532a64586651fc56a72513692e820d06a80" + dependencies: + electron-releases "^2.1.0" + entities@~1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.1.tgz#6e5c2d0a5621b5dadaecef80b90edfb5cd7772f0" @@ -682,6 +1340,10 @@ estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" +estree-walker@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-0.2.1.tgz#bdafe8095383d8414d5dc2ecf4c9173b6db9412e" + esutils@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" @@ -880,7 +1542,7 @@ glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@~7.1.1, glob@~7.1.2: once "^1.3.0" path-is-absolute "^1.0.0" -globals@^9.14.0: +globals@^9.14.0, globals@^9.18.0: version "9.18.0" resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" @@ -977,6 +1639,13 @@ hoek@4.x.x: version "4.2.0" resolved "https://registry.yarnpkg.com/hoek/-/hoek-4.2.0.tgz#72d9d0754f7fe25ca2d01ad8f8f9a9449a89526d" +home-or-tmp@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8" + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.1" + hosted-git-info@^2.1.4: version "2.5.0" resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.5.0.tgz#6d60e34b3abbc8313062c3b798ef8d901a07af3c" @@ -1061,6 +1730,12 @@ interpret@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.1.0.tgz#7ed1b1410c6a0e0f78cf95d3b8440c63f78b8614" +invariant@^2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.2.tgz#9e1f56ac0acdb6bf303306f338be3b204ae60360" + dependencies: + loose-envify "^1.0.0" + invert-kv@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" @@ -1179,7 +1854,7 @@ js-base64@^2.1.8: version "2.4.0" resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.4.0.tgz#9e566fee624751a1d720c966cd6226d29d4025aa" -js-tokens@^3.0.2: +js-tokens@^3.0.0, js-tokens@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" @@ -1194,6 +1869,14 @@ jsbn@~0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" +jsesc@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" + +jsesc@~0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" + json-schema-traverse@^0.3.0: version "0.3.1" resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340" @@ -1212,6 +1895,10 @@ json-stringify-safe@~5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" +json5@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" + jsonfile@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" @@ -1296,14 +1983,28 @@ lodash.cond@^4.3.0: version "4.5.2" resolved "https://registry.yarnpkg.com/lodash.cond/-/lodash.cond-4.5.2.tgz#f471a1da486be60f6ab955d17115523dd1d255d5" +lodash.isplainobject@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" + lodash.mergewith@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/lodash.mergewith/-/lodash.mergewith-4.6.0.tgz#150cf0a16791f5903b8891eab154609274bdea55" -lodash@^4.0.0, lodash@^4.3.0, lodash@~4.17.4: +lodash.some@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.some/-/lodash.some-4.6.0.tgz#1bb9f314ef6b8baded13b549169b2a945eb68e4d" + +lodash@^4.0.0, lodash@^4.17.4, lodash@^4.3.0, lodash@~4.17.4: version "4.17.4" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" +loose-envify@^1.0.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848" + dependencies: + js-tokens "^3.0.0" + loud-rejection@^1.0.0: version "1.6.0" resolved "https://registry.yarnpkg.com/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f" @@ -1538,7 +2239,7 @@ os-locale@^1.4.0: dependencies: lcid "^1.0.0" -os-tmpdir@^1.0.0: +os-tmpdir@^1.0.0, os-tmpdir@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" @@ -1581,7 +2282,7 @@ path-exists@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" -path-is-absolute@^1.0.0: +path-is-absolute@^1.0.0, path-is-absolute@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" @@ -1658,6 +2359,10 @@ prettier@^1.9.2: version "1.9.2" resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.9.2.tgz#96bc2132f7a32338e6078aeb29727178c6335827" +private@^0.1.6, private@^0.1.7: + version "0.1.8" + resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" + process-nextick-args@~1.0.6: version "1.0.7" resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3" @@ -1730,6 +2435,40 @@ redent@^1.0.0: indent-string "^2.1.0" strip-indent "^1.0.1" +regenerate@^1.2.1: + version "1.3.3" + resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.3.3.tgz#0c336d3980553d755c39b586ae3b20aa49c82b7f" + +regenerator-runtime@^0.11.0: + version "0.11.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" + +regenerator-transform@^0.10.0: + version "0.10.1" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.10.1.tgz#1e4996837231da8b7f3cf4114d71b5691a0680dd" + dependencies: + babel-runtime "^6.18.0" + babel-types "^6.19.0" + private "^0.1.6" + +regexpu-core@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-2.0.0.tgz#49d038837b8dcf8bfa5b9a42139938e6ea2ae240" + dependencies: + regenerate "^1.2.1" + regjsgen "^0.2.0" + regjsparser "^0.1.4" + +regjsgen@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.2.0.tgz#6c016adeac554f75823fe37ac05b92d5a4edb1f7" + +regjsparser@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.1.5.tgz#7ee8f84dc6fa792d3fd0ae228d24bd949ead205c" + dependencies: + jsesc "~0.5.0" + relateurl@0.2.x: version "0.2.7" resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9" @@ -1842,6 +2581,31 @@ rimraf@2, rimraf@^2.2.8: dependencies: glob "^7.0.5" +rollup-plugin-babel-minify@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/rollup-plugin-babel-minify/-/rollup-plugin-babel-minify-3.1.2.tgz#86a99d00b3d60984281baaeff4eb1f0eb509b053" + dependencies: + "@comandeer/babel-plugin-banner" "^1.0.0" + babel-core "^6.21.0" + babel-preset-minify "^0.2.0" + +rollup-plugin-babel@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/rollup-plugin-babel/-/rollup-plugin-babel-3.0.3.tgz#63adedc863130327512a4a9006efc2241c5b7c15" + dependencies: + rollup-pluginutils "^1.5.0" + +rollup-pluginutils@^1.5.0: + version "1.5.2" + resolved "https://registry.yarnpkg.com/rollup-pluginutils/-/rollup-pluginutils-1.5.2.tgz#1e156e778f94b7255bfa1b3d0178be8f5c552408" + dependencies: + estree-walker "^0.2.1" + minimatch "^3.0.2" + +rollup@^0.53.2: + version "0.53.3" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-0.53.3.tgz#e7b6777623df912bd0ca30dc24be791d6ebc8e5a" + run-async@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/run-async/-/run-async-0.1.0.tgz#c8ad4a5e110661e402a7d21b530e009f25f8e389" @@ -1891,7 +2655,7 @@ semistandard@^11.0.0: eslint-plugin-standard "~3.0.1" standard-engine "~7.0.0" -"semver@2 || 3 || 4 || 5": +"semver@2 || 3 || 4 || 5", semver@^5.3.0: version "5.4.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.4.1.tgz#e059c09d8571f0540823733433505d3a2f00b18e" @@ -1915,6 +2679,10 @@ signal-exit@^3.0.0: version "3.0.2" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" +slash@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" + slice-ansi@0.0.4: version "0.0.4" resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35" @@ -1931,7 +2699,13 @@ sntp@2.x.x: dependencies: hoek "4.x.x" -source-map@0.5.x: +source-map-support@^0.4.15: + version "0.4.18" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f" + dependencies: + source-map "^0.5.6" + +source-map@0.5.x, source-map@^0.5.6: version "0.5.7" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" @@ -2112,6 +2886,10 @@ through@^2.3.6, through@~2.3.4, through@~2.3.8: version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" +to-fast-properties@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" + tough-cookie@~2.3.0, tough-cookie@~2.3.3: version "2.3.3" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.3.tgz#0b618a5565b6dea90bf3425d04d55edc475a7561" @@ -2122,6 +2900,10 @@ trim-newlines@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613" +trim-right@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" + "true-case-path@^1.0.2": version "1.0.2" resolved "https://registry.yarnpkg.com/true-case-path/-/true-case-path-1.0.2.tgz#7ec91130924766c7f573be3020c34f8fdfd00d62"