moderndash
Version:
A Typescript-First utility library inspired by Lodash. Optimized for modern browsers.
983 lines (917 loc) • 25.5 kB
JavaScript
// src/array/chunk.ts
function chunk(array, chunkSize) {
const intSize = Math.trunc(chunkSize);
if (array.length === 0 || intSize < 1)
return [];
let index = 0;
let resultIndex = 0;
const result = new Array(Math.ceil(array.length / intSize));
while (index < array.length) {
result[resultIndex++] = array.slice(index, index += intSize);
}
return result;
}
// src/array/count.ts
function count(array, criteria) {
const result = {};
for (const value of array) {
const key = criteria(value);
result[key] = (result[key] ?? 0) + 1;
}
return result;
}
// src/helpers/fastArrayFlat.ts
function fastArrayFlat(arrays) {
let result = arrays.shift() ?? [];
for (const array of arrays) {
result = [...result, ...array];
}
return result;
}
// src/array/difference.ts
function difference(...arraysOrCompareFn) {
const compareFnProvided = typeof arraysOrCompareFn.at(-1) === "function";
const compareFunction = compareFnProvided && arraysOrCompareFn.pop();
const arrays = arraysOrCompareFn;
const firstArray = arrays.shift();
const combinedRestArray = fastArrayFlat(arrays);
if (!compareFunction) {
const restSet = new Set(combinedRestArray);
return firstArray.filter((element) => !restSet.has(element));
}
const difference2 = [];
for (const element of firstArray) {
if (combinedRestArray.every((item) => !compareFunction(element, item))) {
difference2.push(element);
}
}
return difference2;
}
// src/array/dropRightWhile.ts
function dropRightWhile(array, predicate) {
let i = array.length;
while (i > 0 && predicate(array[i - 1])) {
i--;
}
return array.slice(0, i);
}
// src/array/dropWhile.ts
function dropWhile(array, predicate) {
const index = array.findIndex((x) => !predicate(x));
return array.slice(index === -1 ? array.length : index);
}
// src/array/group.ts
function group(array, getGroupKey) {
const result = {};
for (const elem of array) {
const key = getGroupKey(elem);
(result[key] ??= []).push(elem);
}
return result;
}
// src/array/unique.ts
function unique(array, compareFn) {
if (!compareFn)
return [...new Set(array)];
const uniqueArray = [];
for (const value of array) {
if (!uniqueArray.some((uniqueValue) => compareFn(value, uniqueValue)))
uniqueArray.push(value);
}
return uniqueArray;
}
// src/array/intersection.ts
function intersection(...arraysOrCompareFn) {
const compareFnProvided = typeof arraysOrCompareFn.at(-1) === "function";
const compareFunction = compareFnProvided && arraysOrCompareFn.pop();
const arrays = arraysOrCompareFn;
const firstArray = unique(arrays.shift());
const combinedRestArray = fastArrayFlat(arrays);
if (!compareFunction) {
const restSet = new Set(combinedRestArray);
return firstArray.filter((element) => restSet.has(element));
}
const intersection2 = [];
for (const element of firstArray) {
if (combinedRestArray.some((item) => compareFunction(element, item))) {
intersection2.push(element);
}
}
return intersection2;
}
// src/array/move.ts
function move(array, fromIndex, toIndex) {
if (fromIndex < 0 || fromIndex >= array.length)
throw new Error(`Invalid 'fromIndex': ${fromIndex}. Must be between 0 and ${array.length - 1}.`);
if (toIndex < 0 || toIndex >= array.length)
throw new Error(`Invalid 'toIndex': ${toIndex}. Must be between 0 and ${array.length - 1}.`);
if (fromIndex === toIndex)
return array;
const item = array[fromIndex];
if (fromIndex < toIndex)
for (let index = fromIndex; index < toIndex; index++)
array[index] = array[index + 1];
else
for (let index = fromIndex; index > toIndex; index--)
array[index] = array[index - 1];
array[toIndex] = item;
return array;
}
// src/array/range.ts
function range(start, end, step = 1) {
if (step <= 0)
throw new Error("The step must be greater than 0.");
step = start > end ? -step : step;
const length = Math.floor(Math.abs((end - start) / step)) + 1;
const result = new Array(length);
for (let i = 0; i < length; i++) {
result[i] = start + i * step;
}
return result;
}
// src/array/shuffle.ts
function shuffle(array) {
const shuffledArray = [...array];
for (let index = shuffledArray.length - 1; index > 0; index--) {
const randomIndex = Math.floor(Math.random() * (index + 1));
[shuffledArray[index], shuffledArray[randomIndex]] = [shuffledArray[randomIndex], shuffledArray[index]];
}
return shuffledArray;
}
// src/array/sort.ts
function sort(array, ...criteria) {
return [...array].sort((a, b) => {
for (const { order = "asc", by = (item) => item } of criteria) {
const aValue = by(a);
const bValue = by(b);
if (aValue !== bValue) {
const compare = aValue < bValue ? -1 : 1;
return order === "asc" ? compare : -compare;
}
}
return 0;
});
}
// src/array/takeRightWhile.ts
function takeRightWhile(array, predicate) {
const result = [];
for (let i = array.length - 1; i >= 0; i--) {
if (predicate(array[i])) {
result.unshift(array[i]);
} else {
break;
}
}
return result;
}
// src/array/takeWhile.ts
function takeWhile(array, predicate) {
const result = [];
for (const element of array) {
if (predicate(element)) {
result.push(element);
} else {
break;
}
}
return result;
}
// src/crypto/hash.ts
var textEncoder;
async function hash(data, algorithm = "SHA-256") {
textEncoder ??= new TextEncoder();
const dataBuffer = typeof data === "string" ? textEncoder.encode(data) : textEncoder.encode(JSON.stringify(data));
const hashBuffer = await crypto.subtle.digest(algorithm, dataBuffer);
const hashArray = [...new Uint8Array(hashBuffer)];
const hexValues = hashArray.map((b) => b.toString(16).padStart(2, "0"));
return hexValues.join("");
}
// src/crypto/randomInt.ts
function randomInt(min, max) {
if (!Number.isInteger(min) || !Number.isInteger(max))
throw new TypeError("min and max must be integers");
if (min >= max)
throw new Error("max must be greater than min");
const range2 = max - min + 1;
const randomBytes = Math.ceil(Math.log2(range2) / 8);
const maxRandNumber = Math.pow(256, randomBytes);
const randomBuffer = new Uint8Array(randomBytes);
let randomValue;
do {
crypto.getRandomValues(randomBuffer);
randomValue = 0;
for (let index = 0; index < randomBytes; index++) {
randomValue = (randomValue << 8) + randomBuffer[index];
}
} while (randomValue >= maxRandNumber - maxRandNumber % range2);
return min + randomValue % range2;
}
// src/crypto/randomElem.ts
function randomElem(array, multi) {
if (multi === void 0) {
if (array.length === 0) return void 0;
return getSingleElement(array);
}
if (multi && array.length === 0) return [];
const result = new Array(multi);
for (let i = 0; i < multi; i++) {
result[i] = getSingleElement(array);
}
return result;
}
function getSingleElement(array) {
const randomIndex = randomInt(0, array.length - 1);
return array[randomIndex];
}
// src/crypto/randomFloat.ts
function randomFloat(min, max) {
if (min >= max)
throw new Error("max must be greater than min");
const randomBuffer = new Uint32Array(2);
crypto.getRandomValues(randomBuffer);
const randomBigInt = BigInt(randomBuffer[0]) << 21n | BigInt(randomBuffer[1]) >> 11n;
const fraction = Number(randomBigInt) / Number.MAX_SAFE_INTEGER;
return min + fraction * (max - min);
}
// src/crypto/randomString.ts
var DEFAULT_CHARSET = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
function randomString(length, charSet = DEFAULT_CHARSET) {
if (charSet.length <= 0) return "";
let result = "";
for (let index = 0; index < length; index++) {
const randomIndex = randomInt(0, charSet.length - 1);
result += charSet[randomIndex];
}
return result;
}
// src/decorator/toDecorator.ts
function toDecorator(func) {
return function(...args) {
return function(originalMethod, _context) {
const funcArgs = [originalMethod, ...args];
return func(...funcArgs);
};
};
}
// src/function/debounce.ts
function debounce(func, wait) {
let timeoutId;
const debounced = function(...args) {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => {
func.apply(this, args);
timeoutId = void 0;
}, wait);
};
debounced.cancel = function() {
clearTimeout(timeoutId);
timeoutId = void 0;
};
debounced.flush = function(...args) {
debounced.cancel();
func.apply(this, args);
};
debounced.pending = function() {
return timeoutId !== void 0;
};
return debounced;
}
// src/decorator/decDebounce.ts
function decDebounce(wait) {
return toDecorator(debounce)(wait);
}
// src/function/maxCalls.ts
function maxCalls(func, n) {
let count2 = 0;
let result;
return function(...args) {
if (count2 < n) {
count2 += 1;
result = func.apply(this, args);
}
return result;
};
}
// src/decorator/decMaxCalls.ts
function decMaxCalls(n) {
return toDecorator(maxCalls)(n);
}
// src/function/memoize.ts
var defaultResolver = (...args) => JSON.stringify(args);
function memoize(func, options = {}) {
const resolver = options.resolver ?? defaultResolver;
const ttl = options.ttl;
const cache = /* @__PURE__ */ new Map();
const memoizedFunc = function(...args) {
const key = resolver(...args);
if (cache.has(key)) {
const [cacheResult, cacheTime] = cache.get(key);
if (ttl === void 0 || Date.now() - cacheTime < ttl) {
return cacheResult;
}
}
const result = func.apply(this, args);
cache.set(key, [result, Date.now()]);
return result;
};
memoizedFunc.cache = cache;
return memoizedFunc;
}
// src/decorator/decMemoize.ts
function decMemoize(options = {}) {
return toDecorator(memoize)(options);
}
// src/function/minCalls.ts
function minCalls(func, n) {
let count2 = 1;
return function(...args) {
if (count2 > n) {
return func.apply(this, args);
}
count2 += 1;
};
}
// src/decorator/decMinCalls.ts
function decMinCalls(n) {
return toDecorator(minCalls)(n);
}
// src/function/throttle.ts
function throttle(func, wait) {
let inThrottle = false;
let lastResult;
return function(...args) {
if (!inThrottle) {
lastResult = func.apply(this, args);
inThrottle = true;
setTimeout(() => inThrottle = false, wait);
}
return lastResult;
};
}
// src/decorator/decThrottle.ts
function decThrottle(wait) {
return toDecorator(throttle)(wait);
}
// src/function/times.ts
function times(func, n) {
const result = [];
for (let i = 0; i < n; i++) {
result.push(func(i));
}
return result;
}
// src/number/sum.ts
function sum(numbers) {
if (numbers.length === 0)
return NaN;
return numbers.reduce((total, current) => total + current, 0);
}
// src/number/average.ts
function average(numbers) {
if (numbers.length === 0)
return NaN;
return sum(numbers) / numbers.length;
}
// src/number/median.ts
function median(numbers) {
if (numbers.length === 0)
return NaN;
const sortedArray = [...numbers].sort((a, b) => a - b);
const mid = Math.floor(sortedArray.length / 2);
return sortedArray.length % 2 === 0 ? (sortedArray[mid - 1] + sortedArray[mid]) / 2 : sortedArray[mid];
}
// src/number/round.ts
function round(number, precision = 2) {
const factor = Math.pow(10, precision);
return Math.round((number + Number.EPSILON) * factor) / factor;
}
// src/validate/isPlainObject.ts
function isPlainObject(value) {
return value?.constructor === Object;
}
// src/object/flatKeys.ts
function flatKeys(obj) {
const flatObject = {};
for (const [key, value] of Object.entries(obj)) {
addToResult(key, value, flatObject);
}
return flatObject;
}
function addToResult(prefix, value, flatObject) {
if (isPlainObject(value)) {
const flatObj = flatKeys(value);
for (const [flatKey, flatValue] of Object.entries(flatObj)) {
flatObject[`${prefix}.${flatKey}`] = flatValue;
}
} else if (Array.isArray(value)) {
for (const [index, element] of value.entries()) {
addToResult(`${prefix}[${index}]`, element, flatObject);
}
} else {
flatObject[prefix] = value;
}
}
// src/object/merge.ts
function merge(target, ...sources) {
const targetCopy = { ...target };
for (const source of sources) {
for (const [key, value] of Object.entries(source)) {
targetCopy[key] = isPlainObject(value) && isPlainObject(targetCopy[key]) ? merge(targetCopy[key], value) : value;
}
}
return targetCopy;
}
// src/object/pick.ts
function pick(object, keysToPick) {
const result = {};
for (const key of keysToPick) {
result[key] = object[key];
}
return result;
}
// src/object/omit.ts
function omit(object, keysToOmit) {
const allKeys = Object.keys(object);
const filteredKeys = difference(allKeys, keysToOmit);
return pick(object, filteredKeys);
}
// src/object/set.ts
var validPathRegex = /^[^.[\]]+(?:\.[^.[\]]+)*(?:\[\d+])*(?:\.[^.[\]]+(?:\[\d+])*)*$/;
var pathSplitRegex = /\.|(?=\[)/g;
var matchBracketsRegex = /[[\]]/g;
function set(obj, path, value) {
if (!validPathRegex.test(path))
throw new Error("Invalid path, look at the examples for the correct format.");
const pathParts = path.split(pathSplitRegex);
let currentObj = obj;
for (let index = 0; index < pathParts.length; index++) {
const key = pathParts[index].replace(matchBracketsRegex, "");
if (index === pathParts.length - 1) {
currentObj[key] = value;
break;
}
const nextElementInArray = pathParts[index + 1].startsWith("[");
const nextElementInObject = !nextElementInArray;
if (nextElementInArray && !Array.isArray(currentObj[key])) {
currentObj[key] = [];
}
if (nextElementInObject && !isPlainObject(currentObj[key])) {
currentObj[key] = {};
}
currentObj = currentObj[key];
}
return obj;
}
// src/promise/queue.ts
var Queue = class {
running = 0;
maxConcurrent;
paused = false;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
queue = [];
finishedPromise;
finishedResolver;
/**
* @constructor
* @param maxConcurrent The maximum number of async functions to run concurrently.
*/
constructor(maxConcurrent) {
this.maxConcurrent = maxConcurrent;
}
add(asyncFn) {
if (Array.isArray(asyncFn)) {
const promises = asyncFn.map((fn) => this.buildWaitingPromise(fn));
return Promise.all(promises);
} else {
return this.buildWaitingPromise(asyncFn);
}
}
buildWaitingPromise(asyncFn) {
return new Promise((resolve, reject) => {
this.queue.push({ asyncFn, resolve, reject });
this.run();
});
}
run() {
while (this.queue.length > 0 && this.running < this.maxConcurrent && !this.paused) {
this.running++;
const queueElement = this.queue.shift();
void queueElement.asyncFn().then((result) => {
queueElement.resolve(result);
}).catch((error) => {
queueElement.reject(error);
}).finally(() => {
this.running--;
this.run();
});
}
this.checkIfDone();
}
/** Removes all the tasks from the queue */
clear() {
for (const queueElement of this.queue) {
queueElement.reject(new Error("Queue cleared"));
}
this.queue = [];
}
/** Pauses the execution of the queue */
pause() {
this.paused = true;
}
/** Resumes the execution of the tasks in the queue */
resume() {
this.paused = false;
this.run();
}
/** Return the tasks added to the queue */
getQueue() {
return this.queue.map((queueElement) => queueElement.asyncFn);
}
/** Returns whether the queue is paused */
isPaused() {
return this.paused;
}
/** Returns a shared promise that resolves when the queue is empty and all tasks have finished executing. */
done() {
if (this.queue.length === 0 && this.running === 0)
return Promise.resolve(true);
this.finishedPromise ??= new Promise((resolve) => this.finishedResolver = () => resolve(true));
return this.finishedPromise;
}
checkIfDone() {
if (this.queue.length === 0 && this.running === 0 && this.finishedResolver) {
this.finishedResolver();
this.finishedPromise = void 0;
this.finishedResolver = void 0;
}
}
};
// src/promise/races.ts
function races(waitFor, ...promises) {
return new Promise((resolve, reject) => {
if (promises.length < waitFor)
waitFor = promises.length;
const results = [];
let resolved = 0;
for (const promise of promises) {
promise.then((value) => {
results.push(value);
resolved++;
if (resolved >= waitFor) {
resolve(results);
}
}).catch((error) => {
reject(error);
});
}
});
}
// src/promise/sleep.ts
function sleep(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
// src/promise/retry.ts
async function retry(func, options) {
const backOffFn = options?.backoff ?? ((retries2) => 2 ** retries2 * 100);
const maxRetries = options?.maxRetries ?? 5;
const onRetry = options?.onRetry ?? (() => {
});
let retries = 0;
let lastError;
while (retries <= maxRetries) {
try {
if (retries > 0)
onRetry(lastError, retries);
return await func();
} catch (error) {
lastError = error;
retries++;
if (retries > maxRetries) {
throw error;
}
await sleep(backOffFn(retries));
}
}
throw new Error("Retry terminated without success, this should never happen");
}
// src/promise/timeout.ts
function timeout(promise, timeout2) {
return new Promise((resolve, reject) => {
const timeoutId = setTimeout(() => {
reject(new Error(`Promise timed out after ${timeout2}ms`));
}, timeout2);
promise.then(
(result) => {
clearTimeout(timeoutId);
resolve(result);
},
(error) => {
clearTimeout(timeoutId);
reject(error);
}
);
});
}
// src/promise/tryCatch.ts
async function tryCatch(promise) {
try {
const data = await promise;
return [data, void 0];
} catch (error) {
if (error instanceof Error)
return [void 0, error];
throw error;
}
}
// src/string/splitWords.ts
var wordsRegex = /(?:\d*[a-z]+)|(?:[A-Z][a-z]+)|(?:\d*[A-Z]+(?=[^a-z]|$))|\d+/g;
function splitWords(str) {
return str.match(wordsRegex) ?? [];
}
// src/string/capitalize.ts
function capitalize(str) {
if (str === "") return "";
return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase();
}
// src/string/deburr.ts
var accentControlRegex = /[\u0300-\u036F]/g;
function deburr(str) {
return str.normalize("NFD").replace(accentControlRegex, "");
}
// src/string/camelCase.ts
function camelCase(str) {
if (str === "") return "";
str = deburr(str);
const words = splitWords(str);
if (words.length === 0) return "";
let camelCase2 = words[0].toLowerCase();
for (let index = 1; index < words.length; index++) {
const word = words[index];
camelCase2 += capitalize(word);
}
return camelCase2;
}
// src/string/escapeHtml.ts
var charRegex = /["&'<>]/g;
var escapeChars = /* @__PURE__ */ new Map([
["&", "&"],
["<", "<"],
[">", ">"],
["'", "'"],
['"', """]
]);
function escapeHtml(str) {
return str.replace(charRegex, (char) => escapeChars.get(char));
}
// src/string/escapeRegExp.ts
var escapeCharsRegex = /[$()*+.?[\\\]^{|}]/g;
function escapeRegExp(str) {
return str.replace(escapeCharsRegex, "\\$&");
}
// src/string/kebabCase.ts
function kebabCase(str) {
if (str === "") return "";
str = deburr(str);
const words = splitWords(str);
let kebabCase2 = "";
for (const word of words) {
kebabCase2 += word.toLowerCase() + "-";
}
return kebabCase2.slice(0, -1);
}
// src/string/pascalCase.ts
function pascalCase(str) {
if (str === "") return "";
str = deburr(str);
const words = splitWords(str);
let pascalCase2 = "";
for (const word of words) {
pascalCase2 += capitalize(word);
}
return pascalCase2;
}
// src/string/replaceLast.ts
function replaceLast(str, searchFor, replaceWith) {
const index = str.lastIndexOf(searchFor);
if (index === -1)
return str;
return str.slice(0, index) + replaceWith + str.slice(index + searchFor.length);
}
// src/string/snakeCase.ts
function snakeCase(str) {
if (str === "") return "";
str = deburr(str);
const words = splitWords(str);
let snakeCase2 = "";
for (const word of words) {
if (snakeCase2.length > 0) {
snakeCase2 += "_";
}
snakeCase2 += word.toLowerCase();
}
return snakeCase2;
}
// src/string/titleCase.ts
function titleCase(str) {
if (str === "") return "";
str = deburr(str);
const words = splitWords(str);
let titleCase2 = "";
for (const word of words) {
titleCase2 += capitalize(word) + " ";
}
return titleCase2.trimEnd();
}
// src/string/trim.ts
function trim(str, chars) {
let startIndex = 0;
while (startIndex < str.length && chars.includes(str[startIndex])) {
startIndex++;
}
let endIndex = str.length - 1;
while (endIndex >= startIndex && chars.includes(str[endIndex])) {
endIndex--;
}
return str.slice(startIndex, endIndex + 1);
}
// src/string/trimEnd.ts
function trimEnd(str, chars) {
let lastIndex = str.length - 1;
while (lastIndex >= 0 && chars.includes(str[lastIndex])) {
lastIndex--;
}
return str.slice(0, lastIndex + 1);
}
// src/string/trimStart.ts
function trimStart(str, chars) {
let startIndex = 0;
while (startIndex < str.length && chars.includes(str[startIndex])) {
startIndex++;
}
return str.slice(startIndex);
}
// src/string/truncate.ts
function truncate(str, options) {
const { length = 30, ellipsis = "...", separator } = options ?? {};
if (str.length <= length) return str;
const end = length - ellipsis.length;
if (end < 1)
return ellipsis;
let truncated = str.slice(0, end);
if (separator) {
const sepIndex = truncated.lastIndexOf(separator);
if (sepIndex > -1) {
truncated = truncated.slice(0, sepIndex);
}
}
return truncated + ellipsis;
}
// src/string/unescapeHtml.ts
var htmlEntitiesRegex = /&(?:amp|lt|gt|quot|#39);/g;
var entityMap = /* @__PURE__ */ new Map([
["&", "&"],
["<", "<"],
[">", ">"],
[""", '"'],
["'", "'"]
]);
function unescapeHtml(str) {
return str.replace(htmlEntitiesRegex, (entity) => entityMap.get(entity));
}
// src/validate/isEmpty.ts
function isEmpty(value) {
if (value === null || value === void 0)
return true;
if (typeof value === "string" || Array.isArray(value))
return value.length === 0;
if (value instanceof Map || value instanceof Set)
return value.size === 0;
if (ArrayBuffer.isView(value))
return value.byteLength === 0;
if (typeof value === "object")
return Object.keys(value).length === 0;
return false;
}
// src/validate/isEqual.ts
function isEqual(a, b) {
if (Object.is(a, b)) return true;
if (typeof a !== typeof b) return false;
if (Array.isArray(a) && Array.isArray(b))
return isSameArray(a, b);
if (a instanceof Date && b instanceof Date)
return a.getTime() === b.getTime();
if (a instanceof RegExp && b instanceof RegExp)
return a.toString() === b.toString();
if (isPlainObject(a) && isPlainObject(b))
return isSameObject(a, b);
if (a instanceof ArrayBuffer && b instanceof ArrayBuffer)
return dataViewsAreEqual(new DataView(a), new DataView(b));
if (a instanceof DataView && b instanceof DataView)
return dataViewsAreEqual(a, b);
if (isTypedArray(a) && isTypedArray(b)) {
if (a.byteLength !== b.byteLength) return false;
return isSameArray(a, b);
}
return false;
}
function isSameObject(a, b) {
const keys1 = Object.keys(a);
const keys2 = Object.keys(b);
if (!isEqual(keys1, keys2)) return false;
for (const key of keys1) {
if (!isEqual(a[key], b[key])) return false;
}
return true;
}
function isSameArray(a, b) {
if (a.length !== b.length) return false;
return a.every((element, index) => isEqual(element, b[index]));
}
function dataViewsAreEqual(a, b) {
if (a.byteLength !== b.byteLength) return false;
for (let offset = 0; offset < a.byteLength; offset++) {
if (a.getUint8(offset) !== b.getUint8(offset)) return false;
}
return true;
}
function isTypedArray(value) {
return ArrayBuffer.isView(value) && !(value instanceof DataView);
}
// src/validate/isUrl.ts
function isUrl(str) {
try {
new URL(str);
return true;
} catch {
return false;
}
}
export {
Queue,
average,
camelCase,
capitalize,
chunk,
count,
debounce,
deburr,
decDebounce,
decMaxCalls,
decMemoize,
decMinCalls,
decThrottle,
difference,
dropRightWhile,
dropWhile,
escapeHtml,
escapeRegExp,
flatKeys,
group,
hash,
intersection,
isEmpty,
isEqual,
isPlainObject,
isUrl,
kebabCase,
maxCalls,
median,
memoize,
merge,
minCalls,
move,
omit,
pascalCase,
pick,
races,
randomElem,
randomFloat,
randomInt,
randomString,
range,
replaceLast,
retry,
round,
set,
shuffle,
sleep,
snakeCase,
sort,
splitWords,
sum,
takeRightWhile,
takeWhile,
throttle,
timeout,
times,
titleCase,
toDecorator,
trim,
trimEnd,
trimStart,
truncate,
tryCatch,
unescapeHtml,
unique
};
//# sourceMappingURL=index.js.map