Added comments to the module building scripts
This commit is contained in:
1101
dist/_30s.es5.js
vendored
Normal file
1101
dist/_30s.es5.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1
dist/_30s.es5.min.js
vendored
Normal file
1
dist/_30s.es5.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
664
dist/_30s.esm.js
vendored
Normal file
664
dist/_30s.esm.js
vendored
Normal file
@ -0,0 +1,664 @@
|
||||
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 += `<li>${item}</li>`));
|
||||
|
||||
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 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 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 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 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 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 isArmstrongNumber = digits =>
|
||||
(arr => arr.reduce((a, d) => a + Math.pow(parseInt(d), arr.length), 0) == digits)(
|
||||
(digits + '').split('')
|
||||
);
|
||||
|
||||
const isArray = val => !!val && Array.isArray(val);
|
||||
|
||||
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 isNumber = val => typeof val === 'number';
|
||||
|
||||
const isPrime = num => {
|
||||
const boundary = Math.floor(Math.sqrt(num));
|
||||
for (var i = 2; i * i <= boundary; i++) if (num % i == 0) return false;
|
||||
return num >= 2;
|
||||
};
|
||||
|
||||
const isString = val => typeof val === 'string';
|
||||
|
||||
const isSymbol = val => typeof val === 'symbol';
|
||||
|
||||
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 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 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 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 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 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 runPromisesInSeries = ps => ps.reduce((p, next) => p.then(next), Promise.resolve());
|
||||
|
||||
const sample = arr => arr[Math.floor(Math.random() * arr.length)];
|
||||
|
||||
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 sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
|
||||
|
||||
const sortCharactersInString = str =>
|
||||
str
|
||||
.split('')
|
||||
.sort((a, b) => a.localeCompare(b))
|
||||
.join('');
|
||||
|
||||
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(Math.pow(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 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 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 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,coalesce,coalesceFactory,collatz,collectInto,compact,compose,countOccurrences,countVowels,currentURL,curry,deepFlatten,detectDeviceType,difference,differenceWith,digitize,distance,distinctValuesOfArray,dropElements,dropRight,elementIsVisibleInViewport,escapeHTML,escapeRegExp,everyNth,extendHex,factorial,fibonacci,fibonacciCountUntilNum,fibonacciUntilNum,filterNonUnique,flatten,flattenDepth,flip,fromCamelCase,functionName,gcd,getDaysDiffBetweenDates,getScrollPosition,getStyle,getType,getURLParameters,groupBy,hammingDistance,hasClass,head,hexToRGB,hide,httpsRedirect,initial,initialize2DArray,initializeArrayWithRange,initializeArrayWithValues,inRange,intersection,isArmstrongNumber,isArray,isBoolean,isDivisible,isEven,isFunction,isNumber,isPrime,isString,isSymbol,JSONToDate,JSONToFile,last,lcm,lowercaseKeys,mapObject,max,median,min,negate,nthElement,objectFromPairs,objectToPairs,onUserInputChange,orderBy,palindrome,percentile,pick,pipeFunctions,powerset,primes,promisify,pull,pullAtIndex,pullAtValue,quickSort,randomHexColorCode,randomIntegerInRange,randomNumberInRange,readFileLines,redirect,remove,repeatString,reverseString,RGBToHex,round,runPromisesInSeries,sample,scrollToTop,sdbm,select,setStyle,shallowClone,show,shuffle,similarity,sleep,sortCharactersInString,speechSynthesis,splitLines,spreadOver,standardDeviation,sum,symmetricDifference,tail,take,takeRight,timeTaken,toCamelCase,toDecimalMark,toEnglishDate,toggleClass,toKebabCase,tomorrow,toOrdinalSuffix,toSnakeCase,truncateString,truthCheckCollection,unescapeHTML,union,UUIDGeneratorBrowser,UUIDGeneratorNode,validateNumber,without,words,zip,zipObject,}
|
||||
|
||||
export default imports;
|
||||
672
dist/_30s.js
vendored
Normal file
672
dist/_30s.js
vendored
Normal file
@ -0,0 +1,672 @@
|
||||
(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 += `<li>${item}</li>`));
|
||||
|
||||
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 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 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 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 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 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 isArmstrongNumber = digits =>
|
||||
(arr => arr.reduce((a, d) => a + Math.pow(parseInt(d), arr.length), 0) == digits)(
|
||||
(digits + '').split('')
|
||||
);
|
||||
|
||||
const isArray = val => !!val && Array.isArray(val);
|
||||
|
||||
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 isNumber = val => typeof val === 'number';
|
||||
|
||||
const isPrime = num => {
|
||||
const boundary = Math.floor(Math.sqrt(num));
|
||||
for (var i = 2; i * i <= boundary; i++) if (num % i == 0) return false;
|
||||
return num >= 2;
|
||||
};
|
||||
|
||||
const isString = val => typeof val === 'string';
|
||||
|
||||
const isSymbol = val => typeof val === 'symbol';
|
||||
|
||||
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 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 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 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 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 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 runPromisesInSeries = ps => ps.reduce((p, next) => p.then(next), Promise.resolve());
|
||||
|
||||
const sample = arr => arr[Math.floor(Math.random() * arr.length)];
|
||||
|
||||
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 sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
|
||||
|
||||
const sortCharactersInString = str =>
|
||||
str
|
||||
.split('')
|
||||
.sort((a, b) => a.localeCompare(b))
|
||||
.join('');
|
||||
|
||||
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(Math.pow(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 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 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 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,coalesce,coalesceFactory,collatz,collectInto,compact,compose,countOccurrences,countVowels,currentURL,curry,deepFlatten,detectDeviceType,difference,differenceWith,digitize,distance,distinctValuesOfArray,dropElements,dropRight,elementIsVisibleInViewport,escapeHTML,escapeRegExp,everyNth,extendHex,factorial,fibonacci,fibonacciCountUntilNum,fibonacciUntilNum,filterNonUnique,flatten,flattenDepth,flip,fromCamelCase,functionName,gcd,getDaysDiffBetweenDates,getScrollPosition,getStyle,getType,getURLParameters,groupBy,hammingDistance,hasClass,head,hexToRGB,hide,httpsRedirect,initial,initialize2DArray,initializeArrayWithRange,initializeArrayWithValues,inRange,intersection,isArmstrongNumber,isArray,isBoolean,isDivisible,isEven,isFunction,isNumber,isPrime,isString,isSymbol,JSONToDate,JSONToFile,last,lcm,lowercaseKeys,mapObject,max,median,min,negate,nthElement,objectFromPairs,objectToPairs,onUserInputChange,orderBy,palindrome,percentile,pick,pipeFunctions,powerset,primes,promisify,pull,pullAtIndex,pullAtValue,quickSort,randomHexColorCode,randomIntegerInRange,randomNumberInRange,readFileLines,redirect,remove,repeatString,reverseString,RGBToHex,round,runPromisesInSeries,sample,scrollToTop,sdbm,select,setStyle,shallowClone,show,shuffle,similarity,sleep,sortCharactersInString,speechSynthesis,splitLines,spreadOver,standardDeviation,sum,symmetricDifference,tail,take,takeRight,timeTaken,toCamelCase,toDecimalMark,toEnglishDate,toggleClass,toKebabCase,tomorrow,toOrdinalSuffix,toSnakeCase,truncateString,truthCheckCollection,unescapeHTML,union,UUIDGeneratorBrowser,UUIDGeneratorNode,validateNumber,without,words,zip,zipObject,}
|
||||
|
||||
return imports;
|
||||
|
||||
})));
|
||||
1
dist/_30s.min.js
vendored
Normal file
1
dist/_30s.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@ -1,74 +1,74 @@
|
||||
/*
|
||||
Builds the `_30s` module.
|
||||
*/
|
||||
// Load modules
|
||||
const fs = require('fs-extra');
|
||||
const cp = require('child_process');
|
||||
const path = require('path');
|
||||
const chalk = require('chalk');
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
@ -1,17 +1,21 @@
|
||||
/*
|
||||
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] });
|
||||
|
||||
Reference in New Issue
Block a user