n2words
Version:
Convert numbers to words in 70+ languages with zero dependencies. Supports BigInt, decimals, and browser/Node.js environments.
3 lines (2 loc) • 6.22 kB
JavaScript
/*! n2words/zh-Hant-TW v5.1.2 | MIT License | github.com/forzagreen/n2words */
var n,e;n=this,e=function(n){"use strict";function e(n){let[e,t]=n.toLowerCase().split("e");const r=parseInt(t,10);let i="";"-"===e[0]&&(i="-",e=e.slice(1));const o=e.indexOf("."),s=-1===o?e:e.slice(0,o)+e.slice(o+1),u=(-1===o?e.length:o)+r;return u>=s.length?i+s+"0".repeat(u-s.length):u<=0?i+"0."+"0".repeat(-u)+s:i+s.slice(0,u)+"."+s.slice(u)}function t(n){const t=n.toString();return r(t)?e(t):t}function r(n){return n.includes("e")||n.includes("E")}function i(n){const e="-"===n[0];e&&(n=n.slice(1));const t=n.indexOf(".");if(-1===t)return{isNegative:e,integerPart:BigInt(n)};const r=n.slice(0,t)||"0",i=n.slice(t+1);return{isNegative:e,integerPart:BigInt(r),decimalPart:i}}function o(n){let t=n.trim();if(0===t.length||Number.isNaN(Number(t)))throw new RangeError(`Invalid currency format: "${n}"`);r(t)&&(t=e(t));const i="-"===t[0];i&&(t=t.slice(1));const o=t.indexOf(".");if(-1===o)return{isNegative:i,dollars:BigInt(t),cents:0n};const s=t.slice(0,o)||"0",u=(t.slice(o+1)+"00").slice(0,2);return{isNegative:i,dollars:BigInt(s),cents:BigInt(u)}}function s(n,e,t){if(null===e)return;if(n<e)return;const r=e.toString().length-1,i=e===10n**BigInt(r)?`10^${r} - 1`:""+(e-1n);throw new RangeError(`Number too large to convert: the largest supported value is ${i}`)}function u(n){return 10n**BigInt(n)}function c(n,e,t){const r={...e};if(void 0===n)return r;if(!function(n){if(null===n||"object"!=typeof n)return!1;const e=Object.getPrototypeOf(n);return null===e||e===Object.prototype}(n))throw new TypeError("Invalid options: expected plain object or undefined, got "+typeof n);const i=Object.keys(e);for(const[t,o]of Object.entries(n)){if(!Object.hasOwn(e,t))throw new TypeError(`Unknown option "${t}" — expected one of: ${i.join(", ")}`);if(void 0!==o){if(typeof o!=typeof r[t])throw new TypeError(`Option "${t}" must be a ${typeof r[t]}, got ${typeof o}`);r[t]=o}}return r}const f=["零","一","二","三","四","五","六","七","八","九"],a=["零","壹","貳","參","肆","伍","陸","柒","捌","玖"],l=u(16),g=u(16),p=u(16),d="零";function b(n,e=!0){if(0n===n)return d;const t=e?a:f,r=e?"拾":"十",i=e?"佰":"百",o=e?"仟":"千";function s(n){if(0n===n)return"";const e=[];let s=!1;const u=n/1000n,c=n%1000n;u>0n&&(e.push(t[Number(u)]+o),s=c>0n&&c<100n);const f=c/100n,a=c%100n;f>0n?(s&&e.push(d),e.push(t[Number(f)]+i),s=a>0n&&a<10n):u>0n&&a>0n&&(s=!0);const l=a/10n,g=a%10n;return l>0n?(s&&(e.push(d),s=!1),e.push(t[Number(l)]+r)):(f>0n||u>0n)&&g>0n&&(s=!0),g>0n&&(s&&e.push(d),e.push(t[Number(g)])),e.join("")}function u(n){if(0n===n)return"";const e=[];if(n>=10000n){const t=n/10000n,r=n%10000n;e.push(s(t)+"萬"),r>0n&&((t%10n==0n||r<1000n)&&e.push(d),e.push(s(r)))}else e.push(s(n));return e.join("")}const c=[];if(n>=100000000n){const e=n%100000000n,t=u(n/100000000n);c.push(t+"億"),e>0n&&(e<10000000n&&c.push(d),c.push(u(e)))}else c.push(u(n));return c.join("")}const m={formal:!0},h={formal:!0},w={formal:!0},y={zhHantTW:function(n,t){const i=function(n){const t=typeof n;if("bigint"==typeof n){if(n<=0n)throw new RangeError("Ordinals must be positive integers");return n}if("number"==typeof n){if(!Number.isFinite(n))throw new RangeError("Ordinals must be finite numbers");if(!Number.isInteger(n))throw new RangeError("Ordinals must be whole numbers");if(n<=0)throw new RangeError("Ordinals must be positive integers");return BigInt(n)}if("string"==typeof n)return function(n){const t=n.trim();if(0===t.length)throw new RangeError("Ordinals cannot be empty strings");if("-"===t[0])throw new RangeError("Ordinals cannot be negative");if(t.includes("."))throw new RangeError("Ordinals must be whole numbers");if(r(t)){const n=e(t);if(n.includes("."))throw new RangeError("Ordinals must be whole numbers");const r=BigInt(n);if(r<=0n)throw new RangeError("Ordinals must be positive integers");return r}try{const n=BigInt(t);if(n<=0n)throw new RangeError("Ordinals must be positive integers");return n}catch(e){if(e instanceof RangeError)throw e;throw new RangeError(`Invalid ordinal format: "${n}"`,{cause:e})}}(n);throw new TypeError(`Invalid value type: expected number, string, or bigint, received ${t}`)}(n);s(i,g);const{formal:o}=c(t,h);return function(n,e=!0){return"第"+b(n,e)}(i,o)}};n.currency={zhHantTW:function(n,e){const{isNegative:r,dollars:i,cents:u}=function(n){const e=typeof n;if("bigint"==typeof n)return n<0n?{isNegative:!0,dollars:-n,cents:0n}:{isNegative:!1,dollars:n,cents:0n};if("number"==typeof n){if(!Number.isFinite(n))throw new RangeError("Currency must be a finite number");return Number.isSafeInteger(n)?n<0?{isNegative:!0,dollars:BigInt(-n),cents:0n}:{isNegative:!1,dollars:BigInt(n),cents:0n}:o(t(n))}if("string"==typeof n)return o(n);throw new TypeError(`Invalid value type: expected number, string, or bigint, received ${e}`)}(n);s(i,p);const{formal:l}=c(e,w),g=l?"圓":"元",m=u/10n,h=u%10n;let y="";return r&&(y="負"),(i>0n||0n===u)&&(y+=b(i,l),y+=g),m>0n&&(y+=(l?a:f)[Number(m)]+"角"),h>0n?(i>0n&&0n===m&&(y+=d),y+=(l?a:f)[Number(h)]+"分"):y+="整",y}},n.ordinal=y,n.zhHantTW=function(n,o){const{isNegative:u,integerPart:g,decimalPart:p}=function(n){const o=typeof n;if("bigint"==typeof n)return n<0n?{isNegative:!0,integerPart:-n}:{isNegative:!1,integerPart:n};if("number"==typeof n){if(!Number.isFinite(n))throw new RangeError("Number must be finite (NaN and Infinity are not supported)");return Number.isSafeInteger(n)?n<0?{isNegative:!0,integerPart:BigInt(-n)}:{isNegative:!1,integerPart:BigInt(n)}:i(t(n))}if("string"==typeof n)return i(function(n){const t=n.trim();if(0===t.length||Number.isNaN(Number(t)))throw new RangeError(`Invalid number format: "${n}"`);return r(t)?e(t):t}(n));throw new TypeError(`Invalid value type: expected number, string, or bigint, received ${o}`)}(n);s(g,l);const{formal:d}=c(o,m);let h="";return u&&(h="負"),h+=b(g,d),p&&(h+="點"+function(n,e=!0){const t=e?a:f,r=[];for(const e of n)r.push(t[Number(e)]);return r}(p,d).join("")),h}},"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((n="undefined"!=typeof globalThis?globalThis:n||self).n2words=n.n2words||{});