UNPKG

to-words

Version:

Convert numbers to words in 132 locales with currency, ordinal, and BigInt support (TypeScript, ESM/CJS/UMD).

1 lines 19.8 kB
"use strict";var ToWords=(()=>{const e={localeCode:`en-IN`,converterOptions:{currency:!1,ignoreDecimal:!1,ignoreZeroCurrency:!1,doNotAddOnly:!1,includeZeroFractional:!1}},t=new WeakMap,n=0n,r=1n,i=11n,a=100n,o=BigInt(2**53-1);var s=class{options={};locale=void 0;localeClass=void 0;formalLocale=void 0;constructor(t={}){this.options=Object.assign({},e,t)}resolveGenderedValue(e,t,n){return t===`feminine`&&e.feminineValue?e.feminineValue:t===`masculine`&&e.masculineValue?e.masculineValue:n&&Array.isArray(e.value)?e.value[1]:e.resolvedValue}resolveLocale(e){let t=this.getLocale();if(!e)return t;let n=t.config.formalConfig;return n?(this.formalLocale||=this.createFormalLocale(t,n),this.formalLocale):t}createFormalLocale(e,t){let n={...e.config};return t.numberWordsMapping&&(n.numberWordsMapping=t.numberWordsMapping),t.exactWordsMapping&&(n.exactWordsMapping=t.exactWordsMapping),t.ordinalWordsMapping&&(n.ordinalWordsMapping=t.ordinalWordsMapping),t.ordinalExactWordsMapping&&(n.ordinalExactWordsMapping=t.ordinalExactWordsMapping),t.currency&&(n.currency=t.currency),t.ignoreOneForWords&&(n.ignoreOneForWords=t.ignoreOneForWords),n.formalConfig=void 0,{config:n}}setLocale(e){return this.localeClass=e,this.locale=void 0,this}getLocaleClass(){if(this.localeClass)return this.localeClass;throw Error(`No locale set. Use setLocale() or import from a locale-specific entry point (e.g., "to-words/en-IN")`)}getLocale(){if(this.locale===void 0){let e=this.getLocaleClass();this.locale=new e,this.initLocaleCache(this.locale)}return this.locale}initLocaleCache(e){let r=e.config,i=r.numberWordsMapping.map(e=>({...e,numberBigInt:BigInt(e.number),resolvedValue:Array.isArray(e.value)?e.value[0]:e.value})),o=new Map;if(r.exactWordsMapping)for(let e of r.exactWordsMapping){let t={...e,numberBigInt:BigInt(e.number),resolvedValue:Array.isArray(e.value)?e.value[0]:e.value};o.set(t.numberBigInt,t)}let s=new Map,c=n;for(let e of i)e.numberBigInt<=a&&(s.set(e.numberBigInt,e),e.numberBigInt>c&&(c=e.numberBigInt));let l=i.filter(e=>e.numberBigInt>=a),u=new Set(r.pluralWords??[]),d=new Set(r.pluralWordsOnlyWhenTrailing??[]),f=new Set(r.ignoreOneForWords??[]),p=new Set(r.noSplitWordAfter??[]);t.set(e,{numberWordsMappingBigInt:i,exactWordsMap:o,smallNumbersMap:s,unitMappings:l,smallNumbersBoundary:c,pluralWordsSet:u,pluralWordsOnlyWhenTrailingSet:d,ignoreOneForWordsSet:f,noSplitWordAfterSet:p})}getLocaleCache(e){let n=t.get(e);return n||=(this.initLocaleCache(e),t.get(e)),n}convert(e,t={}){let n=this.options.converterOptions,r=Object.keys(t).length===0?n??{}:{currency:t.currency??n?.currency??!1,ignoreDecimal:t.ignoreDecimal??n?.ignoreDecimal??!1,ignoreZeroCurrency:t.ignoreZeroCurrency??n?.ignoreZeroCurrency??!1,doNotAddOnly:t.doNotAddOnly??n?.doNotAddOnly??!1,includeZeroFractional:t.includeZeroFractional??n?.includeZeroFractional??!1,currencyOptions:t.currencyOptions??n?.currencyOptions,gender:t.gender??n?.gender,useAnd:t.useAnd??n?.useAnd,formal:t.formal??n?.formal,decimalStyle:t.decimalStyle??n?.decimalStyle};if(!this.isValidNumber(e))throw Error(`Invalid Number "${String(e)}"`);let i=typeof e==`bigint`,a=i?e:Number(e);r.ignoreDecimal&&!i&&(a=Math.trunc(a));let o=!!r.includeZeroFractional&&!i&&!r.ignoreDecimal&&typeof e==`string`&&/\.\d+$/.test(e)&&Number(e.split(`.`)[1])===0,s=[],c=this.resolveLocale(r.formal);return s=r.currency?this.convertCurrency(a,r,o,c):this.convertNumber(a,r,c),c.config.trim?s.join(``):s.join(` `)}toOrdinal(e,t={}){if(!this.isValidNumber(e))throw Error(`Invalid Number "${String(e)}"`);let n=this.resolveLocale(t.formal),r=n.config,i=Number(e);if(!Number.isInteger(i)||i<0)throw Error(`Ordinal numbers must be non-negative integers, got "${e}"`);if(!r.ordinalWordsMapping&&!r.ordinalSuffix&&!r.ordinalPrefix&&!r.ordinalExactWordsMapping)throw Error(`Ordinal conversion not supported for locale "${this.options.localeCode}"`);let a=this.convertOrdinal(i,t,n);return r.trim?a.join(``):a.join(` `)}convertOrdinal(e,t,n){let r=n.config;if(r.ordinalExactWordsMapping){let t=r.ordinalExactWordsMapping.find(t=>t.number===e);if(t)return[t.value]}if(e<=20&&r.ordinalWordsMapping){let t=r.ordinalWordsMapping.find(t=>t.number===e);if(t)return[t.value]}let i=this.convertInternal(BigInt(e),!0,void 0,n),a=i.length-1,o=i[a],s=this.getLastNumberComponent(e,r,n),c=!1;if(r.ordinalWordsMapping){let e=r.ordinalWordsMapping.find(e=>e.number===s);e&&(i[a]=e.value,c=!0)}return!c&&r.ordinalSuffix&&(i[a]=o+r.ordinalSuffix,c=!0),!c&&r.ordinalPrefix&&i.unshift(r.ordinalPrefix),i}getLastNumberComponent(e,t,n){if(e<=20)return e;let r=n?this.getLocaleCache(n).unitMappings:t.numberWordsMapping.filter(e=>Number(e.number)>=100).sort((e,t)=>Number(t.number)-Number(e.number));for(let t of r){let n=Number(t.number);if(e%n===0)return n}let i=e%100;return t.numberWordsMapping.some(e=>Number(e.number)===i)||i%10==0?i:e%10}convertNumber(e,t={},n){let r=n??this.getLocale(),i=r.config,a=t.gender,o=t.useAnd,s=e<0||typeof e==`bigint`&&e<0n;s&&(e=typeof e==`bigint`?-e:Math.abs(e));let c=typeof e==`bigint`,l=!c&&this.isFloat(e),u,d=``;if(c)u=e;else if(l){let t=e.toString().split(`.`);u=BigInt(t[0]),d=t[1]}else u=BigInt(Math.trunc(e));let f=this.isNumberZero(e)&&i.ignoreZeroInDecimals,p=this.convertInternal(u,!0,void 0,r,a,o);l&&f&&(p=[]);let m=[];if(l){let e=Number.parseInt(d,10),n=i.fractionDenominatorMapping?.[d.length];if(t.decimalStyle===`fraction`&&n){f||m.push(i.texts.and),m.push(...this.convertInternal(BigInt(e),!0,void 0,r,a));let t=i.fractionSingularRule===`slavic`?e%10==1&&e%100!=11:e===1;m.push(t?n.singular:n.plural)}else if(f||m.push(i.texts.point),d.startsWith(`0`)&&!i?.decimalLengthWordMapping){let e=[];for(let t of d)e.push(...this.convertInternal(BigInt(t),!0,void 0,r,a));m.push(...e)}else{m.push(...this.convertInternal(BigInt(d),!0,void 0,r,a));let e=i?.decimalLengthWordMapping?.[d.length];e&&m.push(e)}}return!(p.length<=0)&&s&&p.unshift(i.texts.minus),p.push(...m),p}convertCurrency(e,t={},n=!1,r){let i=r??this.getLocale(),a=i.config,o=t.gender,s=t.useAnd,c=t.currencyOptions??a.currency,l=c.precision??2,u=e<0||typeof e==`bigint`&&e<0n;u&&(e=typeof e==`bigint`?-e:Math.abs(e));let d=typeof e==`bigint`;d||(e=this.toFixed(e,l));let f=!d&&this.isFloat(e),p,m=``;if(d)p=e;else if(f){let t=e.toString().split(`.`);p=BigInt(t[0]),m=t[1]}else p=BigInt(Math.trunc(e));let h=[],g=p<=BigInt(2**53-1)?Number(p):-1;if(g!==-1&&c.numberSpecificForms?.[g])h=[c.numberSpecificForms[g]];else{let e=a.useTrailingForCurrency??!1;h=[...this.convertInternal(p,e,void 0,i,o,s)],p===1n&&c.singular?h.push(c.singular):c.plural&&h.push(c.plural)}let _=this.isNumberZero(e)&&(t.ignoreZeroCurrency||a?.ignoreZeroInDecimals&&e!==0&&e!==0n);_&&(h=[]);let v=[];if(f){_||v.push(a.texts.and);let e=!a.decimalLengthWordMapping&&m.length?10**Math.max(0,l-m.length):1,t=Number(m)*e,n=a?.decimalLengthWordMapping?.[m.length];c.fractionalUnit.numberSpecificForms?.[t]?v.push(c.fractionalUnit.numberSpecificForms[t]):(v.push(...this.convertInternal(BigInt(t),!1,void 0,i,o)),n?.length&&v.push(n),t===1&&c.fractionalUnit.singular?v.push(c.fractionalUnit.singular):v.push(c.fractionalUnit.plural))}else n&&!_&&!a.decimalLengthWordMapping&&c.fractionalUnit.plural?(v.push(a.texts.and),c.fractionalUnit.numberSpecificForms?.[0]?v.push(c.fractionalUnit.numberSpecificForms[0]):(v.push(...this.convertInternal(0n,!1,void 0,i,o)),v.push(c.fractionalUnit.plural))):a.decimalLengthWordMapping&&h.length&&v.push(c.fractionalUnit.plural);let y=h.length<=0&&v.length<=0;return!y&&u&&h.unshift(a.texts.minus),!y&&a.texts.only&&!t.doNotAddOnly&&!a.onlyInFront&&v.push(a.texts.only),v.length&&h.push(...v),!y&&!t.doNotAddOnly&&a.onlyInFront&&h.splice(0,0,a.texts.only),h}convertInternal(e,t=!1,s,c,l,u){let d=c??this.getLocale(),f=d.config,p=this.getLocaleCache(d);if(s){let t=e<=o?Number(e):-1;if(t!==-1&&s[t])return[s[t]]}let m=p.exactWordsMap.get(e);if(m)return[this.resolveGenderedValue(m,l,t)];let h;if(e<=a){let n=p.smallNumbersMap.get(e);if(n)return[this.resolveGenderedValue(n,l,t)];h=this.binarySearchDescending(p.numberWordsMappingBigInt,e)}else h=this.binarySearchDescending(p.numberWordsMappingBigInt,e);let g=h.numberBigInt,_=[];if(e<=a||e<1000n&&f.namedLessThan1000){_.push(this.resolveGenderedValue(h,l,t));let r=e-g;if(r>n){f.splitWord&&_.push(f.splitWord);let e=this.convertInternal(r,t,s,d,l,u);for(let t of e)_.push(t)}return _}let v=e/g,y=e%g,b=h.resolvedValue,x=h.resolvedValue,S=Number(g),C=f.pluralForms?.[S],w=!1,T=p.ignoreOneForWordsSet.has(x);if(C){let e=Number(v%a),t=v>=i&&e>=3&&e<=10;v===2n&&C.dual?(b=C.dual,w=!0):v>=BigInt(f.paucalConfig?.min??3)&&v<=BigInt(f.paucalConfig?.max??10)||t?C.paucal&&(b=C.paucal):v>=i&&C.plural&&(b=C.plural)}else{let e=h.value,t=p.pluralWordsSet.has(e),i=p.pluralWordsOnlyWhenTrailingSet.has(e);v>r&&f.pluralMark&&(t||i&&y===n)&&(b+=f.pluralMark),v%10n==r&&!T&&(b=h.singularValue||b)}if(v===r&&T||w){let e;e=w?b:h.singularValue?h.singularValue:this.resolveGenderedValue(h,l,t),_.push(e)}else{let e=this.convertInternal(v,!1,s,d,void 0,u);if(f.scaleFirst){_.push(b);for(let t of e)_.push(t)}else{for(let t of e)_.push(t);_.push(b)}}if(y>n){let e=f.texts.and?.trim();u&&y<a&&!f.splitWord&&e&&_.push(f.texts.and),f.splitWord&&(p.noSplitWordAfterSet.has(h.resolvedValue)||_.push(f.splitWord));let n=this.convertInternal(y,t,s,d,l,u);for(let e of n)_.push(e)}return _}binarySearchDescending(e,t){let n=0,r=e.length-1,i=e[r];for(;n<=r;){let a=n+r>>1;e[a].numberBigInt<=t?(i=e[a],r=a-1):n=a+1}return i}toFixed(e,t=2){return Number(Number(e).toFixed(t))}isFloat(e){return Number(e)===e&&e%1!=0}isValidNumber(e){let t=typeof e;if(t===`bigint`)return!0;if(t===`number`)return!Number.isNaN(e)&&Number.isFinite(e);if(t===`string`){let t=e;if(t.trim()===``)return!1;let n=Number(t);return!Number.isNaN(n)&&Number.isFinite(n)}return!1}isNumberZero(e){return typeof e==`bigint`?e===n:e>=0&&e<1}},c=class{config={currency:{name:`টকা`,plural:`টকা`,singular:`টকা`,symbol:`₹`,fractionalUnit:{name:`পইচা`,singular:`পইচা`,plural:`পইচা`,symbol:``}},texts:{and:`আৰু`,minus:`ঋণ`,only:``,point:`দশমিক`},numberWordsMapping:[{number:10n**17n,value:`শংখ`},{number:10n**15n,value:`পদ্ম`},{number:10n**13n,value:`নীল`},{number:10n**11n,value:`খৰব`},{number:10n**9n,value:`আৰব`},{number:1e7,value:`কোটি`},{number:1e5,value:`লাখ`},{number:1e3,value:`হাজাৰ`},{number:100,value:`এশ`},{number:99,value:`নিয়ান্নব্বৈ`},{number:98,value:`আঠান্নব্বৈ`},{number:97,value:`সাতান্নব্বৈ`},{number:96,value:`ছয়ান্নব্বৈ`},{number:95,value:`পঁচানব্বৈ`},{number:94,value:`চৌৰান্নব্বৈ`},{number:93,value:`তিৰান্নব্বৈ`},{number:92,value:`বিয়ান্নব্বৈ`},{number:91,value:`একান্নব্বৈ`},{number:90,value:`নব্বৈ`},{number:89,value:`ঊননব্বৈ`},{number:88,value:`আঠাশী`},{number:87,value:`সাতাশী`},{number:86,value:`ছয়াশী`},{number:85,value:`পঁচাশী`},{number:84,value:`চৌৰাশী`},{number:83,value:`তিৰাশী`},{number:82,value:`বিয়াশী`},{number:81,value:`একাশী`},{number:80,value:`আশী`},{number:79,value:`ঊনআশী`},{number:78,value:`আঠসত্তৰ`},{number:77,value:`সাতসত্তৰ`},{number:76,value:`ছয়সত্তৰ`},{number:75,value:`পঁসত্তৰ`},{number:74,value:`চৌসত্তৰ`},{number:73,value:`তেসত্তৰ`},{number:72,value:`বাসত্তৰ`},{number:71,value:`এসত্তৰ`},{number:70,value:`সত্তৰ`},{number:69,value:`ঊনসত্তৰ`},{number:68,value:`আঠষষ্ঠি`},{number:67,value:`সাতষষ্ঠি`},{number:66,value:`ছয়ষষ্ঠি`},{number:65,value:`পঁষষ্ঠি`},{number:64,value:`চৌষষ্ঠি`},{number:63,value:`তেষষ্ঠি`},{number:62,value:`বাষষ্ঠি`},{number:61,value:`এষষ্ঠি`},{number:60,value:`ষাঠি`},{number:59,value:`ঊনষাঠি`},{number:58,value:`আঠাৱন`},{number:57,value:`সাতাৱন`},{number:56,value:`ছাপন`},{number:55,value:`পঁচপন`},{number:54,value:`চৌৱন`},{number:53,value:`তেৱন`},{number:52,value:`বাৱন`},{number:51,value:`একাৱন`},{number:50,value:`পঞ্চাছ`},{number:49,value:`ঊনপঞ্চাছ`},{number:48,value:`আঠচল্লিছ`},{number:47,value:`সাতচল্লিছ`},{number:46,value:`ছয়চল্লিছ`},{number:45,value:`পঞ্চল্লিছ`},{number:44,value:`চৌৰাল্লিছ`},{number:43,value:`তিয়াল্লিছ`},{number:42,value:`বিয়াল্লিছ`},{number:41,value:`একচল্লিছ`},{number:40,value:`চল্লিছ`},{number:39,value:`ঊনচল্লিছ`},{number:38,value:`আঠত্ৰিছ`},{number:37,value:`সাতত্ৰিছ`},{number:36,value:`ছয়ত্ৰিছ`},{number:35,value:`পঁয়ত্ৰিছ`},{number:34,value:`চৌত্ৰিছ`},{number:33,value:`তেত্ৰিছ`},{number:32,value:`বত্ৰিছ`},{number:31,value:`একত্ৰিছ`},{number:30,value:`ত্ৰিছ`},{number:29,value:`ঊন্ত্ৰিছ`},{number:28,value:`আঠাইছ`},{number:27,value:`সাতাইছ`},{number:26,value:`ছাবিছ`},{number:25,value:`পঁচিছ`},{number:24,value:`চৌবিছ`},{number:23,value:`তেইছ`},{number:22,value:`বাইছ`},{number:21,value:`একৈছ`},{number:20,value:`বিছ`},{number:19,value:`ঊনৈছ`},{number:18,value:`ওঠৰ`},{number:17,value:`সোতৰ`},{number:16,value:`ষোল্ল`},{number:15,value:`পোন্ধৰ`},{number:14,value:`চৈধ্য`},{number:13,value:`তেৰ`},{number:12,value:`বাৰ`},{number:11,value:`এঘাৰ`},{number:10,value:`দহ`},{number:9,value:`ন`},{number:8,value:`আঠ`},{number:7,value:`সাত`},{number:6,value:`ছয়`},{number:5,value:`পাঁচ`},{number:4,value:`চাৰি`},{number:3,value:`তিনি`},{number:2,value:`দুই`},{number:1,value:`এক`},{number:0,value:`শূন্য`}],ordinalWordsMapping:[{number:1e7,value:`কোটিতম`},{number:1e5,value:`লক্ষতম`},{number:1e3,value:`সহস্ৰতম`},{number:100,value:`শততম`},{number:99,value:`নিয়ান্নব্বৈতম`},{number:98,value:`আঠান্নব্বৈতম`},{number:97,value:`সাতান্নব্বৈতম`},{number:96,value:`ছয়ান্নব্বৈতম`},{number:95,value:`পঁচানব্বৈতম`},{number:94,value:`চৌৰান্নব্বৈতম`},{number:93,value:`তিৰান্নব্বৈতম`},{number:92,value:`বিয়ান্নব্বৈতম`},{number:91,value:`একান্নব্বৈতম`},{number:90,value:`নব্বৈতম`},{number:89,value:`ঊননব্বৈতম`},{number:88,value:`আঠাশীতম`},{number:87,value:`সাতাশীতম`},{number:86,value:`ছয়াশীতম`},{number:85,value:`পঁচাশীতম`},{number:84,value:`চৌৰাশীতম`},{number:83,value:`তিৰাশীতম`},{number:82,value:`বিয়াশীতম`},{number:81,value:`একাশীতম`},{number:80,value:`আশীতম`},{number:79,value:`ঊনআশীতম`},{number:78,value:`আঠসত্তৰতম`},{number:77,value:`সাতসত্তৰতম`},{number:76,value:`ছয়সত্তৰতম`},{number:75,value:`পঁসত্তৰতম`},{number:74,value:`চৌসত্তৰতম`},{number:73,value:`তেসত্তৰতম`},{number:72,value:`বাসত্তৰতম`},{number:71,value:`এসত্তৰতম`},{number:70,value:`সত্তৰতম`},{number:69,value:`ঊনসত্তৰতম`},{number:68,value:`আঠষষ্ঠিতম`},{number:67,value:`সাতষষ্ঠিতম`},{number:66,value:`ছয়ষষ্ঠিতম`},{number:65,value:`পঁষষ্ঠিতম`},{number:64,value:`চৌষষ্ঠিতম`},{number:63,value:`তেষষ্ঠিতম`},{number:62,value:`বাষষ্ঠিতম`},{number:61,value:`এষষ্ঠিতম`},{number:60,value:`ষাঠিতম`},{number:59,value:`ঊনষাঠিতম`},{number:58,value:`আঠাৱনতম`},{number:57,value:`সাতাৱনতম`},{number:56,value:`ছাপনতম`},{number:55,value:`পঁচপনতম`},{number:54,value:`চৌৱনতম`},{number:53,value:`তেৱনতম`},{number:52,value:`বাৱনতম`},{number:51,value:`একাৱনতম`},{number:50,value:`পঞ্চাছতম`},{number:49,value:`ঊনপঞ্চাছতম`},{number:48,value:`আঠচল্লিছতম`},{number:47,value:`সাতচল্লিছতম`},{number:46,value:`ছয়চল্লিছতম`},{number:45,value:`পঞ্চল্লিছতম`},{number:44,value:`চৌৰাল্লিছতম`},{number:43,value:`তিয়াল্লিছতম`},{number:42,value:`বিয়াল্লিছতম`},{number:41,value:`একচল্লিছতম`},{number:40,value:`চল্লিছতম`},{number:39,value:`ঊনচল্লিছতম`},{number:38,value:`আঠত্ৰিছতম`},{number:37,value:`সাতত্ৰিছতম`},{number:36,value:`ছয়ত্ৰিছতম`},{number:35,value:`পঁয়ত্ৰিছতম`},{number:34,value:`চৌত্ৰিছতম`},{number:33,value:`তেত্ৰিছতম`},{number:32,value:`বত্ৰিছতম`},{number:31,value:`একত্ৰিছতম`},{number:30,value:`ত্ৰিছতম`},{number:29,value:`ঊন্ত্ৰিছতম`},{number:28,value:`আঠাইছতম`},{number:27,value:`সাতাইছতম`},{number:26,value:`ছাবিছতম`},{number:25,value:`পঁচিছতম`},{number:24,value:`চৌবিছতম`},{number:23,value:`তেইছতম`},{number:22,value:`বাইছতম`},{number:21,value:`একৈছতম`},{number:20,value:`বিছতম`},{number:19,value:`ঊনৈছতম`},{number:18,value:`ওঠৰতম`},{number:17,value:`সোতৰতম`},{number:16,value:`ষোল্লতম`},{number:15,value:`পোন্ধৰতম`},{number:14,value:`চৈধ্যতম`},{number:13,value:`তেৰতম`},{number:12,value:`বাৰতম`},{number:11,value:`এঘাৰতম`},{number:10,value:`দশম`},{number:9,value:`নৱম`},{number:8,value:`অষ্টম`},{number:7,value:`সপ্তম`},{number:6,value:`ষষ্ঠ`},{number:5,value:`পঞ্চম`},{number:4,value:`চতুৰ্থ`},{number:3,value:`তৃতীয়`},{number:2,value:`দ্বিতীয়`},{number:1,value:`প্ৰথম`},{number:0,value:`শূন্যতম`}],fractionDenominatorMapping:{1:{singular:`দশমাংশ`,plural:`দশমাংশ`},2:{singular:`শতাংশ`,plural:`শতাংশ`},3:{singular:`সহস্ৰাংশ`,plural:`সহস্ৰাংশ`},4:{singular:`দহ-সহস্ৰাংশ`,plural:`দহ-সহস্ৰাংশ`},5:{singular:`শত-সহস্ৰাংশ`,plural:`শত-সহস্ৰাংশ`},6:{singular:`দহ-লাখাংশ`,plural:`দহ-লাখাংশ`}}}},l=class extends s{constructor(e={}){super(e),this.setLocale(c)}};const u=new l;function d(e,t){return u.convert(e,t)}function f(e,t){return u.toOrdinal(e,t)}function p(e,t){return u.convert(e,{...t,currency:!0})}return l;})();