n2words
Version:
Convert numbers to words in 70+ languages with zero dependencies. Supports BigInt, decimals, and browser/Node.js environments.
3 lines (2 loc) • 9.46 kB
JavaScript
/*! n2words/uk-UA v5.1.2 | MIT License | github.com/forzagreen/n2words */
function e(e){let[n,t]=e.toLowerCase().split("e");const i=parseInt(t,10);let r="";"-"===n[0]&&(r="-",n=n.slice(1));const o=n.indexOf("."),s=-1===o?n:n.slice(0,o)+n.slice(o+1),u=(-1===o?n.length:o)+i;return u>=s.length?r+s+"0".repeat(u-s.length):u<=0?r+"0."+"0".repeat(-u)+s:r+s.slice(0,u)+"."+s.slice(u)}function n(n){const i=n.toString();return t(i)?e(i):i}function t(e){return e.includes("e")||e.includes("E")}function i(e){const n="-"===e[0];n&&(e=e.slice(1));const t=e.indexOf(".");if(-1===t)return{isNegative:n,integerPart:BigInt(e)};const i=e.slice(0,t)||"0",r=e.slice(t+1);return{isNegative:n,integerPart:BigInt(i),decimalPart:r}}function r(n){let i=n.trim();if(0===i.length||Number.isNaN(Number(i)))throw new RangeError(`Invalid currency format: "${n}"`);t(i)&&(i=e(i));const r="-"===i[0];r&&(i=i.slice(1));const o=i.indexOf(".");if(-1===o)return{isNegative:r,dollars:BigInt(i),cents:0n};const s=i.slice(0,o)||"0",u=(i.slice(o+1)+"00").slice(0,2);return{isNegative:r,dollars:BigInt(s),cents:BigInt(u)}}function o(e,n,t){if(null===n)return;if(e<n&&!(t&&BigInt(t)>=n))return;const i=n.toString().length-1,r=n===10n**BigInt(i)?`10^${i} - 1`:""+(n-1n);throw new RangeError(`Number too large to convert: the largest supported value is ${r}`)}function s(e){return 10n**BigInt(3*(e+1))}const u=["","один","два","три","чотири","п'ять","шiсть","сiм","вiсiм","дев'ять"],c=["","одна","двi","три","чотири","п'ять","шiсть","сiм","вiсiм","дев'ять"],f=["десять","одинадцять","дванадцять","тринадцять","чотирнадцять","п'ятнадцять","шiстнадцять","сiмнадцять","вiсiмнадцять","дев'ятнадцять"],g=["","","двадцять","тридцять","сорок","п'ятдесят","шiстдесят","сiмдесят","вiсiмдесят","дев'яносто"],l=["","сто","двiстi","триста","чотириста","п'ятсот","шiстсот","сiмсот","вiсiмсот","дев'ятсот"],a="нуль",h="мiнус",p=["","перший","другий","третiй","четвертий","п'ятий","шостий","сьомий","восьмий","дев'ятий"],b=["десятий","одинадцятий","дванадцятий","тринадцятий","чотирнадцятий","п'ятнадцятий","шiстнадцятий","сiмнадцятий","вiсiмнадцятий","дев'ятнадцятий"],m=["","","двадцятий","тридцятий","сороковий","п'ятдесятий","шiстдесятий","сiмдесятий","вiсiмдесятий","дев'яностий"],d=["","сотий","двохсотий","трьохсотий","чотирьохсотий","п'ятисотий","шестисотий","семисотий","восьмисотий","дев'ятисотий"],w=["тисячний","мiльйонний","мiльярдний","трильйонний"],N=["гривня","гривнi","гривень"],v=["копiйка","копiйки","копiйок"],y=[["тисяча","тисячi","тисяч"],["мiльйон","мiльйони","мiльйонiв"],["мiльярд","мiльярди","мiльярдiв"],["трильйон","трильйони","трильйонiв"],["квадрильйон","квадрильйони","квадрильйонiв"],["квiнтильйон","квiнтильйони","квiнтильйонiв"],["секстильйон","секстильйони","секстильйонiв"],["септильйон","септильйони","септильйонiв"],["октильйон","октильйони","октильйонiв"]];function I(e,n){const t="bigint"==typeof e?Number(e):e,i=t%10,r=t%100;return r>=11&&r<=19?n[2]:1===i?n[0]:i>=2&&i<=4?n[1]:n[2]}function E(e){if(0===e)return"";const n=e%10,t=Math.trunc(e/10)%10,i=Math.trunc(e/100),r=[];return i>0&&r.push(l[i]),t>1&&r.push(g[t]),1===t?r.push(f[n]):n>0&&r.push(u[n]),r.join(" ")}function O(e){if(0===e)return"";const n=e%10,t=Math.trunc(e/10)%10,i=Math.trunc(e/100),r=[];return i>0&&r.push(l[i]),t>1&&r.push(g[t]),1===t?r.push(f[n]):n>0&&r.push(c[n]),r.join(" ")}function B(e,n){return 0n===e?a:e<1000n?"feminine"===n?O(Number(e)):E(Number(e)):function(e,n){const t=e.toString(),i=t.length,r=[],o=i%3;let s=0;for(o>0&&(r.push(Number(t.slice(0,o))),s=o);s<i;)r.push(Number(t.slice(s,s+3))),s+=3;const u=[];let c=r.length-1;for(let e=0;e<r.length;e++){const t=r[e];if(0!==t)if(0===c)u.push("feminine"===n?O(t):E(t));else{const e=I(t,y[c-1]),n=1===c?O(t):E(t);u.push(n+" "+e)}c--}return u.join(" ")}(e,n)}const R=s(y.length),$=s(w.length),j=s(y.length),P={gender:"masculine"},x={gender:["masculine","feminine"]};function S(r,s){const{isNegative:u,integerPart:c,decimalPart:f}=function(r){const o=typeof r;if("bigint"==typeof r)return r<0n?{isNegative:!0,integerPart:-r}:{isNegative:!1,integerPart:r};if("number"==typeof r){if(!Number.isFinite(r))throw new RangeError("Number must be finite (NaN and Infinity are not supported)");return Number.isSafeInteger(r)?r<0?{isNegative:!0,integerPart:BigInt(-r)}:{isNegative:!1,integerPart:BigInt(r)}:i(n(r))}if("string"==typeof r)return i(function(n){const i=n.trim();if(0===i.length||Number.isNaN(Number(i)))throw new RangeError(`Invalid number format: "${n}"`);return t(i)?e(i):i}(r));throw new TypeError(`Invalid value type: expected number, string, or bigint, received ${o}`)}(r);o(c,R,f);const{gender:g}=function(e,n,t){const i={...n};if(void 0===e)return i;if(!function(e){if(null===e||"object"!=typeof e)return!1;const n=Object.getPrototypeOf(e);return null===n||n===Object.prototype}(e))throw new TypeError("Invalid options: expected plain object or undefined, got "+typeof e);const r=Object.keys(n);for(const[o,s]of Object.entries(e)){if(!Object.hasOwn(n,o))throw new TypeError(`Unknown option "${o}" — expected one of: ${r.join(", ")}`);if(void 0!==s){if(typeof s!=typeof i[o])throw new TypeError(`Option "${o}" must be a ${typeof i[o]}, got ${typeof s}`);if(void 0!==t&&Object.hasOwn(t,o)){const e=t[o];if(!e.includes(s))throw new RangeError(`Option "${o}" must be one of: ${e.join(", ")} — got ${JSON.stringify(s)}`)}i[o]=s}}return i}(s,P,x);let l="";return u&&(l=h+" "),l+=B(c,g),f&&(l+=" кома "+function(e,n){let t="",i=0;for(;i<e.length&&"0"===e[i];)t&&(t+=" "),t+=a,i++;const r=e.slice(i);return r&&(t&&(t+=" "),t+=B(BigInt(r),n)),t}(f,g)),l}function M(e){if(0===e)return"";const n=e%10,t=Math.trunc(e/10);return 0===t?p[n]:1===t?b[n]:0===n?m[t]:g[t]+" "+p[n]}function T(e){if(e<100n)return M(Number(e));if(e<1000n){const n=Number(e),t=Math.trunc(n/100),i=n%100;return 0===i?d[t]:l[t]+" "+M(i)}if(e<1000000n){const n=Number(e/1000n),t=Number(e%1000n);if(0===t)return 1===n?w[0]:O(n)+" "+w[0];const i=I(n,y[0]);return O(n)+" "+i+" "+T(BigInt(t))}return function(e){const n=e.toString(),t=n.length,i=[],r=t%3;let o=0;for(r>0&&(i.push(Number(n.slice(0,r))),o=r);o<t;)i.push(Number(n.slice(o,o+3))),o+=3;let s=i.length-1;for(;s>=0&&0===i[s];)s--;const u=[];let c=i.length-1;for(let e=0;e<i.length;e++){const n=i[e];if(0!==n){const t=e===s;if(0===c)u.push(t?T(BigInt(n)):E(n));else if(t)if(1===n)u.push(w[c-1]);else{const e=1===c?O(n):E(n);u.push(e+" "+w[c-1])}else{const e=I(n,y[c-1]),t=1===c?O(n):E(n);u.push(t+" "+e)}}c--}return u.join(" ")}(e)}function F(n){const i=function(n){const i=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 i=n.trim();if(0===i.length)throw new RangeError("Ordinals cannot be empty strings");if("-"===i[0])throw new RangeError("Ordinals cannot be negative");if(i.includes("."))throw new RangeError("Ordinals must be whole numbers");if(t(i)){const n=e(i);if(n.includes("."))throw new RangeError("Ordinals must be whole numbers");const t=BigInt(n);if(t<=0n)throw new RangeError("Ordinals must be positive integers");return t}try{const e=BigInt(i);if(e<=0n)throw new RangeError("Ordinals must be positive integers");return e}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 ${i}`)}(n);return o(i,$),T(i)}function k(e){const{isNegative:t,dollars:i,cents:s}=function(e){const t=typeof e;if("bigint"==typeof e)return e<0n?{isNegative:!0,dollars:-e,cents:0n}:{isNegative:!1,dollars:e,cents:0n};if("number"==typeof e){if(!Number.isFinite(e))throw new RangeError("Currency must be a finite number");return Number.isSafeInteger(e)?e<0?{isNegative:!0,dollars:BigInt(-e),cents:0n}:{isNegative:!1,dollars:BigInt(e),cents:0n}:r(n(e))}if("string"==typeof e)return r(e);throw new TypeError(`Invalid value type: expected number, string, or bigint, received ${t}`)}(e);o(i,j);let u="";return t&&(u=h+" "),(i>0n||0n===s)&&(u+=B(i,"feminine"),u+=" "+I(i,N)),s>0n&&(i>0n&&(u+=" "),u+=B(s,"feminine"),u+=" "+I(s,v)),u}export{P as cardinalDefaults,R as cardinalMax,x as cardinalValues,j as currencyMax,$ as ordinalMax,S as toCardinal,k as toCurrency,F as toOrdinal};