foreslash 0.3.2 → 0.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +26 -0
- package/lib/index.cmn.cjs +305 -4
- package/lib/index.d.ts +269 -26
- package/lib/index.mjs +298 -5
- package/lib/index.umd.js +305 -4
- package/package.json +1 -1
package/lib/index.mjs
CHANGED
|
@@ -43,6 +43,10 @@ function cartesianProduct(...arrList) {
|
|
|
43
43
|
return res;
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
+
function castArray(value) {
|
|
47
|
+
return Array.isArray(value) ? value.slice() : [value];
|
|
48
|
+
}
|
|
49
|
+
|
|
46
50
|
function chunk(array, size = 2) {
|
|
47
51
|
const res = [];
|
|
48
52
|
if (size < 1 || isNaN(size))
|
|
@@ -607,6 +611,201 @@ function format(num, options) {
|
|
|
607
611
|
return sign + integer;
|
|
608
612
|
}
|
|
609
613
|
|
|
614
|
+
function lerp(val1, val2, t) {
|
|
615
|
+
if (isNumber(val1)) {
|
|
616
|
+
if (!isNumber(val2))
|
|
617
|
+
throw new Error('Invalid val2 parameter: val2 should be a number');
|
|
618
|
+
return _lerp(val1, val2, t);
|
|
619
|
+
}
|
|
620
|
+
else if (isArray(val1)) {
|
|
621
|
+
if (!isArray(val2))
|
|
622
|
+
throw new Error('Invalid val2 parameter: val2 should be an Array');
|
|
623
|
+
if (val1.length !== val2.length) {
|
|
624
|
+
throw new Error(`Invalid val2 parameter: the length of val2 (${val2.length}) should be consistent with val1 (${val1.length})`);
|
|
625
|
+
}
|
|
626
|
+
if (val1.length === 0)
|
|
627
|
+
return [];
|
|
628
|
+
if (isNumber(val1[0])) {
|
|
629
|
+
if (!isNumber(val2[0]))
|
|
630
|
+
throw new Error('Invalid val2 parameter: val2 should be an Array<number>');
|
|
631
|
+
return val1.map((v1, index) => _lerp(v1, val2[index], t));
|
|
632
|
+
}
|
|
633
|
+
else if (isArray(val1[0])) {
|
|
634
|
+
const res = [];
|
|
635
|
+
for (let i = 0; i < val1.length; i++) {
|
|
636
|
+
const arr1 = val1[i];
|
|
637
|
+
const arr2 = val2[i];
|
|
638
|
+
if (arr1.length !== arr2.length) {
|
|
639
|
+
throw new Error(`Invalid val2 parameter: The length of array at index ${i} in val2 (${arr2.length}) must match the length of the corresponding array in val1 (${arr1.length})`);
|
|
640
|
+
}
|
|
641
|
+
res.push(arr1.map((v1, index) => _lerp(v1, arr2[index], t)));
|
|
642
|
+
}
|
|
643
|
+
return res;
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
throw new Error('Invalid val1 parameter: val1 should be a number or Array');
|
|
647
|
+
}
|
|
648
|
+
function _lerp(val1, val2, t) {
|
|
649
|
+
return val1 + (val2 - val1) * t;
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
function romanNumerals(num, options) {
|
|
653
|
+
const str = decimalNotation(num);
|
|
654
|
+
if (/NaN|Inf/.test(str))
|
|
655
|
+
return str;
|
|
656
|
+
const type = (options || {}).type || 'unicode';
|
|
657
|
+
const thousand = (options || {}).thousand || 'normal';
|
|
658
|
+
const forceSplitThousand = thousand === 'strict';
|
|
659
|
+
const integer = str.split('.')[0].replace('-', '');
|
|
660
|
+
if (integer === '0') {
|
|
661
|
+
const zero = (options || {}).zero || '0';
|
|
662
|
+
if (type === 'json')
|
|
663
|
+
return `["${zero}"]`;
|
|
664
|
+
else
|
|
665
|
+
return zero;
|
|
666
|
+
}
|
|
667
|
+
if (integer === '1') {
|
|
668
|
+
const one = (options || {}).one || 'I';
|
|
669
|
+
if (type === 'json')
|
|
670
|
+
return `["${one}"]`;
|
|
671
|
+
else
|
|
672
|
+
return one;
|
|
673
|
+
}
|
|
674
|
+
const chunks = chunk(Array.from(integer).reverse(), 3);
|
|
675
|
+
const romanChunks = [];
|
|
676
|
+
for (let i = 0; i < chunks.length; i++) {
|
|
677
|
+
const val = Number(chunks[i].reverse().join(''));
|
|
678
|
+
if (i === chunks.length - 2 && !forceSplitThousand && Number(chunks[i + 1]) < 4) {
|
|
679
|
+
romanChunks.push(number2roman(val + Number(chunks[i + 1]) * 1000));
|
|
680
|
+
break;
|
|
681
|
+
}
|
|
682
|
+
else {
|
|
683
|
+
romanChunks.push(number2roman(val));
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
switch (type) {
|
|
687
|
+
case 'js':
|
|
688
|
+
return romanChunks
|
|
689
|
+
.map((str, index) => str
|
|
690
|
+
.split('')
|
|
691
|
+
.map((s) => s + '\\\\u0305'.repeat(index))
|
|
692
|
+
.join(''))
|
|
693
|
+
.reverse()
|
|
694
|
+
.join('');
|
|
695
|
+
case 'html':
|
|
696
|
+
return romanChunks
|
|
697
|
+
.map((str, index) => str
|
|
698
|
+
.split('')
|
|
699
|
+
.map((s) => s + '̅'.repeat(index))
|
|
700
|
+
.join(''))
|
|
701
|
+
.reverse()
|
|
702
|
+
.join('');
|
|
703
|
+
case 'json':
|
|
704
|
+
return `[${romanChunks.map((str) => `"${str}"`).join(', ')}]`;
|
|
705
|
+
case 'unicode':
|
|
706
|
+
default:
|
|
707
|
+
return romanChunks
|
|
708
|
+
.map((str, index) => str
|
|
709
|
+
.split('')
|
|
710
|
+
.map((s) => s + '\u0305'.repeat(index))
|
|
711
|
+
.join(''))
|
|
712
|
+
.reverse()
|
|
713
|
+
.join('');
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
|
+
function number2roman(num) {
|
|
717
|
+
const symbols = [
|
|
718
|
+
[1000, 'M'],
|
|
719
|
+
[900, 'CM'],
|
|
720
|
+
[500, 'D'],
|
|
721
|
+
[400, 'CD'],
|
|
722
|
+
[100, 'C'],
|
|
723
|
+
[90, 'XC'],
|
|
724
|
+
[50, 'L'],
|
|
725
|
+
[40, 'XL'],
|
|
726
|
+
[10, 'X'],
|
|
727
|
+
[9, 'IX'],
|
|
728
|
+
[5, 'V'],
|
|
729
|
+
[4, 'IV'],
|
|
730
|
+
[1, 'I'],
|
|
731
|
+
];
|
|
732
|
+
let roman = '';
|
|
733
|
+
for (const [val, str] of symbols) {
|
|
734
|
+
while (num >= val) {
|
|
735
|
+
num -= val;
|
|
736
|
+
roman += str;
|
|
737
|
+
}
|
|
738
|
+
if (num == 0)
|
|
739
|
+
break;
|
|
740
|
+
}
|
|
741
|
+
return roman;
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
function scientificNotation(num, options) {
|
|
745
|
+
const str = decimalNotation(num);
|
|
746
|
+
if (/NaN|Inf/.test(str))
|
|
747
|
+
return str;
|
|
748
|
+
const type = (options || {}).type || 'unicode';
|
|
749
|
+
const _precision = (options || {}).precision;
|
|
750
|
+
const precision = isNumber(_precision) ? clamp(_precision, 0, Infinity) : null;
|
|
751
|
+
const round = (options || {}).round || 'round';
|
|
752
|
+
let [integer, fractional] = str.split('.');
|
|
753
|
+
let sign = '';
|
|
754
|
+
if (/^-/.test(integer)) {
|
|
755
|
+
integer = integer.substring(1);
|
|
756
|
+
sign = '-';
|
|
757
|
+
}
|
|
758
|
+
fractional = fractional !== null && fractional !== void 0 ? fractional : '';
|
|
759
|
+
let exp = 0;
|
|
760
|
+
let n = '';
|
|
761
|
+
if (integer === '0') {
|
|
762
|
+
exp = /^(0+)/.test(fractional) ? -(fractional.match(/^(0+)/)[0].length + 1) : -1;
|
|
763
|
+
[integer, fractional] = [fractional.slice(-exp - 1, -exp), fractional.slice(-exp)];
|
|
764
|
+
}
|
|
765
|
+
else {
|
|
766
|
+
exp = integer.length - 1;
|
|
767
|
+
[integer, fractional] = [integer.slice(0, 1), integer.slice(1) + fractional];
|
|
768
|
+
}
|
|
769
|
+
if (isNumber(precision)) {
|
|
770
|
+
if (fractional.length > precision) {
|
|
771
|
+
const roundMap = { round: roundBase, banker: roundBank, floor: roundFloor, ceil: roundCeil };
|
|
772
|
+
[integer, fractional] = (roundMap[round] || roundBase)(integer, fractional, precision, !!sign);
|
|
773
|
+
}
|
|
774
|
+
else if (fractional.length < precision) {
|
|
775
|
+
fractional += '0'.repeat(precision - fractional.length);
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
else {
|
|
779
|
+
fractional = fractional.replace(/0+$/, '');
|
|
780
|
+
}
|
|
781
|
+
if ((precision === null && fractional) || (isNumber(precision) && precision > 0)) {
|
|
782
|
+
n = sign + integer + '.' + fractional;
|
|
783
|
+
}
|
|
784
|
+
else
|
|
785
|
+
n = sign + integer;
|
|
786
|
+
switch (type) {
|
|
787
|
+
case 'exp':
|
|
788
|
+
return `${n}e${exp < 0 ? '' : '+'}${exp}`;
|
|
789
|
+
case 'js':
|
|
790
|
+
return `${n}*10**${exp}`;
|
|
791
|
+
case 'code':
|
|
792
|
+
return `${n}*10^${exp}`;
|
|
793
|
+
case 'html':
|
|
794
|
+
return `${n}×10<sup>${exp}</sup>`;
|
|
795
|
+
case 'json':
|
|
796
|
+
return `{"number":"${n}","exp":${exp}}`;
|
|
797
|
+
case 'unicode':
|
|
798
|
+
default:
|
|
799
|
+
return `${n}×10${transferNumberToUniCode(String(exp))}`;
|
|
800
|
+
}
|
|
801
|
+
}
|
|
802
|
+
function transferNumberToUniCode(n) {
|
|
803
|
+
const strMap = Object.assign(Object.assign({}, Array.from('⁰¹²³⁴⁵⁶⁷⁸⁹')), { '-': '⁻', '+': '⁺' });
|
|
804
|
+
return Array.from(n)
|
|
805
|
+
.map((s) => (strMap[s] ? strMap[s] : s))
|
|
806
|
+
.join('');
|
|
807
|
+
}
|
|
808
|
+
|
|
610
809
|
function parallel(args, fn, options) {
|
|
611
810
|
return __awaiter(this, void 0, void 0, function* () {
|
|
612
811
|
if (!args.length)
|
|
@@ -1238,6 +1437,54 @@ function randomChoice(arr, weights) {
|
|
|
1238
1437
|
return arr[index];
|
|
1239
1438
|
}
|
|
1240
1439
|
|
|
1440
|
+
function randomDistribution(p, options) {
|
|
1441
|
+
const threshold = (options === null || options === void 0 ? void 0 : options.threshold) ? Math.max(options.threshold, Number.MIN_VALUE * 2) : 5e-6;
|
|
1442
|
+
const C = getInitP(p, threshold);
|
|
1443
|
+
let current = C;
|
|
1444
|
+
return function getRandomDistribution() {
|
|
1445
|
+
const res = Math.random() < current;
|
|
1446
|
+
if (res)
|
|
1447
|
+
current = C;
|
|
1448
|
+
else
|
|
1449
|
+
current += C;
|
|
1450
|
+
return res;
|
|
1451
|
+
};
|
|
1452
|
+
}
|
|
1453
|
+
function getInitP(targetP, threshold = 5e-6) {
|
|
1454
|
+
if (targetP <= 0)
|
|
1455
|
+
return 0;
|
|
1456
|
+
if (targetP >= 1)
|
|
1457
|
+
return 1;
|
|
1458
|
+
let [down, up] = [0, 1];
|
|
1459
|
+
let mid = 1;
|
|
1460
|
+
let tempP = 1;
|
|
1461
|
+
let tempPLast = 1;
|
|
1462
|
+
let step = 64;
|
|
1463
|
+
while (step-- > 0) {
|
|
1464
|
+
mid = (down + up) / 2;
|
|
1465
|
+
tempP = getRealPFromInitP(mid);
|
|
1466
|
+
if (Math.abs(tempPLast - tempP) < threshold)
|
|
1467
|
+
break;
|
|
1468
|
+
if (tempP > targetP)
|
|
1469
|
+
up = mid;
|
|
1470
|
+
else
|
|
1471
|
+
down = mid;
|
|
1472
|
+
}
|
|
1473
|
+
return mid;
|
|
1474
|
+
}
|
|
1475
|
+
function getRealPFromInitP(initP) {
|
|
1476
|
+
let sum = 0;
|
|
1477
|
+
let prod = 0;
|
|
1478
|
+
let cur = 0;
|
|
1479
|
+
let max = Math.ceil(1 / initP);
|
|
1480
|
+
for (let n = 1; n <= max; n++) {
|
|
1481
|
+
cur = Math.min(1, n * initP) * (1 - prod);
|
|
1482
|
+
prod += cur;
|
|
1483
|
+
sum += n * cur;
|
|
1484
|
+
}
|
|
1485
|
+
return 1 / sum;
|
|
1486
|
+
}
|
|
1487
|
+
|
|
1241
1488
|
const radix32 = '0123456789abcdefghijklmnopqrstuv';
|
|
1242
1489
|
const base32Chars = 'abcdefghijklmnopqrstuvwxyz234567';
|
|
1243
1490
|
const base32Crockford = '0123456789abcdefghjkmnpqrstvwxyz';
|
|
@@ -1864,22 +2111,22 @@ function _deepClone(obj, map, options) {
|
|
|
1864
2111
|
if (isFormData(obj))
|
|
1865
2112
|
return _cloneFormData(obj, map, _deepClone, options);
|
|
1866
2113
|
let res;
|
|
1867
|
-
if (obj
|
|
2114
|
+
if (isDate(obj)) {
|
|
1868
2115
|
res = new Date(obj.valueOf());
|
|
1869
2116
|
map.set(obj, res);
|
|
1870
2117
|
}
|
|
1871
|
-
else if (obj
|
|
2118
|
+
else if (isRegExp(obj)) {
|
|
1872
2119
|
res = new RegExp(obj.source, obj.flags);
|
|
1873
2120
|
map.set(obj, res);
|
|
1874
2121
|
}
|
|
1875
|
-
else if (obj
|
|
2122
|
+
else if (isArrayBuffer(obj)) {
|
|
1876
2123
|
res = _cloneArrayBuffer(obj, map);
|
|
1877
2124
|
}
|
|
1878
2125
|
else if (isTypedArray(obj)) {
|
|
1879
2126
|
res = new obj.constructor(_cloneArrayBuffer(obj.buffer, map), obj.byteOffset, obj.length);
|
|
1880
2127
|
map.set(obj, res);
|
|
1881
2128
|
}
|
|
1882
|
-
else if (obj
|
|
2129
|
+
else if (isDataView(obj)) {
|
|
1883
2130
|
res = new DataView(map.has(obj.buffer) ? map.get(obj.buffer) : _cloneArrayBuffer(obj.buffer, map), obj.byteOffset, obj.byteLength);
|
|
1884
2131
|
map.set(obj, res);
|
|
1885
2132
|
}
|
|
@@ -2240,6 +2487,27 @@ function not(value) {
|
|
|
2240
2487
|
return !Boolean(value);
|
|
2241
2488
|
}
|
|
2242
2489
|
|
|
2490
|
+
function omit(obj, keys) {
|
|
2491
|
+
const res = (Object.getPrototypeOf(obj) ? {} : Object.create(null));
|
|
2492
|
+
const ownKeys = Reflect.ownKeys(obj);
|
|
2493
|
+
if (isFunction(keys)) {
|
|
2494
|
+
for (let i = 0; i < ownKeys.length; i++) {
|
|
2495
|
+
const key = ownKeys[i];
|
|
2496
|
+
if (!keys(obj[key], key, obj))
|
|
2497
|
+
res[key] = obj[key];
|
|
2498
|
+
}
|
|
2499
|
+
}
|
|
2500
|
+
else {
|
|
2501
|
+
const keysSet = new Set((isArray(keys) ? keys : [keys]).map((k) => (isNumber(k) ? String(k) : k)));
|
|
2502
|
+
for (let i = 0; i < ownKeys.length; i++) {
|
|
2503
|
+
const key = ownKeys[i];
|
|
2504
|
+
if (!keysSet.has(key))
|
|
2505
|
+
res[key] = obj[key];
|
|
2506
|
+
}
|
|
2507
|
+
}
|
|
2508
|
+
return res;
|
|
2509
|
+
}
|
|
2510
|
+
|
|
2243
2511
|
function pass(value) {
|
|
2244
2512
|
return value;
|
|
2245
2513
|
}
|
|
@@ -2250,6 +2518,31 @@ function passWith(fn) {
|
|
|
2250
2518
|
});
|
|
2251
2519
|
}
|
|
2252
2520
|
|
|
2521
|
+
function pick(obj, keys) {
|
|
2522
|
+
const res = (Object.getPrototypeOf(obj) ? {} : Object.create(null));
|
|
2523
|
+
const ownKeys = Reflect.ownKeys(obj);
|
|
2524
|
+
if (isFunction(keys)) {
|
|
2525
|
+
for (let i = 0; i < ownKeys.length; i++) {
|
|
2526
|
+
const key = ownKeys[i];
|
|
2527
|
+
if (keys(obj[key], key, obj))
|
|
2528
|
+
res[key] = obj[key];
|
|
2529
|
+
}
|
|
2530
|
+
}
|
|
2531
|
+
else if (isArray(keys)) {
|
|
2532
|
+
const keysSet = new Set(ownKeys);
|
|
2533
|
+
for (let i = 0; i < keys.length; i++) {
|
|
2534
|
+
const key = keys[i];
|
|
2535
|
+
if (keysSet.has(isNumber(key) ? String(key) : key))
|
|
2536
|
+
res[key] = obj[key];
|
|
2537
|
+
}
|
|
2538
|
+
}
|
|
2539
|
+
else if (isString(keys) || isNumber(keys) || isSymbol(keys)) {
|
|
2540
|
+
if (ownKeys.includes(isNumber(keys) ? String(keys) : keys))
|
|
2541
|
+
res[keys] = obj[keys];
|
|
2542
|
+
}
|
|
2543
|
+
return res;
|
|
2544
|
+
}
|
|
2545
|
+
|
|
2253
2546
|
function pipe(...pipeFunc) {
|
|
2254
2547
|
if (pipeFunc.length === 0) {
|
|
2255
2548
|
throw new Error('Invalid pipeFunc parameter: pipeFunc is empty');
|
|
@@ -2275,4 +2568,4 @@ function throttle(fn, delay, options) {
|
|
|
2275
2568
|
return _throttle(fn, delay, Object.assign({ trailing: false, leading: true }, options));
|
|
2276
2569
|
}
|
|
2277
2570
|
|
|
2278
|
-
export { $$Empty, _, acceptableFileName, acceptableFileType, camelCase, capitalize, cartesianProduct, caseCamel, caseConvert, caseKebab, casePascal, caseSnake, chunk, clamp, compose, _curryMore as curry, debounce, decimalNotation, dedent, deepClone, deepMerge, defer, fastClone, format, getAcceptableExtByMIME, getAcceptableMIMEByExt, getGlobalThis, getTag, indent, isArray, isArrayBuffer, isArrayLike, isBigInt, isBigInt64Array, isBigUint64Array, isBlob, isBoolean, isBuffer, isDataView, isDate, isEmpty, isEven, isFile, isFloat32Array, isFloat64Array, isFormData, isFunction, isInt16Array, isInt32Array, isInt8Array, isInteger, isIterable, isMap, isMergeEmptyPlaceholder, isNil, isNull, isNumber, isObject, isOdd, isPlaceholder, isPlainObject, isPrimitive, isPromise, isPromiseLike, isRegExp, isSet, isString, isSymbol, isTypedArray, isUint16Array, isUint32Array, isUint8Array, isUint8ClampedArray, isUndefined, isWeakMap, isWeakSet, isWrapperBigInt, isWrapperBoolean, isWrapperNumber, isWrapperObject, isWrapperString, isWrapperSymbol, kebabCase, memo, noop, not, parallel, pascalCase, pass, passWith, pipe, randomBase32String, randomChoice, randomHexString, randomInt, randomIntFloor, randomString, range, remove, retry, round, roundBank, roundBase, roundCeil, roundFloor, shuffle, sleep, snakeCase, splitWords, throttle, titleCase, tryit, ulid, uncapitalize, uuidNil, uuidV4, withResolvers };
|
|
2571
|
+
export { $$Empty, _, acceptableFileName, acceptableFileType, camelCase, capitalize, cartesianProduct, caseCamel, caseConvert, caseKebab, casePascal, caseSnake, castArray, chunk, clamp, compose, _curryMore as curry, debounce, decimalNotation, dedent, deepClone, deepMerge, defer, fastClone, format, getAcceptableExtByMIME, getAcceptableMIMEByExt, getGlobalThis, getInitP, getTag, indent, isArray, isArrayBuffer, isArrayLike, isBigInt, isBigInt64Array, isBigUint64Array, isBlob, isBoolean, isBuffer, isDataView, isDate, isEmpty, isEven, isFile, isFloat32Array, isFloat64Array, isFormData, isFunction, isInt16Array, isInt32Array, isInt8Array, isInteger, isIterable, isMap, isMergeEmptyPlaceholder, isNil, isNull, isNumber, isObject, isOdd, isPlaceholder, isPlainObject, isPrimitive, isPromise, isPromiseLike, isRegExp, isSet, isString, isSymbol, isTypedArray, isUint16Array, isUint32Array, isUint8Array, isUint8ClampedArray, isUndefined, isWeakMap, isWeakSet, isWrapperBigInt, isWrapperBoolean, isWrapperNumber, isWrapperObject, isWrapperString, isWrapperSymbol, kebabCase, lerp, memo, noop, not, omit, parallel, pascalCase, pass, passWith, pick, pipe, randomBase32String, randomChoice, randomDistribution, randomHexString, randomInt, randomIntFloor, randomString, range, remove, retry, romanNumerals, round, roundBank, roundBase, roundCeil, roundFloor, scientificNotation, shuffle, sleep, snakeCase, splitWords, throttle, titleCase, tryit, ulid, uncapitalize, uuidNil, uuidV4, withResolvers };
|