foreslash 0.3.6 → 0.3.7

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 CHANGED
@@ -1,6 +1,16 @@
1
1
  # Change Log
2
2
 
3
- ## Version 0.3.6 - 2026-01-
3
+ ## Version 0.3.7 - 2026-01-24
4
+
5
+ Add a method to convert numbers to Chinese numerals
6
+
7
+ - Feat 🥥 Functions added: `chinaNumerals`
8
+
9
+ 添加了将数字转换为中文的方法
10
+
11
+ - 功能 🥥 添加函数: `chinaNumerals`
12
+
13
+ ## Version 0.3.6 - 2026-01-09
4
14
 
5
15
  Unstable version
6
16
 
package/lib/index.cmn.cjs CHANGED
@@ -424,23 +424,6 @@ function defer(asyncFunction, options) {
424
424
  });
425
425
  }
426
426
 
427
- function clamp(num, min, max, options) {
428
- var _a, _b;
429
- if (isNaN(min))
430
- throw new Error('Invalid min parameter');
431
- if (isNaN(max))
432
- throw new Error('Invalid max parameter');
433
- if (max < min) {
434
- [min, max] = [max, min];
435
- }
436
- const { default: def, defaultMin: _dMin, defaultMax: _dMax } = options || {};
437
- const defaultMin = (_a = _dMin !== null && _dMin !== void 0 ? _dMin : def) !== null && _a !== void 0 ? _a : min;
438
- const defaultMax = (_b = _dMax !== null && _dMax !== void 0 ? _dMax : def) !== null && _b !== void 0 ? _b : max;
439
- if (isNaN(num))
440
- return defaultMin;
441
- return num < min ? defaultMin : num > max ? defaultMax : num;
442
- }
443
-
444
427
  function decimalNotation(num) {
445
428
  const n = isNumber(num) ? num : Number(num);
446
429
  if (!isFinite(n))
@@ -467,6 +450,138 @@ function decimalNotation(num) {
467
450
  }
468
451
  }
469
452
 
453
+ function chinaNumerals(num, options) {
454
+ var _a, _b, _c;
455
+ const str = decimalNotation(num);
456
+ if (/NaN|Inf/.test(str))
457
+ return str;
458
+ const type = (options || {}).type || 'normal';
459
+ const numeralsType = (options || {}).numeralsType || 'normal';
460
+ const customNumerals = (options || {}).customNumerals;
461
+ const customUnits = Array.from((options || {}).customUnits || (type === 'upper' ? '拾佰仟万亿兆京垓秭穰沟涧正载' : '十百千万亿兆京垓秭穰沟涧正载'));
462
+ customUnits.unshift('');
463
+ if (type === 'custom' && (!customNumerals || customNumerals.length !== 10)) {
464
+ throw new Error('Invalid customNumerals: customNumerals must be provided and its length must be 10.');
465
+ }
466
+ const numberChar = Array.from(type === 'normal'
467
+ ? '零一二三四五六七八九'
468
+ : type === 'lower'
469
+ ? '〇一二三四五六七八九'
470
+ : type === 'upper'
471
+ ? '零壹贰叁肆伍陆柒捌玖'
472
+ : customNumerals);
473
+ const zeroChar = numberChar[0];
474
+ const zeroRegex = new RegExp(`${zeroChar}+`, 'g');
475
+ const trailingZeroRegex = new RegExp(`${zeroChar}$`);
476
+ const [integer, fractional] = str.split('.');
477
+ let integerPart = '';
478
+ if (numeralsType === 'minio') {
479
+ const chunks = chunk(Array.from(integer).reverse(), customUnits.length - 1);
480
+ const parts = [];
481
+ for (let i = 0; i < chunks.length; i++) {
482
+ const subChunk = chunks[i].reverse();
483
+ const chars = subChunk
484
+ .map((digit, index) => {
485
+ const num = Number(digit);
486
+ const unitIndex = subChunk.length - 1 - index;
487
+ if (num === 0)
488
+ return numberChar[num];
489
+ else
490
+ return numberChar[num] + customUnits[unitIndex];
491
+ })
492
+ .filter((part) => part !== '');
493
+ if (chars.length > 0) {
494
+ const stringified = chars.join('').replace(zeroRegex, zeroChar).replace(trailingZeroRegex, '');
495
+ const unitIndex = i * (customUnits.length - 1);
496
+ parts.unshift(stringified + (unitIndex > 0 ? customUnits[unitIndex] : ''));
497
+ }
498
+ }
499
+ const result = parts.join('').replace(zeroRegex, zeroChar).replace(trailingZeroRegex, '');
500
+ integerPart = result === '' ? numberChar[0] : result;
501
+ }
502
+ else {
503
+ const chunks = chunk(Array.from(integer).reverse(), 4);
504
+ const parts = [];
505
+ for (let i = 0; i < chunks.length; i++) {
506
+ const subChunk = chunks[i].reverse();
507
+ const chars = subChunk
508
+ .map((digit, index) => {
509
+ const num = Number(digit);
510
+ const unitIndex = subChunk.length - 1 - index;
511
+ if (num === 0)
512
+ return numberChar[num];
513
+ else
514
+ return numberChar[num] + customUnits[unitIndex];
515
+ })
516
+ .filter((part) => part !== '');
517
+ if (chars.length > 0) {
518
+ const stringified = chars.join('').replace(zeroRegex, zeroChar).replace(trailingZeroRegex, '');
519
+ let unitStr = '';
520
+ if (numeralsType === 'normal') {
521
+ unitStr = getNormalUnits(customUnits.slice(4), i);
522
+ }
523
+ else if (numeralsType === 'mega') {
524
+ unitStr = getMegaUnits(customUnits.slice(4), i);
525
+ }
526
+ if (stringified !== '')
527
+ parts.unshift(stringified + unitStr);
528
+ }
529
+ }
530
+ const result = parts.join('').replace(zeroRegex, zeroChar).replace(trailingZeroRegex, '');
531
+ integerPart = result === '' ? numberChar[0] : result;
532
+ }
533
+ return fractional
534
+ ? integerPart +
535
+ ((_a = options === null || options === void 0 ? void 0 : options.integerUnit) !== null && _a !== void 0 ? _a : '') +
536
+ ((_b = options === null || options === void 0 ? void 0 : options.dot) !== null && _b !== void 0 ? _b : '点') +
537
+ fractional
538
+ .split('')
539
+ .map((d, i) => { var _a, _b; return numberChar[Number(d)] + ((_b = (_a = options === null || options === void 0 ? void 0 : options.fractionalUnits) === null || _a === void 0 ? void 0 : _a[i]) !== null && _b !== void 0 ? _b : ''); })
540
+ .join('')
541
+ : integerPart + ((_c = options === null || options === void 0 ? void 0 : options.integerUnit) !== null && _c !== void 0 ? _c : '');
542
+ }
543
+ function getNormalUnits(units, index) {
544
+ if (index === 0)
545
+ return '';
546
+ if (index <= units.length)
547
+ return units[index - 1];
548
+ const majorCount = Math.floor(index / units.length);
549
+ const minorIndex = index % units.length;
550
+ return (minorIndex > 0 ? units[minorIndex - 1] : '') + units[units.length - 1].repeat(majorCount);
551
+ }
552
+ function getMegaUnits(units, index) {
553
+ if (index === 0)
554
+ return '';
555
+ if (index === 1)
556
+ return units[0];
557
+ const combinations = 2 ** (units.length - 1);
558
+ const majorCount = Math.floor(index / combinations);
559
+ let minorIndex = index % combinations;
560
+ let result = '';
561
+ for (let i = 0; i < units.length; i++) {
562
+ if ((minorIndex & (1 << i)) !== 0)
563
+ result += units[i];
564
+ }
565
+ return result + units[units.length - 1].repeat(majorCount);
566
+ }
567
+
568
+ function clamp(num, min, max, options) {
569
+ var _a, _b;
570
+ if (isNaN(min))
571
+ throw new Error('Invalid min parameter');
572
+ if (isNaN(max))
573
+ throw new Error('Invalid max parameter');
574
+ if (max < min) {
575
+ [min, max] = [max, min];
576
+ }
577
+ const { default: def, defaultMin: _dMin, defaultMax: _dMax } = options || {};
578
+ const defaultMin = (_a = _dMin !== null && _dMin !== void 0 ? _dMin : def) !== null && _a !== void 0 ? _a : min;
579
+ const defaultMax = (_b = _dMax !== null && _dMax !== void 0 ? _dMax : def) !== null && _b !== void 0 ? _b : max;
580
+ if (isNaN(num))
581
+ return defaultMin;
582
+ return num < min ? defaultMin : num > max ? defaultMax : num;
583
+ }
584
+
470
585
  function isOdd(num) {
471
586
  return !!(typeof num === 'bigint' ? num & BigInt(1) : num & 1);
472
587
  }
@@ -2652,6 +2767,7 @@ exports.caseKebab = caseKebab;
2652
2767
  exports.casePascal = casePascal;
2653
2768
  exports.caseSnake = caseSnake;
2654
2769
  exports.castArray = castArray;
2770
+ exports.chinaNumerals = chinaNumerals;
2655
2771
  exports.chunk = chunk;
2656
2772
  exports.clamp = clamp;
2657
2773
  exports.compose = compose;
package/lib/index.d.ts CHANGED
@@ -958,6 +958,60 @@ declare function isWrapperSymbol(value: unknown): value is Symbol;
958
958
  */
959
959
  declare function isWrapperBigInt(value: unknown): value is BigInt;
960
960
 
961
+ /**
962
+ * 将一个数字转换为汉语表达, 可以配置大写或小写, 默认使用小写(除了 0 默认使用 `零`)
963
+ * @param num 需要转换的数字
964
+ * @param options 格式化配置\
965
+ * `type` 类型, 默认为 `normal`
966
+ * - `'normal'` 习惯写法, 如 `2025` 会转换为 `二千零二十五`
967
+ * - `'lower'` 小写, 如 `2025` 会转换为 `二千〇二十五`
968
+ * - `'upper'` 大写, 如 `2025` 会转换为 `贰仟零贰拾伍`
969
+ * - `'custom'` 自定义, 允许传入自定义的数字和单位字符, 具体见下方 `customNumerals` 和 `customUnits`
970
+ *
971
+ * `numeralsType` 数字类型, 默认为 `normal`
972
+ * - `'normal'` 使用常规的中数表示法, 以万为单位, 万万为亿、万亿为兆、万兆为京
973
+ * - `'minio'` 古代的下数表示法, 十万为亿、十亿为兆、十兆为京
974
+ * - `'mega'` 古代的上数表示法, 万万为亿、亿亿为兆、兆兆为京
975
+ *
976
+ * `customNumerals` 自定义数字字符, 类型为 `ArrayLike<string>`\
977
+ * 分别用于表示 0-9 , 仅在 `type` 为 `'custom'` 时有效\
978
+ * 需要传入一个长度为 10 的字符串, 如 `'零壹贰叁肆伍陆柒捌玖'`\
979
+ * 如果传入的长度不为 10, 则会抛出一个错误
980
+ *
981
+ * `customUnits` 自定义单位字符, 类型为 `ArrayLike<string>`\
982
+ * 用于表示进位, 如 `'十百千万亿兆京垓秭穰沟涧正载'`\
983
+ * 前 3 个单位固定表示十(10)、百(100)、千(1000), 后续单位根据 `numeralsType` 进行调整, 仅在 `type` 为 `'custom'` 时有效
984
+ *
985
+ * `integerUnit` 自定义整数部分的单位字符, 类型为 `string`\
986
+ * 用于表示整数部分的单位, 如 `'元'`、`'块'` 等, 默认为空字符串 `''`\
987
+ * 该选项会在整数部分的数字后面添加指定的单位字符
988
+ *
989
+ * `dot` 小数点字符, 类型为 `string`\
990
+ * 用于表示小数点的字符, 默认为 `'点'`\
991
+ * 该选项会替换默认的小数点字符
992
+ *
993
+ * `fractionalUnits` 小数部分的单位字符数组, 类型为 `ArrayLike<string>`\
994
+ * 用于表示小数部分每一位的单位, 如 `['角', '分', '厘']` 等, 默认为空数组 `[]`\
995
+ * 该选项会在小数部分的每一位数字后面添加对应的单位字符, 如果小数部分的位数超过了该数组的长度, 则超出部分不添加单位字符
996
+ * @returns 返回一个汉语表达的数字
997
+ * @example
998
+ * ```js
999
+ * chinaNumerals(2025) // 二千零二十五
1000
+ * chinaNumerals(2025, { type: 'upper' }) // 贰仟零贰拾伍
1001
+ * chinaNumerals(1002003, { type: 'lower' }) // 一百万二千〇三
1002
+ * ```
1003
+ * @version 0.3.7
1004
+ */
1005
+ declare function chinaNumerals(num: string | number, options?: {
1006
+ type?: 'normal' | 'lower' | 'upper' | 'custom';
1007
+ numeralsType?: 'normal' | 'minio' | 'mega';
1008
+ customNumerals?: ArrayLike<string>;
1009
+ customUnits?: ArrayLike<string>;
1010
+ integerUnit?: string;
1011
+ dot?: string;
1012
+ fractionalUnits?: ArrayLike<string>;
1013
+ }): string;
1014
+
961
1015
  /**
962
1016
  * 将一个数字限制在指定范围内
963
1017
  * @param num 初始值
@@ -2569,5 +2623,5 @@ declare function throttle<T extends any[]>(fn: (...args: T) => any, delay: numbe
2569
2623
  reset: () => void;
2570
2624
  };
2571
2625
 
2572
- export { $$Empty, _, acceptableFileName, acceptableFileType, base64ToBlob, blobToBase64, camelCase, capitalize, cartesianProduct, caseCamel, caseConvert, caseKebab, casePascal, caseSnake, castArray, chunk, clamp, compose, _curryMore as curry, dataUrlToBlob, debounce, decimalNotation, decodeBase64, dedent, deepClone, deepMerge, defer, deprecate, encodeBase64, 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, uuidV7, withResolvers };
2626
+ export { $$Empty, _, acceptableFileName, acceptableFileType, base64ToBlob, blobToBase64, camelCase, capitalize, cartesianProduct, caseCamel, caseConvert, caseKebab, casePascal, caseSnake, castArray, chinaNumerals, chunk, clamp, compose, _curryMore as curry, dataUrlToBlob, debounce, decimalNotation, decodeBase64, dedent, deepClone, deepMerge, defer, deprecate, encodeBase64, 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, uuidV7, withResolvers };
2573
2627
  export type { BaseMargeType, CastArray, Chunked, CloneOptions, CustomCloner, IsNegative, IsPositive, IsZero, MergeOption, MergeStrategy, MergeStrategyFunction, MergeType, MergeTypeStrategy, Not, RangeOptions, SourceMergeType, Stringify, TargetMergeType, TypedArray };
package/lib/index.mjs CHANGED
@@ -422,23 +422,6 @@ function defer(asyncFunction, options) {
422
422
  });
423
423
  }
424
424
 
425
- function clamp(num, min, max, options) {
426
- var _a, _b;
427
- if (isNaN(min))
428
- throw new Error('Invalid min parameter');
429
- if (isNaN(max))
430
- throw new Error('Invalid max parameter');
431
- if (max < min) {
432
- [min, max] = [max, min];
433
- }
434
- const { default: def, defaultMin: _dMin, defaultMax: _dMax } = options || {};
435
- const defaultMin = (_a = _dMin !== null && _dMin !== void 0 ? _dMin : def) !== null && _a !== void 0 ? _a : min;
436
- const defaultMax = (_b = _dMax !== null && _dMax !== void 0 ? _dMax : def) !== null && _b !== void 0 ? _b : max;
437
- if (isNaN(num))
438
- return defaultMin;
439
- return num < min ? defaultMin : num > max ? defaultMax : num;
440
- }
441
-
442
425
  function decimalNotation(num) {
443
426
  const n = isNumber(num) ? num : Number(num);
444
427
  if (!isFinite(n))
@@ -465,6 +448,138 @@ function decimalNotation(num) {
465
448
  }
466
449
  }
467
450
 
451
+ function chinaNumerals(num, options) {
452
+ var _a, _b, _c;
453
+ const str = decimalNotation(num);
454
+ if (/NaN|Inf/.test(str))
455
+ return str;
456
+ const type = (options || {}).type || 'normal';
457
+ const numeralsType = (options || {}).numeralsType || 'normal';
458
+ const customNumerals = (options || {}).customNumerals;
459
+ const customUnits = Array.from((options || {}).customUnits || (type === 'upper' ? '拾佰仟万亿兆京垓秭穰沟涧正载' : '十百千万亿兆京垓秭穰沟涧正载'));
460
+ customUnits.unshift('');
461
+ if (type === 'custom' && (!customNumerals || customNumerals.length !== 10)) {
462
+ throw new Error('Invalid customNumerals: customNumerals must be provided and its length must be 10.');
463
+ }
464
+ const numberChar = Array.from(type === 'normal'
465
+ ? '零一二三四五六七八九'
466
+ : type === 'lower'
467
+ ? '〇一二三四五六七八九'
468
+ : type === 'upper'
469
+ ? '零壹贰叁肆伍陆柒捌玖'
470
+ : customNumerals);
471
+ const zeroChar = numberChar[0];
472
+ const zeroRegex = new RegExp(`${zeroChar}+`, 'g');
473
+ const trailingZeroRegex = new RegExp(`${zeroChar}$`);
474
+ const [integer, fractional] = str.split('.');
475
+ let integerPart = '';
476
+ if (numeralsType === 'minio') {
477
+ const chunks = chunk(Array.from(integer).reverse(), customUnits.length - 1);
478
+ const parts = [];
479
+ for (let i = 0; i < chunks.length; i++) {
480
+ const subChunk = chunks[i].reverse();
481
+ const chars = subChunk
482
+ .map((digit, index) => {
483
+ const num = Number(digit);
484
+ const unitIndex = subChunk.length - 1 - index;
485
+ if (num === 0)
486
+ return numberChar[num];
487
+ else
488
+ return numberChar[num] + customUnits[unitIndex];
489
+ })
490
+ .filter((part) => part !== '');
491
+ if (chars.length > 0) {
492
+ const stringified = chars.join('').replace(zeroRegex, zeroChar).replace(trailingZeroRegex, '');
493
+ const unitIndex = i * (customUnits.length - 1);
494
+ parts.unshift(stringified + (unitIndex > 0 ? customUnits[unitIndex] : ''));
495
+ }
496
+ }
497
+ const result = parts.join('').replace(zeroRegex, zeroChar).replace(trailingZeroRegex, '');
498
+ integerPart = result === '' ? numberChar[0] : result;
499
+ }
500
+ else {
501
+ const chunks = chunk(Array.from(integer).reverse(), 4);
502
+ const parts = [];
503
+ for (let i = 0; i < chunks.length; i++) {
504
+ const subChunk = chunks[i].reverse();
505
+ const chars = subChunk
506
+ .map((digit, index) => {
507
+ const num = Number(digit);
508
+ const unitIndex = subChunk.length - 1 - index;
509
+ if (num === 0)
510
+ return numberChar[num];
511
+ else
512
+ return numberChar[num] + customUnits[unitIndex];
513
+ })
514
+ .filter((part) => part !== '');
515
+ if (chars.length > 0) {
516
+ const stringified = chars.join('').replace(zeroRegex, zeroChar).replace(trailingZeroRegex, '');
517
+ let unitStr = '';
518
+ if (numeralsType === 'normal') {
519
+ unitStr = getNormalUnits(customUnits.slice(4), i);
520
+ }
521
+ else if (numeralsType === 'mega') {
522
+ unitStr = getMegaUnits(customUnits.slice(4), i);
523
+ }
524
+ if (stringified !== '')
525
+ parts.unshift(stringified + unitStr);
526
+ }
527
+ }
528
+ const result = parts.join('').replace(zeroRegex, zeroChar).replace(trailingZeroRegex, '');
529
+ integerPart = result === '' ? numberChar[0] : result;
530
+ }
531
+ return fractional
532
+ ? integerPart +
533
+ ((_a = options === null || options === void 0 ? void 0 : options.integerUnit) !== null && _a !== void 0 ? _a : '') +
534
+ ((_b = options === null || options === void 0 ? void 0 : options.dot) !== null && _b !== void 0 ? _b : '点') +
535
+ fractional
536
+ .split('')
537
+ .map((d, i) => { var _a, _b; return numberChar[Number(d)] + ((_b = (_a = options === null || options === void 0 ? void 0 : options.fractionalUnits) === null || _a === void 0 ? void 0 : _a[i]) !== null && _b !== void 0 ? _b : ''); })
538
+ .join('')
539
+ : integerPart + ((_c = options === null || options === void 0 ? void 0 : options.integerUnit) !== null && _c !== void 0 ? _c : '');
540
+ }
541
+ function getNormalUnits(units, index) {
542
+ if (index === 0)
543
+ return '';
544
+ if (index <= units.length)
545
+ return units[index - 1];
546
+ const majorCount = Math.floor(index / units.length);
547
+ const minorIndex = index % units.length;
548
+ return (minorIndex > 0 ? units[minorIndex - 1] : '') + units[units.length - 1].repeat(majorCount);
549
+ }
550
+ function getMegaUnits(units, index) {
551
+ if (index === 0)
552
+ return '';
553
+ if (index === 1)
554
+ return units[0];
555
+ const combinations = 2 ** (units.length - 1);
556
+ const majorCount = Math.floor(index / combinations);
557
+ let minorIndex = index % combinations;
558
+ let result = '';
559
+ for (let i = 0; i < units.length; i++) {
560
+ if ((minorIndex & (1 << i)) !== 0)
561
+ result += units[i];
562
+ }
563
+ return result + units[units.length - 1].repeat(majorCount);
564
+ }
565
+
566
+ function clamp(num, min, max, options) {
567
+ var _a, _b;
568
+ if (isNaN(min))
569
+ throw new Error('Invalid min parameter');
570
+ if (isNaN(max))
571
+ throw new Error('Invalid max parameter');
572
+ if (max < min) {
573
+ [min, max] = [max, min];
574
+ }
575
+ const { default: def, defaultMin: _dMin, defaultMax: _dMax } = options || {};
576
+ const defaultMin = (_a = _dMin !== null && _dMin !== void 0 ? _dMin : def) !== null && _a !== void 0 ? _a : min;
577
+ const defaultMax = (_b = _dMax !== null && _dMax !== void 0 ? _dMax : def) !== null && _b !== void 0 ? _b : max;
578
+ if (isNaN(num))
579
+ return defaultMin;
580
+ return num < min ? defaultMin : num > max ? defaultMax : num;
581
+ }
582
+
468
583
  function isOdd(num) {
469
584
  return !!(typeof num === 'bigint' ? num & BigInt(1) : num & 1);
470
585
  }
@@ -2635,4 +2750,4 @@ function throttle(fn, delay, options) {
2635
2750
  return _throttle(fn, delay, Object.assign({ trailing: false, leading: true }, options));
2636
2751
  }
2637
2752
 
2638
- export { $$Empty, _, acceptableFileName, acceptableFileType, base64ToBlob, blobToBase64, camelCase, capitalize, cartesianProduct, caseCamel, caseConvert, caseKebab, casePascal, caseSnake, castArray, chunk, clamp, compose, _curryMore as curry, dataUrlToBlob, debounce, decimalNotation, decodeBase64, dedent, deepClone, deepMerge, defer, deprecate, encodeBase64, 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, uuidV7, withResolvers };
2753
+ export { $$Empty, _, acceptableFileName, acceptableFileType, base64ToBlob, blobToBase64, camelCase, capitalize, cartesianProduct, caseCamel, caseConvert, caseKebab, casePascal, caseSnake, castArray, chinaNumerals, chunk, clamp, compose, _curryMore as curry, dataUrlToBlob, debounce, decimalNotation, decodeBase64, dedent, deepClone, deepMerge, defer, deprecate, encodeBase64, 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, uuidV7, withResolvers };
package/lib/index.umd.js CHANGED
@@ -428,23 +428,6 @@ See the Mulan PSL v2 for more details.
428
428
  });
429
429
  }
430
430
 
431
- function clamp(num, min, max, options) {
432
- var _a, _b;
433
- if (isNaN(min))
434
- throw new Error('Invalid min parameter');
435
- if (isNaN(max))
436
- throw new Error('Invalid max parameter');
437
- if (max < min) {
438
- [min, max] = [max, min];
439
- }
440
- const { default: def, defaultMin: _dMin, defaultMax: _dMax } = options || {};
441
- const defaultMin = (_a = _dMin !== null && _dMin !== void 0 ? _dMin : def) !== null && _a !== void 0 ? _a : min;
442
- const defaultMax = (_b = _dMax !== null && _dMax !== void 0 ? _dMax : def) !== null && _b !== void 0 ? _b : max;
443
- if (isNaN(num))
444
- return defaultMin;
445
- return num < min ? defaultMin : num > max ? defaultMax : num;
446
- }
447
-
448
431
  function decimalNotation(num) {
449
432
  const n = isNumber(num) ? num : Number(num);
450
433
  if (!isFinite(n))
@@ -471,6 +454,138 @@ See the Mulan PSL v2 for more details.
471
454
  }
472
455
  }
473
456
 
457
+ function chinaNumerals(num, options) {
458
+ var _a, _b, _c;
459
+ const str = decimalNotation(num);
460
+ if (/NaN|Inf/.test(str))
461
+ return str;
462
+ const type = (options || {}).type || 'normal';
463
+ const numeralsType = (options || {}).numeralsType || 'normal';
464
+ const customNumerals = (options || {}).customNumerals;
465
+ const customUnits = Array.from((options || {}).customUnits || (type === 'upper' ? '拾佰仟万亿兆京垓秭穰沟涧正载' : '十百千万亿兆京垓秭穰沟涧正载'));
466
+ customUnits.unshift('');
467
+ if (type === 'custom' && (!customNumerals || customNumerals.length !== 10)) {
468
+ throw new Error('Invalid customNumerals: customNumerals must be provided and its length must be 10.');
469
+ }
470
+ const numberChar = Array.from(type === 'normal'
471
+ ? '零一二三四五六七八九'
472
+ : type === 'lower'
473
+ ? '〇一二三四五六七八九'
474
+ : type === 'upper'
475
+ ? '零壹贰叁肆伍陆柒捌玖'
476
+ : customNumerals);
477
+ const zeroChar = numberChar[0];
478
+ const zeroRegex = new RegExp(`${zeroChar}+`, 'g');
479
+ const trailingZeroRegex = new RegExp(`${zeroChar}$`);
480
+ const [integer, fractional] = str.split('.');
481
+ let integerPart = '';
482
+ if (numeralsType === 'minio') {
483
+ const chunks = chunk(Array.from(integer).reverse(), customUnits.length - 1);
484
+ const parts = [];
485
+ for (let i = 0; i < chunks.length; i++) {
486
+ const subChunk = chunks[i].reverse();
487
+ const chars = subChunk
488
+ .map((digit, index) => {
489
+ const num = Number(digit);
490
+ const unitIndex = subChunk.length - 1 - index;
491
+ if (num === 0)
492
+ return numberChar[num];
493
+ else
494
+ return numberChar[num] + customUnits[unitIndex];
495
+ })
496
+ .filter((part) => part !== '');
497
+ if (chars.length > 0) {
498
+ const stringified = chars.join('').replace(zeroRegex, zeroChar).replace(trailingZeroRegex, '');
499
+ const unitIndex = i * (customUnits.length - 1);
500
+ parts.unshift(stringified + (unitIndex > 0 ? customUnits[unitIndex] : ''));
501
+ }
502
+ }
503
+ const result = parts.join('').replace(zeroRegex, zeroChar).replace(trailingZeroRegex, '');
504
+ integerPart = result === '' ? numberChar[0] : result;
505
+ }
506
+ else {
507
+ const chunks = chunk(Array.from(integer).reverse(), 4);
508
+ const parts = [];
509
+ for (let i = 0; i < chunks.length; i++) {
510
+ const subChunk = chunks[i].reverse();
511
+ const chars = subChunk
512
+ .map((digit, index) => {
513
+ const num = Number(digit);
514
+ const unitIndex = subChunk.length - 1 - index;
515
+ if (num === 0)
516
+ return numberChar[num];
517
+ else
518
+ return numberChar[num] + customUnits[unitIndex];
519
+ })
520
+ .filter((part) => part !== '');
521
+ if (chars.length > 0) {
522
+ const stringified = chars.join('').replace(zeroRegex, zeroChar).replace(trailingZeroRegex, '');
523
+ let unitStr = '';
524
+ if (numeralsType === 'normal') {
525
+ unitStr = getNormalUnits(customUnits.slice(4), i);
526
+ }
527
+ else if (numeralsType === 'mega') {
528
+ unitStr = getMegaUnits(customUnits.slice(4), i);
529
+ }
530
+ if (stringified !== '')
531
+ parts.unshift(stringified + unitStr);
532
+ }
533
+ }
534
+ const result = parts.join('').replace(zeroRegex, zeroChar).replace(trailingZeroRegex, '');
535
+ integerPart = result === '' ? numberChar[0] : result;
536
+ }
537
+ return fractional
538
+ ? integerPart +
539
+ ((_a = options === null || options === void 0 ? void 0 : options.integerUnit) !== null && _a !== void 0 ? _a : '') +
540
+ ((_b = options === null || options === void 0 ? void 0 : options.dot) !== null && _b !== void 0 ? _b : '点') +
541
+ fractional
542
+ .split('')
543
+ .map((d, i) => { var _a, _b; return numberChar[Number(d)] + ((_b = (_a = options === null || options === void 0 ? void 0 : options.fractionalUnits) === null || _a === void 0 ? void 0 : _a[i]) !== null && _b !== void 0 ? _b : ''); })
544
+ .join('')
545
+ : integerPart + ((_c = options === null || options === void 0 ? void 0 : options.integerUnit) !== null && _c !== void 0 ? _c : '');
546
+ }
547
+ function getNormalUnits(units, index) {
548
+ if (index === 0)
549
+ return '';
550
+ if (index <= units.length)
551
+ return units[index - 1];
552
+ const majorCount = Math.floor(index / units.length);
553
+ const minorIndex = index % units.length;
554
+ return (minorIndex > 0 ? units[minorIndex - 1] : '') + units[units.length - 1].repeat(majorCount);
555
+ }
556
+ function getMegaUnits(units, index) {
557
+ if (index === 0)
558
+ return '';
559
+ if (index === 1)
560
+ return units[0];
561
+ const combinations = 2 ** (units.length - 1);
562
+ const majorCount = Math.floor(index / combinations);
563
+ let minorIndex = index % combinations;
564
+ let result = '';
565
+ for (let i = 0; i < units.length; i++) {
566
+ if ((minorIndex & (1 << i)) !== 0)
567
+ result += units[i];
568
+ }
569
+ return result + units[units.length - 1].repeat(majorCount);
570
+ }
571
+
572
+ function clamp(num, min, max, options) {
573
+ var _a, _b;
574
+ if (isNaN(min))
575
+ throw new Error('Invalid min parameter');
576
+ if (isNaN(max))
577
+ throw new Error('Invalid max parameter');
578
+ if (max < min) {
579
+ [min, max] = [max, min];
580
+ }
581
+ const { default: def, defaultMin: _dMin, defaultMax: _dMax } = options || {};
582
+ const defaultMin = (_a = _dMin !== null && _dMin !== void 0 ? _dMin : def) !== null && _a !== void 0 ? _a : min;
583
+ const defaultMax = (_b = _dMax !== null && _dMax !== void 0 ? _dMax : def) !== null && _b !== void 0 ? _b : max;
584
+ if (isNaN(num))
585
+ return defaultMin;
586
+ return num < min ? defaultMin : num > max ? defaultMax : num;
587
+ }
588
+
474
589
  function isOdd(num) {
475
590
  return !!(typeof num === 'bigint' ? num & BigInt(1) : num & 1);
476
591
  }
@@ -2656,6 +2771,7 @@ See the Mulan PSL v2 for more details.
2656
2771
  exports.casePascal = casePascal;
2657
2772
  exports.caseSnake = caseSnake;
2658
2773
  exports.castArray = castArray;
2774
+ exports.chinaNumerals = chinaNumerals;
2659
2775
  exports.chunk = chunk;
2660
2776
  exports.clamp = clamp;
2661
2777
  exports.compose = compose;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "foreslash",
3
- "version": "0.3.6",
3
+ "version": "0.3.7",
4
4
  "description": "Foreslash is a Javascript utilities lib which contains plenty of practical functions.",
5
5
  "author": "moushu",
6
6
  "license": "Mulan PSL v2",