{"version":3,"file":"codymath.cjs","names":[],"sources":["../src/alphabets/greek.ts","../src/constants/constants.ts","../src/algebra/arithmetic.ts","../src/utils/toWords/en-US.ts","../src/utils/toWords/pt-BR.ts","../src/utils/toWords/es-ES.ts","../src/utils/toWords/index.ts","../src/utils/utils.ts","../src/utils/index.ts"],"sourcesContent":["/**\r\n * @fileoverview Initial module for CodyMath containing the Greek alphabet.\r\n * @version 0.8.0\r\n * @license MIT\r\n * * @author Jackson Douglas de Souza\r\n * @see {@link https://www.linkedin.com/in/jacksondouglasdsouza/|LinkedIn}\r\n * @see {@link https://github.com/jacksondouglasdesouza|GitHub}\r\n * * @description\r\n * This module is based on universally accepted mathematical constants and tables.\r\n * While the initial data is from Schaum's Outlines, the module is cross-referenced\r\n * with other major mathematical handbooks to ensure accuracy and completeness.\r\n * * @see\r\n * Sources & References:\r\n * 1. Spiegel, M. R., Lipschutz, S., & Liu, J. \"Schaum's Outline of Mathematical Handbook of Formulas and Tables\".\r\n * 2. National Institute of Standards and Technology (NIST). \"Digital Library of Mathematical Functions (DLMF)\".\r\n * 3. Abramowitz, M., & Stegun, I. A. \"Handbook of Mathematical Functions\".\r\n * 4. Gradshteyn, I. S., & Ryzhik, I. M. \"Table of Integrals, Series, and Products\".\r\n * 5. Wolfram Research. \"Wolfram MathWorld\".\r\n */\r\n\r\n/**\r\n * Interface defining the structure of a Greek letter.\r\n */\r\ninterface GreekLetter {\r\n   /** The English name of the letter. */\r\n   name: string;\r\n   /** The lowercase character. */\r\n   lower: string;\r\n   /** The uppercase character. */\r\n   upper: string;\r\n}\r\n\r\n/**\r\n * An object containing all 24 letters of the Greek alphabet.\r\n * The keys are the English names of the letters for programmatic access.\r\n */\r\nexport const greekAlphabet: { [key: string]: GreekLetter } = {\r\n   alpha: { name: \"Alpha\", lower: \"α\", upper: \"Α\" },\r\n   beta: { name: \"Beta\", lower: \"β\", upper: \"Β\" },\r\n   gamma: { name: \"Gamma\", lower: \"γ\", upper: \"Γ\" },\r\n   delta: { name: \"Delta\", lower: \"δ\", upper: \"Δ\" },\r\n   epsilon: { name: \"Epsilon\", lower: \"ε\", upper: \"Ε\" },\r\n   zeta: { name: \"Zeta\", lower: \"ζ\", upper: \"Ζ\" },\r\n   eta: { name: \"Eta\", lower: \"η\", upper: \"Η\" },\r\n   theta: { name: \"Theta\", lower: \"θ\", upper: \"Θ\" },\r\n   iota: { name: \"Iota\", lower: \"ι\", upper: \"Ι\" },\r\n   kappa: { name: \"Kappa\", lower: \"κ\", upper: \"Κ\" },\r\n   lambda: { name: \"Lambda\", lower: \"λ\", upper: \"Λ\" },\r\n   mu: { name: \"Mu\", lower: \"μ\", upper: \"Μ\" },\r\n   nu: { name: \"Nu\", lower: \"ν\", upper: \"Ν\" },\r\n   xi: { name: \"Xi\", lower: \"ξ\", upper: \"Ξ\" },\r\n   omicron: { name: \"Omicron\", lower: \"ο\", upper: \"Ο\" },\r\n   pi: { name: \"Pi\", lower: \"π\", upper: \"Π\" },\r\n   rho: { name: \"Rho\", lower: \"ρ\", upper: \"Ρ\" },\r\n   sigma: { name: \"Sigma\", lower: \"σ\", upper: \"Σ\" },\r\n   tau: { name: \"Tau\", lower: \"τ\", upper: \"Τ\" },\r\n   upsilon: { name: \"Upsilon\", lower: \"υ\", upper: \"Υ\" },\r\n   phi: { name: \"Phi\", lower: \"φ\", upper: \"Φ\" },\r\n   chi: { name: \"Chi\", lower: \"χ\", upper: \"Χ\" },\r\n   psi: { name: \"Psi\", lower: \"ψ\", upper: \"Ψ\" },\r\n   omega: { name: \"Omega\", lower: \"ω\", upper: \"Ω\" },\r\n};\r\n","// src/constants/constants.ts\r\n\r\n/**\r\n * @fileoverview Foundational mathematical constants for the CodyMath library.\r\n * @version 0.8.0\r\n * @license MIT\r\n * @author Jackson Douglas de Souza\r\n * @see {@link https://www.linkedin.com/in/jacksondouglasdsouza/|LinkedIn}\r\n * @see {@link https://github.com/jacksondouglasdesouza|GitHub}\r\n * @description This module provides a centralized and reliable source for fundamental mathematical constants.\r\n * It includes transcendental numbers (like π and e), number-theoretic constants (like γ),\r\n * and essential conversion factors used across science, engineering, and mathematics.\r\n *\r\n * Each constant is defined to the highest possible precision within the standard\r\n * IEEE 754 double-precision format used by JavaScript numbers. The values are rigorously\r\n * cross-referenced with authoritative sources to ensure their accuracy and adherence\r\n * to international standards.\r\n * @see\r\n * Sources & References:\r\n * 1. National Institute of Standards and Technology (NIST). (2023). *Digital Library of Mathematical Functions*. U.S. Department of Commerce. Retrieved from https://dlmf.nist.gov/\r\n * 2. Wolfram Research, Inc. *Wolfram MathWorld*. Retrieved from https://mathworld.wolfram.com/\r\n * 3. Spiegel, M. R., et al. (2018). *Schaum's Outline of Mathematical Handbook of Formulas and Tables, 5th Edition*. McGraw-Hill Education.\r\n * 4. ECMA International. (2025). *ECMAScript® 2025 Language Specification*. Retrieved from https://tc39.es/ecma262/\r\n */\r\n\r\n/**\r\n * An object containing fundamental mathematical constants.\r\n */\r\nexport const constants = {\r\n   /**\r\n    * Pi (π), the ratio of a circle's circumference to its diameter.\r\n    * @value 3.141592653589793\r\n    */\r\n   pi: 3.141592653589793,\r\n\r\n   /**\r\n    * Euler's number (e), the base of the natural logarithm.\r\n    * @value 2.718281828459045\r\n    */\r\n   e: 2.718281828459045,\r\n\r\n   /**\r\n    * The golden ratio (φ), the positive root of x^2 = x + 1.\r\n    * Equals (1 + √5) / 2 and appears throughout geometry, art, and nature.\r\n    * @value 1.618033988749895\r\n    */\r\n   phi: 1.618033988749895,\r\n\r\n   /**\r\n    * Tau (τ), the ratio of a circle's circumference to its radius (2π).\r\n    * Represents one full turn in radians.\r\n    * @value 6.283185307179586\r\n    */\r\n   tau: 6.283185307179586,\r\n\r\n   /**\r\n    * The square root of 2 (√2), known as Pythagoras' constant.\r\n    * The diagonal of a unit square, and the first number proven irrational.\r\n    * @value 1.4142135623730951\r\n    */\r\n   sqrt2: 1.4142135623730951,\r\n\r\n   /**\r\n    * The square root of 3 (√3), known as Theodorus' constant.\r\n    * The space diagonal of a unit cube; also (√3)/2 is an equilateral triangle's height.\r\n    * @value 1.7320508075688772\r\n    */\r\n   sqrt3: 1.7320508075688772,\r\n\r\n   /**\r\n    * The square root of 5 (√5).\r\n    * The core of the golden ratio: φ = (1 + √5) / 2.\r\n    * @value 2.23606797749979\r\n    */\r\n   sqrt5: 2.23606797749979,\r\n\r\n   /**\r\n    * The reciprocal square root of 2 (1/√2 = √½), equal to √2 / 2.\r\n    * The value of sin(45°) = cos(45°); common in geometry and signal RMS.\r\n    * @value 0.7071067811865476\r\n    */\r\n   sqrt1_2: 0.7071067811865476,\r\n\r\n   /**\r\n    * The natural logarithm of 2 (ln 2).\r\n    * Key to half-life and decay, information theory, and logarithm base changes.\r\n    * @value 0.6931471805599453\r\n    */\r\n   ln2: 0.6931471805599453,\r\n\r\n   /**\r\n    * The natural logarithm of 10 (ln 10).\r\n    * Bridges natural and base-10 logs: log₁₀(x) = ln(x) / ln 10.\r\n    * @value 2.302585092994046\r\n    */\r\n   ln10: 2.302585092994046,\r\n\r\n   /**\r\n    * The base-2 logarithm of e (log₂ e), the reciprocal of ln 2.\r\n    * Converts natural logs to base 2: log₂(x) = ln(x) · log₂ e.\r\n    * @value 1.4426950408889634\r\n    */\r\n   log2e: 1.4426950408889634,\r\n\r\n   /**\r\n    * The base-10 logarithm of e (log₁₀ e), the reciprocal of ln 10.\r\n    * Converts natural logs to base 10: log₁₀(x) = ln(x) · log₁₀ e.\r\n    * @value 0.4342944819032518\r\n    */\r\n   log10e: 0.4342944819032518,\r\n\r\n   /**\r\n    * Catalan's constant (G), defined by the series Σ (−1)ⁿ / (2n+1)².\r\n    * Appears in combinatorics, definite integrals, and lattice sums.\r\n    * Whether it is irrational is still an open problem.\r\n    * @value 0.915965594177219\r\n    */\r\n   catalan: 0.915965594177219,\r\n\r\n   /**\r\n    * Apéry's constant (ζ(3)), the Riemann zeta function at 3: Σ 1/n³.\r\n    * Proven irrational by Roger Apéry in 1979. Shows up in quantum\r\n    * electrodynamics and in the statistics of random spanning trees.\r\n    * @value 1.2020569031595942\r\n    */\r\n   apery: 1.2020569031595942,\r\n\r\n   /**\r\n    * The golden angle (in radians), π·(3 − √5) ≈ 137.5°.\r\n    * The angle that divides a turn by the golden ratio; nature uses it to\r\n    * pack leaves and seeds (phyllotaxis) without overlap.\r\n    * @value 2.399963229728653\r\n    */\r\n   goldenAngle: 2.399963229728653,\r\n\r\n   /**\r\n    * The plastic number (ρ), the real root of x³ = x + 1.\r\n    * The \"three-dimensional\" analogue of the golden ratio (which solves x² = x + 1).\r\n    * Drives the Padovan and Perrin sequences; used in design and architecture.\r\n    * @value 1.324717957244746\r\n    */\r\n   plasticNumber: 1.324717957244746,\r\n\r\n   /**\r\n    * The Euler-Mascheroni constant (γ), often referred to as Euler's constant.\r\n    * @value 0.5772156649015329\r\n    */\r\n   eulerMascheroni: 0.5772156649015329,\r\n\r\n   /**\r\n    * The constant e to the power of gamma (e^γ).\r\n    * It is one of the Mertens' constants, appearing in number theory.\r\n    * @value 1.781072417990198\r\n    */\r\n   eToTheGamma: 1.781072417990198,\r\n\r\n   /**\r\n    * The square root of Euler's number (√e).\r\n    * @value 1.6487212707001282\r\n    */\r\n   sqrtE: 1.6487212707001282,\r\n\r\n   /**\r\n    * The square root of Pi (√π), also related to the Gamma function as Γ(1/2).\r\n    * @value 1.772453850905516\r\n    */\r\n   sqrtPi: 1.772453850905516,\r\n\r\n   /**\r\n    * The value of the Gamma function Γ(1/3).\r\n    * @value 2.6789385347077475\r\n    */\r\n   gammaOneThird: 2.6789385347077475,\r\n\r\n   /**\r\n    * The value of the Gamma function Γ(1/4).\r\n    * @value 3.625609908221908\r\n    */\r\n   gammaOneFourth: 3.625609908221908,\r\n\r\n   /**\r\n    * The conversion factor from radians to degrees (180/π).\r\n    * @value 57.29577951308232\r\n    */\r\n   radToDeg: 57.29577951308232,\r\n\r\n   /**\r\n    * The conversion factor from degrees to radians (π/180).\r\n    * @value 0.017453292519943295\r\n    */\r\n   degToRad: 0.017453292519943295,\r\n};\r\n","// src/algebra/arithmetic.ts\r\n\r\nimport { constants } from \"../constants/constants\";\r\n\r\n/**\r\n * @fileoverview Core arithmetic, number theory, and utility functions.\r\n * @version 0.8.0\r\n * @license MIT\r\n * @author Jackson Douglas de Souza\r\n * @see {@link https://www.linkedin.com/in/jacksondouglasdsouza/|LinkedIn}\r\n * @see {@link https://github.com/jacksondouglasdesouza/codymath|GitHub}\r\n * @description\r\n * This module forms the foundational layer of the CodyMath library, providing a comprehensive\r\n * suite of basic arithmetic, number theory, and utility functions.\r\n *\r\n * The goal is to create robust, well-tested primitives that can be used to build\r\n * more complex mathematical functionalities in other modules, ensuring internal consistency\r\n * and reliability.\r\n *\r\n * Sources & References:\r\n * 1. National Institute of Standards and Technology (NIST). (2023). *Digital Library of Mathematical Functions*. U.S. Department of Commerce. Retrieved from https://dlmf.nist.gov/\r\n * 2. Wolfram Research, Inc. *Wolfram MathWorld*. Retrieved from https://mathworld.wolfram.com/\r\n * 3. Spiegel, M. R., et al. (2018). *Schaum's Outline of Mathematical Handbook of Formulas and Tables, 5th Edition*. McGraw-Hill Education.\r\n * 4. ECMA International. (2025). *ECMAScript® 2025 Language Specification*. Retrieved from https://tc39.es/ecma262/\r\n * 5. Knuth, D. E. (1997). *The Art of Computer Programming, Vol. 2: Seminumerical Algorithms, 3rd Edition*. Addison-Wesley.\r\n * 6. Cormen, T. H., et al. (2022). *Introduction to Algorithms, 4th Edition*. MIT Press.\r\n * 7. Goldberg, D. (1991). *What Every Computer Scientist Should Know About Floating-Point Arithmetic*. ACM Computing Surveys, 23(1), 5-48.\r\n * 8. OEIS Foundation Inc. *The On-Line Encyclopedia of Integer Sequences*. Retrieved from https://oeis.org/\r\n */\r\n\r\n/**\r\n * Calculates the sum of a set of numbers.\r\n * @param {...number} numbers A list of numbers to sum.\r\n * @returns {number} The total sum. Returns 0 if no numbers are provided.\r\n */\r\nexport function sum(...numbers: number[]): number {\r\n   return numbers.reduce((total, current) => total + current, 0);\r\n}\r\n\r\n/**\r\n * Calculates the difference between two numbers (a - b).\r\n * @param {number} a The number to subtract from (minuend).\r\n * @param {number} b The number to subtract (subtrahend).\r\n * @returns {number} The result of the subtraction.\r\n */\r\nexport function subtract(a: number, b: number): number {\r\n   return a - b;\r\n}\r\n\r\n/**\r\n * Calculates the product of a set of numbers.\r\n * @param {...number} numbers A list of numbers to multiply.\r\n * @returns {number} The total product. Returns 1 if no numbers are provided (multiplicative identity).\r\n */\r\nexport function multiply(...numbers: number[]): number {\r\n   return numbers.reduce((total, current) => total * current, 1);\r\n}\r\n\r\n/**\r\n * Divides one number by another (a / b).\r\n * Throws an error if division by zero is attempted.\r\n * @param {number} a The dividend.\r\n * @param {number} b The divisor.\r\n * @returns {number} The result of the division.\r\n * @throws {Error} If the divisor `b` is 0.\r\n */\r\nexport function divide(a: number, b: number): number {\r\n   if (b === 0) {\r\n      throw new Error(\"Division by zero is not allowed.\");\r\n   }\r\n   return a / b;\r\n}\r\n\r\n/**\r\n * Calculates the arithmetic mean (average) of a set of numbers.\r\n * @param {...number} numbers A list of numbers to average.\r\n * @returns {number} The arithmetic mean. Returns NaN if no numbers are provided.\r\n */\r\nexport function mean(...numbers: number[]): number {\r\n   if (numbers.length === 0) {\r\n      return NaN;\r\n   }\r\n   return sum(...numbers) / numbers.length;\r\n}\r\n\r\n/**\r\n * Calculates the value of a base raised to the power of an exponent ($base^{exponent}$).\r\n * @param {number} base The base number.\r\n * @param {number} exponent The exponent.\r\n * @returns {number} The result of the exponentiation.\r\n */\r\nexport function power(base: number, exponent: number): number {\r\n   return base ** exponent;\r\n}\r\n\r\n/**\r\n * Calculates the square root of a non-negative number ($\\sqrt{n}$).\r\n * @param {number} n The number to calculate the square root of. Must be non-negative.\r\n * @returns {number} The square root of `n`. Returns `NaN` if `n` is negative.\r\n */\r\nexport function sqrt(n: number): number {\r\n   return Math.sqrt(n);\r\n}\r\n\r\n/**\r\n * Calculates the cube root of a number ($\\sqrt[3]{n}$).\r\n * @param {number} n The number to calculate the cube root of.\r\n * @returns {number} The cube root of `n`.\r\n */\r\nexport function cbrt(n: number): number {\r\n   return Math.cbrt(n);\r\n}\r\n\r\n/**\r\n * Calculates the nth root of a number ($ \\sqrt[root]{n} $).\r\n * Handles negative numbers correctly for odd roots.\r\n * @param {number} n The radicand (the number to find the root of).\r\n * @param {number} root The degree of the root (e.g., 2 for square root).\r\n * @returns {number} The nth root of the number.\r\n */\r\nexport function nthRoot(n: number, root: number): number {\r\n   if (n < 0 && root % 2 === 0) {\r\n      return NaN;\r\n   }\r\n\r\n   if (n < 0) {\r\n      return -power(-n, 1 / root);\r\n   }\r\n\r\n   return power(n, 1 / root);\r\n}\r\n\r\n/**\r\n * Calculates the value of Euler's number `e` raised to the power of `n` ($e^n$).\r\n * Uses the native Math.exp for maximum floating-point precision.\r\n * @param {number} n The exponent.\r\n * @returns {number} The result of e^n.\r\n */\r\nexport function exp(n: number): number {\r\n   return Math.exp(n);\r\n}\r\n\r\n/**\r\n * Calculates the natural logarithm (base e) of a number ($ln(n)$).\r\n * @param {number} n The number to calculate the logarithm of. Must be positive.\r\n * @returns {number} The natural logarithm of `n`. Returns `NaN` if `n` is negative and `-Infinity` if `n` is 0.\r\n */\r\nexport function ln(n: number): number {\r\n   return Math.log(n);\r\n}\r\n\r\n/**\r\n * Calculates the common logarithm (base 10) of a number ($log_{10}(n)$).\r\n * @param {number} n The number to calculate the logarithm of. Must be positive.\r\n * @returns {number} The common logarithm of `n`. Returns `NaN` if `n` is negative and `-Infinity` if `n` is 0.\r\n */\r\nexport function log10(n: number): number {\r\n   return Math.log10(n);\r\n}\r\n\r\n/**\r\n * Calculates the binary logarithm (base 2) of a number ($log_{2}(n)$).\r\n * @param {number} n The number to calculate the logarithm of. Must be positive.\r\n * @returns {number} The binary logarithm of `n`. Returns `NaN` if `n` is negative and `-Infinity` if `n` is 0.\r\n */\r\nexport function log2(n: number): number {\r\n   return Math.log2(n);\r\n}\r\n\r\n/**\r\n * Calculates the logarithm of a number `n` with a custom `base` ($log_{base}(n)$).\r\n * @param {number} n The number to calculate the logarithm of. Must be positive.\r\n * @param {number} base The base of the logarithm. Must be positive and not equal to 1.\r\n * @returns {number} The logarithm of `n` with the specified `base`. Returns `NaN` for invalid bases.\r\n */\r\nexport function log(n: number, base: number): number {\r\n   if (base <= 0 || base === 1) {\r\n      return NaN;\r\n   }\r\n\r\n   return divide(ln(n), ln(base));\r\n}\r\n\r\n/**\r\n * Finds the Greatest Common Divisor (GCD) of two integers using the Euclidean algorithm.\r\n * Floats are truncated, and the absolute value of the numbers is used.\r\n * Non-finite inputs (NaN, ±Infinity) return NaN — without this guard, the\r\n * Euclidean loop would never terminate, since NaN propagates through the\r\n * % operator and NaN !== 0 is always true.\r\n * @param {number} a The first integer.\r\n * @param {number} b The second integer.\r\n * @returns {number} The greatest common divisor of a and b. Returns NaN if\r\n *                   either input is NaN or ±Infinity.\r\n */\r\nexport function gcd(a: number, b: number): number {\r\n   // Non-finite inputs would make the % operator produce NaN, and since\r\n   // NaN !== 0 is always true, the Euclidean loop would never terminate.\r\n   if (!Number.isFinite(a) || !Number.isFinite(b)) {\r\n      return NaN;\r\n   }\r\n\r\n   let numA = Math.abs(Math.trunc(a));\r\n   let numB = Math.abs(Math.trunc(b));\r\n\r\n   while (numB !== 0) {\r\n      // Using a temp variable instead of array destructuring for better GC performance.\r\n      let temp = numB;\r\n      numB = numA % numB;\r\n      numA = temp;\r\n   }\r\n\r\n   return numA;\r\n}\r\n\r\n/**\r\n * Finds the Least Common Multiple (LCM) of two integers.\r\n * The calculation is based on the formula: lcm(a, b) = (|a| / gcd(a, b)) * |b|.\r\n * @param {number} a The first integer. Floats are truncated.\r\n * @param {number} b The second integer. Floats are truncated.\r\n * @returns {number} The least common multiple of a and b. Returns 0 if either\r\n *                   a or b is 0, or NaN if either input is non-finite\r\n *                   (inherited from gcd).\r\n */\r\nexport function lcm(a: number, b: number): number {\r\n   const numA = Math.abs(Math.trunc(a));\r\n   const numB = Math.abs(Math.trunc(b));\r\n\r\n   if (numA === 0 || numB === 0) {\r\n      return 0;\r\n   }\r\n\r\n   // Dividing before multiplying avoids premature overflow beyond Number.MAX_SAFE_INTEGER.\r\n   // Since gcd(a, b) always divides a exactly, (numA / gcd) is guaranteed to be an integer.\r\n   return (numA / gcd(numA, numB)) * numB;\r\n}\r\n\r\n/**\r\n * Checks if a number is prime using an optimized trial division method.\r\n * A number is prime if it is greater than 1 and has no positive divisors other than 1 and itself.\r\n * @param {number} n The integer to check. Floats are truncated.\r\n * @returns {boolean} `true` if the number is prime, otherwise `false`.\r\n */\r\nexport function isPrime(n: number): boolean {\r\n   const num = Math.trunc(n);\r\n\r\n   if (num <= 1) {\r\n      return false;\r\n   }\r\n\r\n   if (num === 2) {\r\n      return true;\r\n   }\r\n\r\n   if (num % 2 === 0) {\r\n      return false;\r\n   }\r\n\r\n   // Using i * i <= num instead of i <= Math.sqrt(num) avoids any floating-point\r\n   // imprecision from Math.sqrt and keeps the comparison in pure integer arithmetic.\r\n   for (let i = 3; i * i <= num; i += 2) {\r\n      if (num % i === 0) {\r\n         return false;\r\n      }\r\n   }\r\n\r\n   return true;\r\n}\r\n\r\n/**\r\n * Checks if a number is even.\r\n * @param {number} n The integer to check. Floats are truncated.\r\n * @returns {boolean} `true` if the number is even, otherwise `false`.\r\n */\r\nexport function isEven(n: number): boolean {\r\n   const num = Math.trunc(n);\r\n   return num % 2 === 0;\r\n}\r\n\r\n/**\r\n * Checks if a number is odd.\r\n * @param {number} n The integer to check. Floats are truncated.\r\n * @returns {boolean} `true` if the number is odd, otherwise `false`.\r\n */\r\nexport function isOdd(n: number): boolean {\r\n   // An odd number is simply not an even number.\r\n   // This ensures internal consistency with isEven().\r\n   return !isEven(n);\r\n}\r\n\r\n/**\r\n * Calculates the factorial of a non-negative integer (n!).\r\n * The factorial of n is the product of all positive integers up to n.\r\n *\r\n * Precision note: results are exact only up to 18! (the last value that fits within\r\n * Number.MAX_SAFE_INTEGER). From 23! onward the returned value is an approximation due to\r\n * IEEE-754 limits, and the function returns Infinity for n > 170. For exact large factorials,\r\n * a BigInt-based implementation would be required.\r\n *\r\n * @param {number} n The non-negative integer. Floats are truncated.\r\n * @returns {number} The factorial of n. Returns 1 for n = 0. Returns NaN for negative inputs.\r\n */\r\nexport function factorial(n: number): number {\r\n   const num = Math.trunc(n);\r\n\r\n   // Factorial is not defined for negative numbers.\r\n   if (num < 0) {\r\n      return NaN;\r\n   }\r\n\r\n   if (num === 0) {\r\n      return 1;\r\n   }\r\n\r\n   let result = 1;\r\n   for (let i = 2; i <= num; i++) {\r\n      result *= i;\r\n   }\r\n\r\n   return result;\r\n}\r\n\r\n/**\r\n * Returns the absolute value of a number.\r\n * The absolute value of a number is its distance from zero, always non-negative.\r\n * @param {number} n The number to find the absolute value of.\r\n * @returns {number} The absolute value of the number.\r\n */\r\nexport function absolute(n: number): number {\r\n   return Math.abs(n);\r\n}\r\n\r\n/**\r\n * Rounds a number to a specified number of decimal places.\r\n * Supports rounding to negative decimal places (e.g., rounding to the nearest 10 or 100).\r\n * Uses Number.EPSILON to correct binary floating-point representation errors, applied to the\r\n * magnitude so that rounding is symmetric (\"half away from zero\") for both positive and negative\r\n * values. toPrecision(15) cleans up any residual noise in the output.\r\n * @param {number} n The number to round.\r\n * @param {number} decimals The number of decimal places to round to. Can be negative. Defaults to 0.\r\n * @returns {number} The rounded number.\r\n */\r\nexport function round(n: number, decimals: number = 0): number {\r\n   const d = Math.trunc(decimals);\r\n   const factor = power(10, d);\r\n\r\n   // EPSILON is applied to the magnitude and the sign is reapplied afterwards,\r\n   // guaranteeing symmetric \"half away from zero\" rounding on both sides.\r\n   const rounded =\r\n      (Math.sign(n) *\r\n         Math.round(Math.abs(n) * factor + Number.EPSILON * factor)) /\r\n      factor;\r\n\r\n   return Number(rounded.toPrecision(15));\r\n}\r\n\r\n/**\r\n * Returns the largest integer less than or equal to a given number (rounding down).\r\n * @param {number} n The number to apply the floor operation to.\r\n * @returns {number} The largest integer less than or equal to n.\r\n */\r\nexport function floor(n: number): number {\r\n   return Math.floor(n);\r\n}\r\n\r\n/**\r\n * Returns the smallest integer greater than or equal to a given number (rounding up).\r\n * @param {number} n The number to apply the ceil operation to.\r\n * @returns {number} The smallest integer greater than or equal to n.\r\n */\r\nexport function ceil(n: number): number {\r\n   return Math.ceil(n);\r\n}\r\n\r\n/**\r\n * Returns the integer part of a number by removing any fractional digits.\r\n * @param {number} n The number to truncate.\r\n * @returns {number} The integer part of the number.\r\n */\r\nexport function trunc(n: number): number {\r\n   return Math.trunc(n);\r\n}\r\n\r\n/**\r\n * Returns the sign of a number, indicating whether the number is positive, negative, or zero.\r\n * @param {number} n The number to check the sign of.\r\n * @returns {number} -1 if n is negative, 0 if n is zero, 1 if n is positive.\r\n */\r\nexport function sign(n: number): number {\r\n   return Math.sign(n);\r\n}\r\n\r\n/**\r\n * Clamps a number within the inclusive lower and upper bounds.\r\n * If min > max, max takes precedence (Math.min/Math.max semantics) — e.g.,\r\n * clamp(50, 100, 0) returns 0.\r\n * @param {number} value The number to clamp.\r\n * @param {number} min The lower bound.\r\n * @param {number} max The upper bound.\r\n * @returns {number} The clamped number. Returns NaN if any argument is NaN.\r\n */\r\nexport function clamp(value: number, min: number, max: number): number {\r\n   return Math.min(Math.max(value, min), max);\r\n}\r\n\r\n/**\r\n * Performs linear interpolation between two numbers.\r\n * @param {number} a The start point.\r\n * @param {number} b The end point.\r\n * @param {number} t The interpolation factor, typically between 0 and 1.\r\n * @returns {number} The interpolated value.\r\n */\r\nexport function lerp(a: number, b: number, t: number): number {\r\n   return a * (1 - t) + b * t;\r\n}\r\n\r\n/**\r\n * Checks if a number is within a given range (inclusive).\r\n * @param {number} n The number to check.\r\n * @param {number} start The start of the range.\r\n * @param {number} end The end of the range.\r\n * @returns {boolean} `true` if the number is within the range, otherwise `false`.\r\n */\r\nexport function isInRange(n: number, start: number, end: number): boolean {\r\n   return n >= start && n <= end;\r\n}\r\n\r\n/**\r\n * Calculates the mathematical modulo of two numbers.\r\n * This differs from the JavaScript remainder operator (%) in its handling of negative numbers.\r\n * The result will always have the same sign as the divisor.\r\n * @param {number} a The dividend.\r\n * @param {number} b The divisor.\r\n * @returns {number} The result of the modulo operation. Returns NaN if the\r\n *                   divisor is 0.\r\n */\r\nexport function mod(a: number, b: number): number {\r\n   return ((a % b) + b) % b;\r\n}\r\n\r\n/**\r\n * Checks if a number is negative zero (-0).\r\n * @param {number} n The number to check.\r\n * @returns {boolean} `true` if the number is negative zero, otherwise `false`.\r\n */\r\nexport function isNegativeZero(n: number): boolean {\r\n   return n === 0 && 1 / n === -Infinity;\r\n}\r\n\r\n/**\r\n * Checks if two integers are coprime (relatively prime).\r\n * Two numbers are coprime when their only common positive divisor is 1,\r\n * i.e., gcd(a, b) === 1. This is a fundamental concept in number theory,\r\n * used in cryptography (e.g., RSA key generation), modular arithmetic,\r\n * and irreducible fractions.\r\n *\r\n * Note: coprimality is defined on the absolute values, so coprime(-3, 4)\r\n * is true. Since gcd(0, 0) === 0, coprime(0, 0) returns false; and because\r\n * gcd(0, n) === |n|, zero is only coprime with 1 and -1.\r\n *\r\n * @param {number} a The first integer. Floats are truncated.\r\n * @param {number} b The second integer. Floats are truncated.\r\n * @returns {boolean} `true` if a and b are coprime, otherwise `false`.\r\n */\r\nexport function coprime(a: number, b: number): boolean {\r\n   return gcd(a, b) === 1;\r\n}\r\n\r\n/**\r\n * Safely divides one number by another, returning a fallback value instead of\r\n * throwing when the divisor is 0. This is the non-throwing counterpart of divide(),\r\n * useful in data pipelines, statistics, and UI code where a division by zero\r\n * should degrade gracefully instead of interrupting execution.\r\n *\r\n * @param {number} a The dividend.\r\n * @param {number} b The divisor.\r\n * @param {number} fallback The value returned when `b` is 0. Defaults to 0.\r\n * @returns {number} The result of a / b, or `fallback` if b is 0.\r\n */\r\nexport function safeDiv(a: number, b: number, fallback: number = 0): number {\r\n   if (b === 0) {\r\n      return fallback;\r\n   }\r\n   return divide(a, b);\r\n}\r\n\r\n/**\r\n * Returns the number of digits of an integer, ignoring the sign.\r\n * Floats are truncated before counting (e.g., digits(45.9) counts digits(45) = 2).\r\n * Zero has exactly one digit.\r\n *\r\n * Implementation note: counting is done via string conversion of the truncated\r\n * absolute value, which is exact for all safe integers — unlike log10-based\r\n * approaches, which suffer from floating-point edge cases (e.g., log10(1000)\r\n * can evaluate to 2.9999...).\r\n *\r\n * Range note: results are guaranteed only within Number.MAX_SAFE_INTEGER\r\n * (up to 16 digits). For |n| >= 1e21, JavaScript serializes numbers in\r\n * exponential notation (e.g., \"1e+21\"), so the returned count would not\r\n * reflect the actual decimal digits.\r\n *\r\n * @param {number} n The integer to count digits of. Floats are truncated, sign is ignored.\r\n * @returns {number} The number of digits. Returns NaN if `n` is NaN or ±Infinity.\r\n */\r\nexport function digits(n: number): number {\r\n   if (!Number.isFinite(n)) {\r\n      return NaN;\r\n   }\r\n\r\n   return String(Math.abs(Math.trunc(n))).length;\r\n}\r\n\r\n/**\r\n * Calculates the sum of the squares of a set of numbers ($\\sum x_i^2$).\r\n * This is a fundamental building block in statistics (variance, standard\r\n * deviation) and geometry (Euclidean distance, hypotenuse via hypot).\r\n *\r\n * Note: squaring makes every term non-negative, so the result is always >= 0\r\n * for real inputs. Returns 0 if no numbers are provided (empty sum identity,\r\n * consistent with sum()).\r\n *\r\n * @param {...number} numbers A list of numbers to square and sum.\r\n * @returns {number} The sum of the squares. Returns 0 if no numbers are provided.\r\n */\r\nexport function sumOfSquares(...numbers: number[]): number {\r\n   return numbers.reduce((total, current) => total + power(current, 2), 0);\r\n}\r\n\r\n/**\r\n * Returns all positive divisors of an integer, in ascending order.\r\n * The sign is ignored and floats are truncated (e.g., divisors(-12.9) returns\r\n * the divisors of 12). Divisors are found in O(√n) by iterating only up to\r\n * the square root and collecting each divisor pair (i, n/i) at once.\r\n *\r\n * Edge cases: divisors(0) returns [] (every positive integer divides 0, so the\r\n * set is infinite and cannot be enumerated); divisors(1) returns [1].\r\n *\r\n * @param {number} n The integer to find the divisors of. Floats are truncated, sign is ignored.\r\n * @returns {number[]} An array with all positive divisors in ascending order.\r\n *                     Returns [] for 0 and non-finite inputs.\r\n */\r\nexport function divisors(n: number): number[] {\r\n   if (!Number.isFinite(n)) {\r\n      return [];\r\n   }\r\n\r\n   const num = Math.abs(Math.trunc(n));\r\n\r\n   if (num === 0) {\r\n      return [];\r\n   }\r\n\r\n   const small: number[] = [];\r\n   const large: number[] = [];\r\n\r\n   // O(√n): each i <= √num that divides num yields the pair (i, num / i).\r\n   for (let i = 1; i * i <= num; i++) {\r\n      if (num % i === 0) {\r\n         small.push(i);\r\n         const pair = num / i;\r\n         if (pair !== i) {\r\n            large.push(pair); // avoids duplicating the square root of perfect squares\r\n         }\r\n      }\r\n   }\r\n\r\n   // small is ascending; large was collected descending-pair-wise, so reverse it.\r\n   return small.concat(large.reverse());\r\n}\r\n\r\n/**\r\n * Returns the nth Fibonacci number (0-indexed: F(0) = 0, F(1) = 1).\r\n * The sequence is defined by F(n) = F(n-1) + F(n-2).\r\n *\r\n * Implemented iteratively for O(n) time and O(1) space — no recursion,\r\n * so there is no risk of stack overflow for large n.\r\n *\r\n * Precision note: F(78) = 8944394323791464 is the last Fibonacci number that\r\n * fits within Number.MAX_SAFE_INTEGER. From F(79) onward, results are\r\n * approximations due to IEEE-754 limits.\r\n *\r\n * @param {number} n The 0-based index in the Fibonacci sequence. Floats are truncated.\r\n * @returns {number} The nth Fibonacci number. Returns NaN for negative or non-finite inputs.\r\n */\r\nexport function fibonacci(n: number): number {\r\n   if (!Number.isFinite(n)) {\r\n      return NaN;\r\n   }\r\n\r\n   const num = Math.trunc(n);\r\n\r\n   if (num < 0) {\r\n      return NaN;\r\n   }\r\n\r\n   if (num === 0) {\r\n      return 0;\r\n   }\r\n\r\n   let prev = 0;\r\n   let curr = 1;\r\n\r\n   for (let i = 2; i <= num; i++) {\r\n      // Same temp-variable pattern as gcd: avoids array destructuring allocations.\r\n      const next = prev + curr;\r\n      prev = curr;\r\n      curr = next;\r\n   }\r\n\r\n   return curr;\r\n}\r\n\r\n/**\r\n * Performs the inverse of linear interpolation: given a value, returns the\r\n * interpolation factor `t` such that lerp(a, b, t) === value.\r\n * For value === a returns 0; for value === b returns 1; values outside [a, b]\r\n * extrapolate to t < 0 or t > 1 (mirroring lerp's extrapolation behavior).\r\n *\r\n * This is the foundation of mapRange and of any normalization of a value\r\n * within a known interval (progress bars, gradients, sensor calibration).\r\n *\r\n * Edge case: when a === b the interval is degenerate (zero length), so no\r\n * meaningful t exists — returns NaN rather than an arbitrary value.\r\n *\r\n * @param {number} a The start of the range.\r\n * @param {number} b The end of the range.\r\n * @param {number} value The value to find the interpolation factor of.\r\n * @returns {number} The factor t such that lerp(a, b, t) === value. Returns NaN if a === b.\r\n */\r\nexport function inverseLerp(a: number, b: number, value: number): number {\r\n   if (a === b) {\r\n      return NaN;\r\n   }\r\n\r\n   return (value - a) / (b - a);\r\n}\r\n\r\n/**\r\n * Finds the Greatest Common Divisor (GCD) of any quantity of integers.\r\n * Built on top of gcd() via reduction, leveraging the associativity of the\r\n * GCD operation: gcd(a, b, c) === gcd(gcd(a, b), c).\r\n *\r\n * Floats are truncated and signs are ignored (inherited from gcd).\r\n * Early exit: if the running GCD reaches 1, no further number can change it,\r\n * so the reduction stops immediately (1 is the absorbing element).\r\n *\r\n * @param {...number} numbers The integers to find the GCD of.\r\n * @returns {number} The GCD of all numbers. Returns 0 if no numbers are\r\n *                   provided (identity element: gcd(0, x) === x) or NaN if\r\n *                   any input is non-finite.\r\n */\r\nexport function gcdMultiple(...numbers: number[]): number {\r\n   if (numbers.some((n) => !Number.isFinite(n))) {\r\n      return NaN;\r\n   }\r\n\r\n   let result = 0; // identity: gcd(0, x) === x\r\n\r\n   for (const n of numbers) {\r\n      result = gcd(result, n);\r\n\r\n      // 1 is absorbing: gcd(1, anything) === 1 — no point continuing.\r\n      if (result === 1) {\r\n         return 1;\r\n      }\r\n   }\r\n\r\n   return result;\r\n}\r\n\r\n/**\r\n * Finds the Least Common Multiple (LCM) of any quantity of integers.\r\n * Built on top of lcm() via reduction, leveraging the associativity of the\r\n * LCM operation: lcm(a, b, c) === lcm(lcm(a, b), c).\r\n *\r\n * Floats are truncated and signs are ignored (inherited from lcm).\r\n * Early exit: if any number is 0, the LCM is immediately 0 (0 is the\r\n * absorbing element of LCM, mirroring how 1 absorbs in gcdMultiple).\r\n *\r\n * Precision note: the LCM grows multiplicatively, so results for many\r\n * pairwise-coprime numbers can exceed Number.MAX_SAFE_INTEGER and lose\r\n * exactness — e.g., lcmMultiple of the primes up to 53 already overflows.\r\n *\r\n * @param {...number} numbers The integers to find the LCM of.\r\n * @returns {number} The LCM of all numbers. Returns 1 if no numbers are\r\n *                   provided (identity element: lcm(1, x) === x), 0 if any\r\n *                   number is 0, or NaN if any input is non-finite.\r\n */\r\nexport function lcmMultiple(...numbers: number[]): number {\r\n   if (numbers.some((n) => !Number.isFinite(n))) {\r\n      return NaN;\r\n   }\r\n\r\n   let result = 1; // identity: lcm(1, x) === x\r\n\r\n   for (const n of numbers) {\r\n      result = lcm(result, n);\r\n\r\n      // 0 is absorbing: lcm(0, anything) === 0 — no point continuing.\r\n      if (result === 0) {\r\n         return 0;\r\n      }\r\n   }\r\n\r\n   return result;\r\n}\r\n\r\n/**\r\n * Calculates (base ^ exponent) % modulus efficiently using the\r\n * square-and-multiply algorithm (binary exponentiation), reducing modulo at\r\n * every step. This computes modular exponentiation in O(log exponent)\r\n * multiplications WITHOUT ever materializing base^exponent — power(base, exp)\r\n * would overflow Number.MAX_SAFE_INTEGER almost immediately, while modPow\r\n * keeps every intermediate value below modulus².\r\n *\r\n * This is the core primitive of modular arithmetic in cryptography\r\n * (RSA encryption/decryption, Diffie-Hellman key exchange, primality tests).\r\n *\r\n * Safety limit: intermediate products reach (modulus - 1)², so results are\r\n * only exact while modulus <= 94906265 (√MAX_SAFE_INTEGER). Larger moduli\r\n * would require BigInt.\r\n *\r\n * The result is always non-negative (uses mod(), so negative bases are\r\n * normalized: modPow(-2, 3, 5) === mod(-8, 5) === 2).\r\n *\r\n * @param {number} base The base. Floats are truncated.\r\n * @param {number} exponent The exponent. Must be a non-negative integer. Floats are truncated.\r\n * @param {number} modulus The modulus. Must be a positive integer. Floats are truncated.\r\n * @returns {number} (base ^ exponent) % modulus, in the range [0, modulus).\r\n *                   Returns NaN for non-finite inputs, negative exponents,\r\n *                   modulus <= 0, or modulus > 94906265.\r\n */\r\nexport function modPow(\r\n   base: number,\r\n   exponent: number,\r\n   modulus: number,\r\n): number {\r\n   if (\r\n      !Number.isFinite(base) ||\r\n      !Number.isFinite(exponent) ||\r\n      !Number.isFinite(modulus)\r\n   ) {\r\n      return NaN;\r\n   }\r\n\r\n   let b = Math.trunc(base);\r\n   let e = Math.trunc(exponent);\r\n   const m = Math.trunc(modulus);\r\n\r\n   // Negative exponents would require modular inverse (modInverse, Fase 2).\r\n   if (e < 0) {\r\n      return NaN;\r\n   }\r\n\r\n   // Modulus must be positive, and (m - 1)² must stay within MAX_SAFE_INTEGER.\r\n   if (m <= 0 || m > 94906265) {\r\n      return NaN;\r\n   }\r\n\r\n   // Anything mod 1 is 0.\r\n   if (m === 1) {\r\n      return 0;\r\n   }\r\n\r\n   // Normalize the base into [0, m) — handles negative bases correctly.\r\n   b = mod(b, m);\r\n\r\n   let result = 1;\r\n\r\n   // Square-and-multiply: consume the exponent bit by bit.\r\n   while (e > 0) {\r\n      // If the current lowest bit is 1, multiply the result by the current base.\r\n      if (e % 2 === 1) {\r\n         result = (result * b) % m;\r\n      }\r\n\r\n      // Square the base and move to the next bit.\r\n      b = (b * b) % m;\r\n      e = Math.trunc(e / 2);\r\n   }\r\n\r\n   return result;\r\n}\r\n\r\n/**\r\n * Calculates what percentage `value` represents of `total`.\r\n * Example: percentOf(25, 200) === 12.5 (25 is 12.5% of 200).\r\n *\r\n * @param {number} value The partial value.\r\n * @param {number} total The total (reference) value. Must not be 0.\r\n * @returns {number} The percentage of `total` that `value` represents.\r\n * @throws {Error} If `total` is 0 (inherited from divide).\r\n */\r\nexport function percentOf(value: number, total: number): number {\r\n   return multiply(divide(value, total), 100);\r\n}\r\n\r\n/**\r\n * Calculates the value that corresponds to a given percentage of a total.\r\n * This is the inverse of percentOf. Example: fromPercent(12.5, 200) === 25\r\n * (12.5% of 200 is 25).\r\n *\r\n * @param {number} percent The percentage to apply.\r\n * @param {number} total The total (reference) value.\r\n * @returns {number} The value corresponding to `percent` of `total`.\r\n */\r\nexport function fromPercent(percent: number, total: number): number {\r\n   return multiply(divide(percent, 100), total);\r\n}\r\n\r\n/**\r\n * Calculates the sum of the decimal digits of an integer, ignoring the sign.\r\n * Floats are truncated before summing (e.g., sumOfDigits(45.9) sums 4 + 5 = 9).\r\n * Example: sumOfDigits(12345) = 1 + 2 + 3 + 4 + 5 = 15.\r\n *\r\n * This is the building block of digital roots, checksum algorithms, and\r\n * divisibility rules (a number is divisible by 3 or 9 iff its digit sum is).\r\n *\r\n * Range note: like digits(), results are guaranteed only within\r\n * Number.MAX_SAFE_INTEGER, since the implementation iterates over the\r\n * decimal string representation of the truncated absolute value.\r\n *\r\n * @param {number} n The integer to sum the digits of. Floats are truncated, sign is ignored.\r\n * @returns {number} The sum of the decimal digits. Returns NaN if `n` is NaN or ±Infinity.\r\n */\r\nexport function sumOfDigits(n: number): number {\r\n   if (!Number.isFinite(n)) {\r\n      return NaN;\r\n   }\r\n\r\n   const str = String(Math.abs(Math.trunc(n)));\r\n\r\n   let total = 0;\r\n   for (let i = 0; i < str.length; i++) {\r\n      total += str.charCodeAt(i) - 48; // '0' is charCode 48 — avoids per-digit Number() parsing\r\n   }\r\n\r\n   return total;\r\n}\r\n\r\n/**\r\n * Checks if a number is a perfect square — an integer that is the square of\r\n * another integer (e.g., 36 = 6²).\r\n *\r\n * The check uses Math.sqrt followed by an exact integer verification: the\r\n * rounded candidate root is squared back and compared to the original number,\r\n * eliminating any floating-point imprecision from the square root itself.\r\n *\r\n * Edge cases: 0 is a perfect square (0²); negative numbers never are;\r\n * floats are NOT truncated — 36.5 is not a perfect square, even though\r\n * trunc(36.5) would be. Only true integers can be perfect squares.\r\n *\r\n * @param {number} n The number to check.\r\n * @returns {boolean} `true` if n is a perfect square, otherwise `false`.\r\n *                    Returns `false` for negatives, non-integers, and non-finite inputs.\r\n */\r\nexport function isPerfectSquare(n: number): boolean {\r\n   if (!Number.isFinite(n) || n < 0 || !Number.isInteger(n)) {\r\n      return false;\r\n   }\r\n\r\n   const root = Math.round(sqrt(n));\r\n\r\n   // Verify by squaring back — immune to sqrt's floating-point noise.\r\n   return root * root === n;\r\n}\r\n\r\n/**\r\n * Calculates the Euclidean norm — the square root of the sum of the squares\r\n * of the arguments ($\\sqrt{x_1^2 + x_2^2 + \\dots}$).\r\n *\r\n * For two arguments this is the hypotenuse of a right triangle (Pythagorean\r\n * theorem); for any quantity it is the Euclidean distance from the origin in\r\n * n-dimensional space — the foundation of distance calculations, vector\r\n * magnitudes, and physics simulations.\r\n *\r\n * Built on sumOfSquares() and sqrt() for full internal consistency.\r\n *\r\n * Precision note: unlike Math.hypot, this implementation can overflow to\r\n * Infinity for inputs whose squares exceed Number.MAX_VALUE (around 1e154).\r\n * For everyday magnitudes the results are equivalent.\r\n *\r\n * @param {...number} numbers The components (e.g., the legs of a triangle, vector coordinates).\r\n * @returns {number} The Euclidean norm. Returns 0 if no numbers are provided.\r\n */\r\nexport function hypot(...numbers: number[]): number {\r\n   return sqrt(sumOfSquares(...numbers));\r\n}\r\n\r\n/**\r\n * Performs a linear interpolation with `t` clamped to the [0, 1] range —\r\n * the result is guaranteed to stay between `a` and `b`.\r\n *\r\n * Standard lerp() extrapolates beyond the endpoints when t is outside [0, 1]\r\n * (by design). clampedLerp() locks the result inside the segment, which is\r\n * what UI animations, progress bars, color blending, and game movement\r\n * almost always want: lerp that never overshoots.\r\n *\r\n * Built on clamp() and lerp() for full internal consistency.\r\n *\r\n * @param {number} a The start value (returned when t <= 0).\r\n * @param {number} b The end value (returned when t >= 1).\r\n * @param {number} t The interpolation factor, clamped to [0, 1] before interpolating.\r\n * @returns {number} The interpolated value, always within [min(a,b), max(a,b)].\r\n */\r\nexport function clampedLerp(a: number, b: number, t: number): number {\r\n   return lerp(a, b, clamp(t, 0, 1));\r\n}\r\n\r\n/**\r\n * Maps a value from one range to another, preserving its relative position —\r\n * e.g., 5 in [0, 10] maps to 50 in [0, 100].\r\n *\r\n * This is the famous map() from Arduino/Processing: the workhorse of sensor\r\n * readings, coordinate conversions, audio normalization, and data\r\n * visualization scales.\r\n *\r\n * Built as the composition of the two interpolation primitives:\r\n * inverseLerp() extracts the relative position t from the input range, and\r\n * lerp() applies that t to the output range.\r\n *\r\n * Note: like lerp(), values outside the input range extrapolate\r\n * proportionally (no clamping). Degenerate input range (inMin === inMax)\r\n * returns NaN, propagated from inverseLerp().\r\n *\r\n * @param {number} value The value to remap.\r\n * @param {number} inMin The lower bound of the source range.\r\n * @param {number} inMax The upper bound of the source range.\r\n * @param {number} outMin The lower bound of the target range.\r\n * @param {number} outMax The upper bound of the target range.\r\n * @returns {number} The value remapped to the target range. Returns NaN if the input range is degenerate.\r\n */\r\nexport function mapRange(\r\n   value: number,\r\n   inMin: number,\r\n   inMax: number,\r\n   outMin: number,\r\n   outMax: number,\r\n): number {\r\n   return lerp(outMin, outMax, inverseLerp(inMin, inMax, value));\r\n}\r\n\r\n/**\r\n * Checks if a number is a perfect number — a positive integer that equals\r\n * the sum of its proper divisors (all divisors except itself).\r\n * Example: 28 = 1 + 2 + 4 + 7 + 14.\r\n *\r\n * Perfect numbers have fascinated mathematicians since Euclid: only 52 are\r\n * known to exist, they grow astronomically fast (the 5th is 33,550,336),\r\n * and every known one is even — whether odd perfect numbers exist remains\r\n * one of the oldest unsolved problems in mathematics.\r\n *\r\n * Built on divisors() and sum() for full internal consistency.\r\n *\r\n * Performance note: inherits the O(√n) divisor enumeration from divisors().\r\n * Fine for any realistic input — only 8 perfect numbers fit in the safe\r\n * integer range anyway.\r\n *\r\n * @param {number} n The number to check.\r\n * @returns {boolean} `true` if n is a perfect number, otherwise `false`.\r\n *                    Returns `false` for n < 2, non-integers, and non-finite inputs.\r\n */\r\nexport function isPerfectNumber(n: number): boolean {\r\n   if (!Number.isFinite(n) || n < 2 || !Number.isInteger(n)) {\r\n      return false;\r\n   }\r\n\r\n   const properDivisors = divisors(n);\r\n   properDivisors.pop(); // remove the number itself (always the last element)\r\n\r\n   return sum(...properDivisors) === n;\r\n}\r\n\r\n/**\r\n * Decomposes a positive integer into its prime factorization, returning the\r\n * prime factors in ascending order with repetition.\r\n * Example: primeFactors(60) = [2, 2, 3, 5] (60 = 2² × 3 × 5).\r\n *\r\n * By the Fundamental Theorem of Arithmetic, this decomposition exists and is\r\n * unique for every integer >= 2 — making it the DNA of a number. It powers\r\n * Euler's totient, radical/squarefree analysis, and fraction simplification.\r\n *\r\n * Algorithm: trial division by 2, then odd candidates up to √remainder —\r\n * the same i*i <= n hardening used in isPrime(). Whatever remains > 1 at the\r\n * end is itself prime (the largest prime factor).\r\n *\r\n * @param {number} n The integer to factorize. Floats are truncated.\r\n * @returns {number[]} The prime factors in ascending order, with multiplicity.\r\n *                     Returns [] for n < 2, NaN, and ±Infinity.\r\n */\r\nexport function primeFactors(n: number): number[] {\r\n   if (!Number.isFinite(n)) {\r\n      return [];\r\n   }\r\n\r\n   let remainder = Math.trunc(n);\r\n\r\n   if (remainder < 2) {\r\n      return [];\r\n   }\r\n\r\n   const factors: number[] = [];\r\n\r\n   // Extract all factors of 2 first, so the main loop can skip evens.\r\n   while (remainder % 2 === 0) {\r\n      factors.push(2);\r\n      remainder = remainder / 2;\r\n   }\r\n\r\n   // Trial division by odd candidates up to √remainder.\r\n   for (let i = 3; i * i <= remainder; i += 2) {\r\n      while (remainder % i === 0) {\r\n         factors.push(i);\r\n         remainder = remainder / i;\r\n      }\r\n   }\r\n\r\n   // Whatever survived is itself a prime (the largest factor).\r\n   if (remainder > 1) {\r\n      factors.push(remainder);\r\n   }\r\n\r\n   return factors;\r\n}\r\n\r\n/**\r\n * Multiplies an arbitrary quantity of numbers together, reducing them with\r\n * multiply(). The variadic sibling of sum() for products.\r\n * Example: multiplyMultiple(2, 3, 4) = 24.\r\n *\r\n * Called with no arguments it returns 1 — the empty product, the\r\n * multiplicative identity (the same convention that makes factorial(0) = 1\r\n * and primeFactors(1) = [] mutually consistent).\r\n *\r\n * Includes an early exit: if any factor is 0, the result is 0 immediately\r\n * (mirroring the optimization in lcmMultiple()).\r\n *\r\n * @param {...number} numbers The factors to multiply.\r\n * @returns {number} The product of all numbers. Returns 1 if no numbers are provided.\r\n */\r\nexport function multiplyMultiple(...numbers: number[]): number {\r\n   if (numbers.includes(0)) {\r\n      return 0;\r\n   }\r\n\r\n   return numbers.reduce((acc, current) => multiply(acc, current), 1);\r\n}\r\n\r\n/**\r\n * Calculates the binomial coefficient C(n, k) — \"n choose k\" — the number of\r\n * ways to choose k elements from a set of n, ignoring order.\r\n * Example: binomial(5, 2) = 10 (ten possible pairs out of five items).\r\n *\r\n * This is the engine of combinatorics: Pascal's triangle, probability\r\n * distributions, polynomial expansion (binomial theorem), and lottery odds.\r\n *\r\n * Algorithm: multiplicative formula with progressive cancellation —\r\n * result = result × (n - k + i) / i, iterating i from 1 to k. Each\r\n * intermediate value is itself a smaller binomial coefficient (and therefore\r\n * an integer), which keeps precision exact FAR beyond what factorial(n)/\r\n * (factorial(k) × factorial(n-k)) could reach: that formula dies at n = 18\r\n * (factorial overflow), while this one handles C(60, 30) exactly.\r\n *\r\n * Symmetry shortcut: k is replaced by min(k, n - k), halving the loop.\r\n *\r\n * @param {number} n The size of the set. Floats are truncated.\r\n * @param {number} k The number of elements to choose. Floats are truncated.\r\n * @returns {number} The binomial coefficient C(n, k). Returns 0 when k < 0 or\r\n *                   k > n (no ways to choose). Returns NaN for non-finite inputs or n < 0.\r\n */\r\nexport function binomial(n: number, k: number): number {\r\n   if (!Number.isFinite(n) || !Number.isFinite(k)) {\r\n      return NaN;\r\n   }\r\n\r\n   const numN = Math.trunc(n);\r\n   let numK = Math.trunc(k);\r\n\r\n   if (numN < 0) {\r\n      return NaN;\r\n   }\r\n\r\n   if (numK < 0 || numK > numN) {\r\n      return 0;\r\n   }\r\n\r\n   // Symmetry: C(n, k) === C(n, n - k) — always walk the shorter side.\r\n   if (numK > numN - numK) {\r\n      numK = numN - numK;\r\n   }\r\n\r\n   let result = 1;\r\n\r\n   // Progressive cancellation: each step yields C(n - k + i, i), an integer.\r\n   for (let i = 1; i <= numK; i++) {\r\n      result = (result * (numN - numK + i)) / i;\r\n   }\r\n\r\n   return result;\r\n}\r\n\r\n/**\r\n * Calculates the modular multiplicative inverse of `a` modulo `m` — the\r\n * number x in [1, m) such that (a × x) mod m = 1.\r\n * Example: modInverse(3, 7) = 5, because 3 × 5 = 15 and 15 mod 7 = 1.\r\n *\r\n * This is division's stand-in in modular arithmetic (where true division\r\n * does not exist): multiplying by modInverse(a, m) \"undoes\" multiplying\r\n * by a. It is the heart of RSA key generation — the private exponent d is\r\n * literally modInverse(e, totient(n)) — and of hash functions and CRT.\r\n *\r\n * Algorithm: iterative extended Euclidean algorithm, tracking only the\r\n * Bézout coefficient of `a` (O(log m), no recursion). The inverse exists\r\n * if and only if gcd(a, m) = 1 (a and m coprime); otherwise returns NaN.\r\n *\r\n * Inputs are truncated and `a` is normalized with mod() first, so negative\r\n * `a` works naturally: modInverse(-4, 7) === modInverse(3, 7).\r\n *\r\n * @param {number} a The number to invert. Floats are truncated, negatives normalized.\r\n * @param {number} m The modulus. Floats are truncated. Must be >= 2.\r\n * @returns {number} The modular inverse in [1, m). Returns NaN if it does not\r\n *                   exist (gcd(a, m) !== 1), if m < 2, or for non-finite inputs.\r\n */\r\nexport function modInverse(a: number, m: number): number {\r\n   if (!Number.isFinite(a) || !Number.isFinite(m)) {\r\n      return NaN;\r\n   }\r\n\r\n   const modulus = Math.trunc(m);\r\n\r\n   if (modulus < 2) {\r\n      return NaN;\r\n   }\r\n\r\n   // Normalize a into [0, modulus) — handles negatives via our mod().\r\n   let remainder = mod(Math.trunc(a), modulus);\r\n   let prevRemainder = modulus;\r\n\r\n   // Bézout coefficients of `a` (we only need this column).\r\n   let coef = 1;\r\n   let prevCoef = 0;\r\n\r\n   while (remainder !== 0) {\r\n      const quotient = Math.trunc(prevRemainder / remainder);\r\n\r\n      const tempRemainder = prevRemainder - quotient * remainder;\r\n      prevRemainder = remainder;\r\n      remainder = tempRemainder;\r\n\r\n      const tempCoef = prevCoef - quotient * coef;\r\n      prevCoef = coef;\r\n      coef = tempCoef;\r\n   }\r\n\r\n   // prevRemainder now holds gcd(a, m): inverse exists only if it's 1.\r\n   if (prevRemainder !== 1) {\r\n      return NaN;\r\n   }\r\n\r\n   return mod(prevCoef, modulus);\r\n}\r\n\r\n/**\r\n * Calculates the number of permutations P(n, k) — the number of ways to\r\n * arrange k elements chosen from a set of n, where ORDER MATTERS.\r\n * Example: permutations(5, 2) = 20 (podium positions, passwords, rankings).\r\n *\r\n * The contrast with binomial(): C(n, k) counts subsets (order ignored),\r\n * P(n, k) counts arrangements. They relate by P(n, k) = C(n, k) × k! —\r\n * every subset of k elements can be arranged in k! different orders.\r\n *\r\n * Algorithm: direct falling factorial n × (n-1) × ... × (n-k+1), computed\r\n * iteratively. Like binomial(), this avoids the factorial-quotient formula\r\n * (which would overflow at n = 19) — every intermediate value here is an\r\n * exact integer until the result itself exceeds MAX_SAFE_INTEGER.\r\n *\r\n * @param {number} n The size of the set. Floats are truncated.\r\n * @param {number} k The number of elements to arrange. Floats are truncated.\r\n * @returns {number} The number of permutations P(n, k). Returns 0 when k < 0\r\n *                   or k > n. Returns NaN for non-finite inputs or n < 0.\r\n */\r\nexport function permutations(n: number, k: number): number {\r\n   if (!Number.isFinite(n) || !Number.isFinite(k)) {\r\n      return NaN;\r\n   }\r\n\r\n   const numN = Math.trunc(n);\r\n   const numK = Math.trunc(k);\r\n\r\n   if (numN < 0) {\r\n      return NaN;\r\n   }\r\n\r\n   if (numK < 0 || numK > numN) {\r\n      return 0;\r\n   }\r\n\r\n   let result = 1;\r\n\r\n   // Falling factorial: n × (n-1) × ... × (n-k+1)\r\n   for (let i = 0; i < numK; i++) {\r\n      result = result * (numN - i);\r\n   }\r\n\r\n   return result;\r\n}\r\n\r\n/**\r\n * Calculates Euler's totient φ(n) — the count of integers in [1, n] that\r\n * are coprime with n.\r\n * Example: totient(9) = 6, because 1, 2, 4, 5, 7, 8 share no factor with 9.\r\n *\r\n * The totient is the backbone of modular arithmetic: it gives the size of\r\n * the multiplicative group mod n, powers Euler's theorem\r\n * (a^φ(n) ≡ 1 mod n for coprime a — the generalization of Fermat's little\r\n * theorem), and defines the RSA private key: d = modInverse(e, φ(n)).\r\n *\r\n * Algorithm: Euler's product formula φ(n) = n × Π(1 - 1/p) over the\r\n * distinct prime factors p of n, computed as n × (p - 1) / p per unique\r\n * prime. Every intermediate division is exact (p always divides the\r\n * accumulated value), so the result stays integer-precise throughout.\r\n * Built on primeFactors() for full internal consistency.\r\n *\r\n * @param {number} n The number to evaluate. Floats are truncated.\r\n * @returns {number} φ(n), the count of coprimes with n in [1, n].\r\n *                   Returns 1 for n = 1 (by convention), and NaN for n < 1\r\n *                   or non-finite inputs.\r\n */\r\nexport function totient(n: number): number {\r\n   if (!Number.isFinite(n)) {\r\n      return NaN;\r\n   }\r\n\r\n   const num = Math.trunc(n);\r\n\r\n   if (num < 1) {\r\n      return NaN;\r\n   }\r\n\r\n   if (num === 1) {\r\n      return 1;\r\n   }\r\n\r\n   let result = num;\r\n   let previousPrime = 0;\r\n\r\n   // Euler's product over DISTINCT primes: φ = n × Π (p - 1) / p.\r\n   // primeFactors() returns sorted factors, so repeats are adjacent.\r\n   for (const p of primeFactors(num)) {\r\n      if (p !== previousPrime) {\r\n         result = (result / p) * (p - 1);\r\n         previousPrime = p;\r\n      }\r\n   }\r\n\r\n   return result;\r\n}\r\n\r\n/**\r\n * Calculates the median — the middle value of a sorted dataset, the point\r\n * that splits it into two equal halves.\r\n * Example: median(1, 3, 2) = 2; median(1, 2, 3, 4) = 2.5.\r\n *\r\n * Unlike the mean, the median is robust to outliers: median(1, 2, 3, 1000)\r\n * is 2.5, not 251.5 — which is why income, house prices, and response times\r\n * are reported as medians. Mean and median together reveal skewness.\r\n *\r\n * Algorithm: numeric sort on a copy (the input is never mutated), then the\r\n * middle element (odd count) or the mean of the two middle elements (even\r\n * count).\r\n *\r\n * @param {...number} numbers The dataset (order irrelevant).\r\n * @returns {number} The median value. Returns NaN if called with no numbers\r\n *                   or if any value is NaN.\r\n */\r\nexport function median(...numbers: number[]): number {\r\n   if (numbers.length === 0) {\r\n      return NaN;\r\n   }\r\n\r\n   if (numbers.some((n) => Number.isNaN(n))) {\r\n      return NaN;\r\n   }\r\n\r\n   // Numeric sort on a COPY — never mutate the caller's data.\r\n   const sorted = [...numbers].sort((a, b) => a - b);\r\n\r\n   const middle = Math.trunc(sorted.length / 2);\r\n\r\n   if (isOdd(sorted.length)) {\r\n      return sorted[middle];\r\n   }\r\n\r\n   return divide(sum(sorted[middle - 1], sorted[middle]), 2);\r\n}\r\n\r\n/**\r\n * Returns the smallest of the provided numbers.\r\n * Example: min(3, 1, 4) = 1.\r\n *\r\n * Unlike Math.min (which returns Infinity for no arguments — a surprising\r\n * identity value), this returns NaN when called with no numbers, treating\r\n * \"the minimum of nothing\" as undefined — consistent with mean() and\r\n * median() in this library.\r\n *\r\n * @param {...number} numbers The numbers to compare.\r\n * @returns {number} The smallest value. Returns NaN if called with no\r\n *                   numbers or if any value is NaN.\r\n */\r\nexport function min(...numbers: number[]): number {\r\n   if (numbers.length === 0) {\r\n      return NaN;\r\n   }\r\n\r\n   return Math.min(...numbers);\r\n}\r\n\r\n/**\r\n * Returns the largest of the provided numbers.\r\n * Example: max(3, 1, 4) = 4.\r\n *\r\n * Unlike Math.max (which returns -Infinity for no arguments — a surprising\r\n * identity value), this returns NaN when called with no numbers, treating\r\n * \"the maximum of nothing\" as undefined — consistent with mean() and\r\n * median() in this library.\r\n *\r\n * @param {...number} numbers The numbers to compare.\r\n * @returns {number} The largest value. Returns NaN if called with no\r\n *                   numbers or if any value is NaN.\r\n */\r\nexport function max(...numbers: number[]): number {\r\n   if (numbers.length === 0) {\r\n      return NaN;\r\n   }\r\n\r\n   return Math.max(...numbers);\r\n}\r\n\r\n/**\r\n * Calculates the population variance σ² — the mean of the squared\r\n * deviations from the mean, measuring how spread out a dataset is.\r\n * Example: variance(2, 4, 4, 4, 5, 5, 7, 9) = 4.\r\n *\r\n * Zero variance means all values are identical; larger variance means\r\n * wider dispersion. Variance is the foundation of standard deviation,\r\n * z-scores, regression, and virtually all of statistics.\r\n *\r\n * This is the POPULATION variance (divides by n), treating the input as\r\n * the complete dataset. For SAMPLE variance (divides by n - 1, Bessel's\r\n * correction for estimating from a sample), multiply the result by\r\n * n / (n - 1).\r\n *\r\n * Algorithm: two-pass — first the mean, then sumOfSquares of the\r\n * deviations, divided by n. The two-pass approach is numerically stabler\r\n * than the one-pass E[X²] - E[X]² formula, which suffers catastrophic\r\n * cancellation for large values with small spread.\r\n * Built on mean(), sumOfSquares(), and divide().\r\n *\r\n * @param {...number} numbers The complete dataset (population).\r\n * @returns {number} The population variance σ². Returns NaN if called with\r\n *                   no numbers or if any value is NaN.\r\n */\r\nexport function variance(...numbers: number[]): number {\r\n   if (numbers.length === 0) {\r\n      return NaN;\r\n   }\r\n\r\n   const avg = mean(...numbers);\r\n   const deviations = numbers.map((n) => n - avg);\r\n\r\n   return divide(sumOfSquares(...deviations), numbers.length);\r\n}\r\n\r\n/**\r\n * Calculates the population standard deviation σ — the square root of the\r\n * variance, measuring dispersion in the SAME UNIT as the data.\r\n * Example: standardDeviation(2, 4, 4, 4, 5, 5, 7, 9) = 2.\r\n *\r\n * This is variance made interpretable: if heights are in centimeters, σ is\r\n * in centimeters too (variance would be in cm², which nobody can picture).\r\n * It powers the 68-95-99.7 rule, z-scores, error bars, and volatility.\r\n *\r\n * Population flavor (divides by n), inherited directly from variance().\r\n * For the sample version, multiply variance by n/(n-1) before the root.\r\n *\r\n * Built as sqrt(variance(...)) — pure composition.\r\n *\r\n * @param {...number} numbers The complete dataset (population).\r\n * @returns {number} The population standard deviation σ. Returns NaN if\r\n *                   called with no numbers or if any value is NaN.\r\n */\r\nexport function standardDeviation(...numbers: number[]): number {\r\n   return sqrt(variance(...numbers));\r\n}\r\n\r\n/**\r\n * Finds the mode — the value(s) that appear most frequently in a dataset.\r\n * Example: mode(1, 2, 2, 3) = [2]; mode(1, 1, 2, 2, 3) = [1, 2].\r\n *\r\n * The third pillar of central tendency (with mean and median), and the only\r\n * one defined for ANY data — it needs counting, not arithmetic. It is also\r\n * the only one that can be plural: bimodal and multimodal datasets are\r\n * common (and statistically meaningful), so this returns an ARRAY.\r\n *\r\n * Returns ALL tied values in ascending order. When every value appears the\r\n * same number of times (e.g., all distinct), every value is technically a\r\n * mode — the array simply contains them all, sorted.\r\n *\r\n * Counting uses a Map keyed by the numeric value itself, so 2 and 2.0\r\n * collapse (same number in JS) while 0 and -0 also collapse (Map treats\r\n * them as the same key — SameValueZero).\r\n *\r\n * @param {...number} numbers The dataset (order irrelevant).\r\n * @returns {number[]} The most frequent value(s), sorted ascending.\r\n *                     Returns [] if called with no numbers or if any value is NaN.\r\n */\r\nexport function mode(...numbers: number[]): number[] {\r\n   if (numbers.length === 0) {\r\n      return [];\r\n   }\r\n\r\n   if (numbers.some((n) => Number.isNaN(n))) {\r\n      return [];\r\n   }\r\n\r\n   const counts = new Map<number, number>();\r\n   let highest = 0;\r\n\r\n   for (const n of numbers) {\r\n      const count = (counts.get(n) ?? 0) + 1;\r\n      counts.set(n, count);\r\n\r\n      if (count > highest) {\r\n         highest = count;\r\n      }\r\n   }\r\n\r\n   const modes: number[] = [];\r\n   for (const [value, count] of counts) {\r\n      if (count === highest) {\r\n         modes.push(value);\r\n      }\r\n   }\r\n\r\n   return modes.sort((a, b) => a - b);\r\n}\r\n\r\n/**\r\n * Returns the running totals (partial sums) of a sequence of numbers.\r\n * Equivalent to numpy's cumsum: each element i is the sum of all\r\n * inputs from index 0 up to i.\r\n *\r\n * Example: cumulativeSum(1, 2, 3, 4) returns [1, 3, 6, 10].\r\n *\r\n * Useful for time series (accumulated balances, running scores),\r\n * prefix-sum algorithms, and converting deltas into absolute values.\r\n *\r\n * Algorithm note: single O(n) pass with an accumulator (conceptually\r\n * repeated sum, but without calling sum() per element, which would\r\n * be O(n²)).\r\n *\r\n * Precision note: partial sums are exact within the safe integer\r\n * zone (|sum| < 2^53). With binary fractions (0.1, 0.7...) the usual\r\n * float drift applies — compare with tolerance in that range.\r\n *\r\n * @param {...number} numbers - Sequence of numbers (variadic).\r\n *     Floats and negatives are accepted as-is (no truncation).\r\n * @returns {number[]} Array of partial sums, same length as the\r\n *     input. Empty call returns [] (no data, no totals). Non-finite\r\n *     values propagate honestly through JS arithmetic: from the\r\n *     first NaN onward every total is NaN; an Infinity turns the\r\n *     following totals into Infinity (and Infinity + -Infinity\r\n *     yields NaN).\r\n */\r\nexport function cumulativeSum(...numbers: number[]): number[] {\r\n   const result: number[] = [];\r\n   let acc = 0;\r\n\r\n   for (const n of numbers) {\r\n      acc += n;\r\n      result.push(acc);\r\n   }\r\n\r\n   return result;\r\n}\r\n\r\n/**\r\n * Applies a dead zone to a normalized axis value with continuous\r\n * rescaling: inputs whose magnitude is at or below the threshold\r\n * collapse to 0, and the remaining range is linearly remapped so\r\n * the output still spans the full [-1, 1] — with NO jump at the\r\n * threshold edge.\r\n *\r\n * Example: deadzone(0.05, 0.1) returns 0 (inside the dead zone);\r\n * deadzone(0.55, 0.1) returns 0.5; deadzone(1, 0.1) returns 1;\r\n * deadzone(-0.55, 0.1) returns -0.5 (symmetric by sign).\r\n *\r\n * Useful for joystick/gamepad drift filtering, robotics control\r\n * sticks and analog sensor noise gates. The naive approach (just\r\n * zeroing below the threshold) creates a discontinuity: the output\r\n * jumps from 0 to ~threshold as soon as the stick leaves the zone.\r\n * This implementation rescales sign(v) × (|v| − t) / (1 − t), which\r\n * is continuous at the edge and preserves full output range.\r\n *\r\n * Algorithm note: dogfooding with sign(), absolute() and min() from\r\n * this library. Input magnitude is clamped to 1 before remapping,\r\n * matching real-world axis APIs where hardware may report values\r\n * slightly outside the nominal range (e.g. 1.0000001).\r\n *\r\n * @param {number} value - Normalized axis value, expected in\r\n *     [-1, 1]. Magnitudes above 1 are clamped to 1. Floats and\r\n *     negatives are the normal use case. Non-finite returns NaN.\r\n * @param {number} threshold - Dead zone radius, valid in [0, 1).\r\n *     0 disables the dead zone (identity within [-1, 1]). Values\r\n *     below 0, equal to or above 1, or non-finite return NaN\r\n *     (a threshold of 1 would collapse the whole axis and divide\r\n *     by zero — honest NaN instead of a silent lie).\r\n * @returns {number} Remapped value in [-1, 1]; exactly 0 inside\r\n *     the dead zone (|value| <= threshold); NaN for invalid inputs.\r\n */\r\nexport function deadzone(value: number, threshold: number): number {\r\n   if (!Number.isFinite(value) || !Number.isFinite(threshold)) {\r\n      return NaN;\r\n   }\r\n\r\n   if (threshold < 0 || threshold >= 1) {\r\n      return NaN;\r\n   }\r\n\r\n   const magnitude = min(absolute(value), 1);\r\n\r\n   if (magnitude <= threshold) {\r\n      return 0;\r\n   }\r\n\r\n   return sign(value) * ((magnitude - threshold) / (1 - threshold));\r\n}\r\n\r\n/**\r\n * Raises the magnitude of the base to the exponent while preserving\r\n * the original sign: sign(base) × |base|^exp. Solves the classic\r\n * JavaScript trap where (-4) ** 0.5 yields NaN — fractional powers\r\n * of negative numbers are undefined in the reals, but in practice\r\n * what callers almost always want is the symmetric curve.\r\n *\r\n * Example: signedPow(-4, 0.5) returns -2; signedPow(4, 0.5)\r\n * returns 2; signedPow(-8, 1/3) returns -2; signedPow(-3, 2)\r\n * returns -9 (sign preserved even for even exponents — this is\r\n * the defining feature, not a bug).\r\n *\r\n * Useful for symmetric easing/response curves: signedPow(x, 2)\r\n * gives a quadratic joystick response that still pushes left when\r\n * the stick goes left; signedPow(x, 0.5) softens extremes in both\r\n * directions. Also used in audio waveshaping and signed gamma\r\n * correction.\r\n *\r\n * Algorithm note: dogfooding with sign(), absolute() and power()\r\n * from this library. The identity signedPow(x, k) = -signedPow(-x, k)\r\n * holds for every valid input (odd symmetry by construction).\r\n *\r\n * @param {number} base - Any finite number. Negatives are the whole\r\n *     point: their magnitude is raised and the sign is restored.\r\n *     Non-finite returns NaN.\r\n * @param {number} exp - Any finite exponent, including fractional\r\n *     and negative. Non-finite returns NaN.\r\n * @returns {number} sign(base) × |base|^exp. Edge cases:\r\n *     signedPow(x, 0) returns sign(x) (1, -1 or 0) since |x|^0 = 1;\r\n *     signedPow(0, exp) returns 0 for exp > 0; signedPow(0, exp)\r\n *     with exp < 0 returns NaN (0 × Infinity is an honest\r\n *     indeterminate, not a silent 0); NaN for non-finite inputs.\r\n */\r\nexport function signedPow(base: number, exp: number): number {\r\n   if (!Number.isFinite(base) || !Number.isFinite(exp)) {\r\n      return NaN;\r\n   }\r\n\r\n   return sign(base) * power(absolute(base), exp);\r\n}\r\n\r\n/**\r\n * Rounds a number to a given count of significant figures — the\r\n * leading digits that carry measurement information — instead of\r\n * a fixed count of decimal places.\r\n *\r\n * Example: roundToSignificant(123456, 2) returns 120000;\r\n * roundToSignificant(0.00012345, 3) returns 0.000123;\r\n * roundToSignificant(9.876, 2) returns 9.9. Note how the same\r\n * sigFigs adapts to any magnitude — toFixed(2) could never do the\r\n * first two.\r\n *\r\n * Useful for science and engineering output (lab reports, sensor\r\n * readings), display formatting of measurements, and honest\r\n * uncertainty: 0.00012345 measured with 3-digit confidence IS\r\n * 0.000123, no matter where the decimal point sits.\r\n *\r\n * Algorithm note: finds the magnitude with floor(log10(|n|)),\r\n * scales the number so the requested digits sit left of the\r\n * decimal point, rounds, and scales back: sign(n) × round(|n| /\r\n * scale) × scale, with scale = 10^(magnitude − sigFigs + 1).\r\n * Dogfooding: sign(), absolute(), floor(), log10(), round() and\r\n * power() from this library. Rounding away from a power-of-ten\r\n * boundary self-corrects: 99.5 at 2 figures becomes 100 (= 1.0e2)\r\n * naturally.\r\n *\r\n * Precision note: results are the closest IEEE 754 double to the\r\n * decimal value (0.000123 is stored as the nearest binary float,\r\n * as with any decimal literal). Ties round half away from zero\r\n * symmetrically: roundToSignificant(-12.5, 2) mirrors\r\n * roundToSignificant(12.5, 2).\r\n *\r\n * @param {number} n - The number to round. Floats and negatives\r\n *     are first-class (sign is preserved by symmetric decomposition).\r\n *     Non-finite returns NaN.\r\n * @param {number} sigFigs - How many significant figures to keep.\r\n *     Must be an integer >= 1; fractional, zero, negative or\r\n *     non-finite values return NaN (there is no such thing as\r\n *     \"2.5 significant digits\" — honest NaN instead of a guess).\r\n * @returns {number} The rounded value; 0 stays 0 (zero has no\r\n *     significant digits to count); NaN for invalid inputs.\r\n */\r\nexport function roundToSignificant(n: number, sigFigs: number): number {\r\n   if (!Number.isFinite(n) || !Number.isFinite(sigFigs)) {\r\n      return NaN;\r\n   }\r\n\r\n   if (!Number.isInteger(sigFigs) || sigFigs < 1) {\r\n      return NaN;\r\n   }\r\n\r\n   if (n === 0) {\r\n      return 0;\r\n   }\r\n\r\n   const magnitude = floor(log10(absolute(n)));\r\n   const scale = power(10, magnitude - sigFigs + 1);\r\n\r\n   return sign(n) * round(absolute(n) / scale) * scale;\r\n}\r\n\r\n/**\r\n * Rescales a list of numbers so they sum to a target value while\r\n * preserving their relative proportions. The default target of 1\r\n * turns any list of weights into a probability distribution.\r\n *\r\n * Example: normalizeToSum([2, 3, 5]) returns [0.2, 0.3, 0.5];\r\n * normalizeToSum([1, 1, 2], 100) returns [25, 25, 50] (percentages);\r\n * normalizeToSum([-1, 3]) returns [-0.5, 1.5] (negatives are fine\r\n * as long as the total is nonzero — proportions still hold).\r\n *\r\n * Useful for probability/weight normalization (softmax-free),\r\n * percentage breakdowns, portfolio allocations, and converting\r\n * arbitrary scores into shares of a whole.\r\n *\r\n * Algorithm note: single uniform scaling by target / sum(values),\r\n * with sum() from this library as the aggregator. Proportions are\r\n * preserved exactly: output[i] / output[j] === values[i] / values[j]\r\n * for every pair (same ratio, same signs).\r\n *\r\n * Precision note: the rescaled values sum to the target up to\r\n * normal IEEE 754 accumulation drift (use tolerance when comparing;\r\n * for integer-exact partitioning of a total, see proportionalSplit).\r\n *\r\n * @param {number[]} values - The list to rescale. Floats and\r\n *     negatives are accepted; the input array is never mutated.\r\n *     Empty list returns [] (nothing to normalize).\r\n * @param {number} [target=1] - The desired total after rescaling.\r\n *     0 is valid (collapses every entry to 0). Non-finite returns\r\n *     all-NaN.\r\n * @returns {number[]} New array, same length, scaled to sum to the\r\n *     target. If the values sum to 0 the direction of scaling is\r\n *     undefined (division by zero) and every entry is an honest NaN;\r\n *     likewise any non-finite entry or target yields all-NaN —\r\n *     a half-scaled list would be a silent lie.\r\n */\r\nexport function normalizeToSum(values: number[], target = 1): number[] {\r\n   if (!Number.isFinite(target) || values.some((v) => !Number.isFinite(v))) {\r\n      return new Array(values.length).fill(NaN);\r\n   }\r\n\r\n   const total = sum(...values);\r\n\r\n   if (total === 0) {\r\n      return new Array(values.length).fill(NaN);\r\n   }\r\n\r\n   const ratio = target / total;\r\n\r\n   return values.map((v) => v * ratio);\r\n}\r\n\r\n/**\r\n * Multiplicative (geometric) interpolation between two positive\r\n * values: instead of moving in equal DIFFERENCES like the ordinary\r\n * lerp, it moves in equal RATIOS. The midpoint of 1 and 100 is 10\r\n * (the geometric mean), not 50.5.\r\n *\r\n * Example: geometricLerp(1, 100, 0.5) returns 10;\r\n * geometricLerp(220, 880, 0.5) returns 440 — the note A4, exactly\r\n * one octave above A3 and one below A5, because pitch perception\r\n * is multiplicative; geometricLerp(1, 100, 0) returns 1 and\r\n * geometricLerp(1, 100, 1) returns 100 (exact endpoints).\r\n *\r\n * Useful wherever the quantity lives on a log scale: audio\r\n * frequencies and volume, zoom levels (each step multiplies the\r\n * scale), animation of scale factors, log-axis charting, and\r\n * compound growth between two known states.\r\n *\r\n * Algorithm note: computed as power(a, 1 - t) × power(b, t) rather\r\n * than a × power(b / a, t) — the two-power form makes BOTH\r\n * endpoints exact (t = 0 gives a × 1, t = 1 gives 1 × b, with no\r\n * b/a division drift). Dogfooding with power() from this library.\r\n * Defining property: equal steps in t multiply the output by equal\r\n * ratios — geometricLerp(a, b, t + d) / geometricLerp(a, b, t) is\r\n * constant for fixed d.\r\n *\r\n * @param {number} a - Start value. Must be strictly positive:\r\n *     geometric interpolation crosses zero never and sign flips\r\n *     have no geometric meaning. Zero, negatives or non-finite\r\n *     return NaN.\r\n * @param {number} b - End value. Same constraint: > 0, finite,\r\n *     otherwise NaN.\r\n * @param {number} t - Interpolation parameter. 0 returns exactly a,\r\n *     1 returns exactly b, 0.5 returns the geometric mean √(a·b).\r\n *     Values outside [0, 1] extrapolate along the same geometric\r\n *     progression (t = 2 with a=1, b=10 gives 100). Non-finite\r\n *     returns NaN.\r\n * @returns {number} a^(1−t) × b^t. NaN for invalid inputs; may\r\n *     overflow to Infinity under extreme extrapolation (IEEE 754\r\n *     limit, ~1.8e308).\r\n */\r\nexport function geometricLerp(a: number, b: number, t: number): number {\r\n   if (!Number.isFinite(a) || !Number.isFinite(b) || !Number.isFinite(t)) {\r\n      return NaN;\r\n   }\r\n\r\n   if (a <= 0 || b <= 0) {\r\n      return NaN;\r\n   }\r\n\r\n   return power(a, 1 - t) * power(b, t);\r\n}\r\n\r\n/**\r\n * Splits an integer total into whole-number parts proportional to\r\n * the given weights, guaranteeing the parts sum to EXACTLY the\r\n * total — no cent lost, no cent invented. Uses the largest\r\n * remainder method (a.k.a. Hamilton's method).\r\n *\r\n * Example: proportionalSplit(100, 1, 1, 1) returns [34, 33, 33]\r\n * (not [33.33, 33.33, 33.33] that sums to 99.99); splitting R$ 100\r\n * three ways gives someone the extra cent honestly;\r\n * proportionalSplit(10, 1, 2, 2) returns [2, 4, 4];\r\n * proportionalSplit(7, 50, 50) returns [4, 3] (the odd unit goes\r\n * to the largest remainder, then to the earliest index on a tie).\r\n *\r\n * Useful for dividing money (the classic \"split the bill\" cent\r\n * problem), allocating discrete seats by proportion (apportionment),\r\n * distributing inventory, or any integer rationing where the parts\r\n * must reconcile to the whole.\r\n *\r\n * Algorithm note (largest remainder / Hamilton): give each part its\r\n * floor(total × weight / weightSum); this leaves a remainder R =\r\n * total − Σfloors of whole units undistributed. Hand those R units\r\n * out one each to the parts with the largest fractional remainders,\r\n * breaking ties by lowest index (stable, deterministic). The result\r\n * provably sums to the total. Dogfooding with sum() and floor().\r\n *\r\n * Range note: total must be a safe integer (|total| < 2^53) for the\r\n * floors to stay exact.\r\n *\r\n * @param {number} total - The integer amount to divide. Must be a\r\n *     finite integer (in cents for money — never split floats).\r\n *     Negative totals split symmetrically (parts are negated).\r\n *     Non-integer or non-finite returns NaN-filled array.\r\n * @param {...number} weights - Proportional weights (variadic).\r\n *     Need not sum to anything special; only their ratios matter.\r\n *     Must be finite and non-negative. Empty weights, all-zero\r\n *     weights, or any negative/non-finite weight returns an array\r\n *     of NaN (matching the weight count, or [] for empty) — a\r\n *     fabricated split would be a silent accounting lie.\r\n * @returns {number[]} Integer parts, same length as weights,\r\n *     summing to exactly total. [] for no weights; NaN-filled for\r\n *     invalid input.\r\n */\r\nexport function proportionalSplit(\r\n   total: number,\r\n   ...weights: number[]\r\n): number[] {\r\n   if (weights.length === 0) {\r\n      return [];\r\n   }\r\n\r\n   const invalid =\r\n      !Number.isInteger(total) ||\r\n      weights.some((w) => !Number.isFinite(w) || w < 0);\r\n\r\n   if (invalid) {\r\n      return new Array(weights.length).fill(NaN);\r\n   }\r\n\r\n   const weightSum = sum(...weights);\r\n\r\n   if (weightSum === 0) {\r\n      return new Array(weights.length).fill(NaN);\r\n   }\r\n\r\n   const exactShares = weights.map((w) => (total * w) / weightSum);\r\n   const floors = exactShares.map((share) => floor(share));\r\n   const distributed = sum(...floors);\r\n   const remainder = total - distributed;\r\n\r\n   // Pair each part with its fractional remainder, then hand out the\r\n   // leftover units to the largest remainders (ties → lowest index).\r\n   const order = exactShares\r\n      .map((share, index) => ({ index, frac: share - floors[index] }))\r\n      .sort((a, b) => b.frac - a.frac || a.index - b.index);\r\n\r\n   const result = [...floors];\r\n   for (let i = 0; i < remainder; i++) {\r\n      result[order[i].index] += 1;\r\n   }\r\n\r\n   return result;\r\n}\r\n","// src/utils/toWords/en-US.ts\r\n\r\nimport { absolute, trunc, floor, divide, multiply, subtract } from '../../algebra/arithmetic';\r\n\r\nexport const ones = [\r\n    '', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten',\r\n    'eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen', 'sixteen',\r\n    'seventeen', 'eighteen', 'nineteen'\r\n];\r\n\r\nexport const tens = [\r\n    '', '', 'twenty', 'thirty', 'forty', 'fifty',\r\n    'sixty', 'seventy', 'eighty', 'ninety'\r\n];\r\n\r\nexport const scales = [\r\n    '', 'thousand', 'million', 'billion', 'trillion',\r\n    'quadrillion', 'quintillion', 'sextillion', 'septillion',\r\n    'octillion', 'nonillion', 'decillion', 'undecillion',\r\n    'duodecillion', 'tredecillion', 'quattuordecillion',\r\n    'quindecillion', 'sexdecillion', 'septendecillion',\r\n    'octodecillion', 'novemdecillion', 'vigintillion'\r\n];\r\n\r\n//-- \r\n\r\nfunction convertInteger(integerNum: number): string {\r\n    if (integerNum === 0) return 'zero';\r\n\r\n    let words = [];\r\n    let scaleIndex = 0;\r\n    let tempNum = integerNum;\r\n\r\n    while (tempNum > 0) {\r\n        const chunk = tempNum % 1000;\r\n        if (chunk > 0) {\r\n            let chunkWords = [];\r\n            const hundreds = floor(divide(chunk, 100));\r\n            let remainder = chunk % 100;\r\n            \r\n            if (hundreds > 0) { chunkWords.push(ones[hundreds], 'hundred'); }\r\n            if (remainder >= 20) {\r\n                chunkWords.push(tens[floor(divide(remainder, 10))]);\r\n                remainder %= 10;\r\n            }\r\n            if (remainder > 0) { chunkWords.push(ones[remainder]); }\r\n            \r\n            const scaleWord = scales[scaleIndex];\r\n            if (scaleWord) { words.unshift(scaleWord); }\r\n            words.unshift(chunkWords.join(' '));\r\n        }\r\n        tempNum = floor(divide(tempNum, 1000));\r\n        scaleIndex++;\r\n    }\r\n    return words.join(' ').replace(/\\s+/g, ' ').trim();\r\n}\r\n\r\nfunction pureConverter(n: number): string {\r\n    if (!Number.isSafeInteger(trunc(n))) {\r\n        return 'Integer part is too large or not a safe integer.';\r\n    }\r\n\r\n    const isNegative = n < 0;\r\n    const num = absolute(n);\r\n    \r\n    const integerPart = trunc(num);\r\n    const numberAsString = num.toString();\r\n    const fractionalString = numberAsString.includes('.') ? numberAsString.split('.')[1] : '';\r\n\r\n    let result;\r\n    if (integerPart === 0 && fractionalString.length > 0) {\r\n        result = 'zero';\r\n    } else {\r\n        result = convertInteger(integerPart);\r\n    }\r\n\r\n    if (fractionalString.length > 0) {\r\n        const fractionalWords = fractionalString.split('').map(digit => ones[Number(digit)] || 'zero').join(' ');\r\n        result += ` point ${fractionalWords}`;\r\n    }\r\n    \r\n    return (isNegative ? `minus ${result}` : result).trim();\r\n}\r\n\r\n//-- formatCurrency function --//\r\n\r\nfunction currencyConverter(n: number, options: {\r\n    majorSingular: string;\r\n    majorPlural: string;\r\n    minorSingular: string;\r\n    minorPlural: string;\r\n}): string {\r\n    if (!Number.isSafeInteger(trunc(n))) {\r\n        return 'Integer part is too large or not a safe integer.';\r\n    }\r\n    const isNegative = n < 0;\r\n    const num = absolute(n);\r\n    \r\n    const integerPart = trunc(num);\r\n    // Usamos round para lidar com casos como 1.235 -> 24 centavos\r\n    const fractionalPart = Math.round(multiply(subtract(num, integerPart), 100));\r\n    \r\n    // Define o singular/plural para a unidade principal (ex: dollar/dollars)\r\n    const majorUnit = integerPart === 1 ? options.majorSingular : options.majorPlural;\r\n    // Define o singular/plural para a unidade fracionária (ex: cent/cents)\r\n    const minorUnit = fractionalPart === 1 ? options.minorSingular : options.minorPlural;\r\n\r\n    // Converte os números em palavras usando a função que já temos\r\n    const majorWords = convertInteger(integerPart);\r\n    const minorWords = convertInteger(fractionalPart);\r\n    \r\n    const parts = [];\r\n\r\n    // Adiciona a parte principal se ela for maior que zero, ou se o valor total for zero.\r\n    if (integerPart > 0 || (integerPart === 0 && fractionalPart === 0)) {\r\n        parts.push(`${majorWords} ${majorUnit}`);\r\n    }\r\n\r\n    // Adiciona a parte fracionária se ela existir\r\n    if (fractionalPart > 0) {\r\n        parts.push(`${minorWords} ${minorUnit}`);\r\n    }\r\n    \r\n    // Junta as duas partes com \" and \"\r\n    const result = parts.join(' and ');\r\n    \r\n    // Adiciona o \"minus\" se for negativo e retorna\r\n    return (isNegative ? `minus ${result}` : result).trim();\r\n}\r\n\r\n\r\n// -- Exporting the locale object --//\r\nexport const enUS = {\r\n    pureConverter: pureConverter,\r\n    currencyConverter: currencyConverter,\r\n    currencyDefaults: {\r\n        majorSingular: 'dollar',\r\n        majorPlural: 'dollars',\r\n        minorSingular: 'cent',\r\n        minorPlural: 'cents',\r\n    }\r\n};","// src/utils/toWords/pt-BR.ts\r\n\r\nimport { absolute, divide, floor, multiply, power, round, subtract, trunc } from \"../../algebra/arithmetic\";\r\n\r\nexport const ones = [\r\n    'zero', 'um', 'dois', 'três', 'quatro', 'cinco',\r\n    'seis', 'sete', 'oito', 'nove', 'dez',\r\n    'onze', 'doze', 'treze', 'catorze', 'quinze',\r\n    'dezesseis', 'dezessete', 'dezoito', 'dezenove'\r\n];\r\n\r\nexport const tens = [\r\n    '', '', 'vinte', 'trinta', 'quarenta', 'cinquenta',\r\n    'sessenta', 'setenta', 'oitenta', 'noventa'\r\n];\r\n\r\nexport const hundreds = [\r\n    '', 'cem', 'duzentos', 'trezentos', 'quatrocentos',\r\n    'quinhentos', 'seiscentos', 'setecentos',\r\n    'oitocentos', 'novecentos'\r\n];\r\n\r\nexport const scales = [\r\n    '', '',\r\n    'mil', 'mil',\r\n    'milhão', 'milhões',\r\n    'bilhão', 'bilhões',\r\n    'trilhão', 'trilhões',\r\n    'quadrilhão', 'quadrilhões',\r\n    'quintilhão', 'quintilhões',\r\n    'sextilhão', 'sextilhões',\r\n    'septilhão', 'septilhões',\r\n    'octilhão', 'octilhões',\r\n    'nonilhão', 'nonilhões',\r\n    'decilhão', 'decilhões',\r\n    'undecilhão', 'undecilhões',\r\n    'duodecilhão', 'duodecilhões',\r\n    'tredecilhão', 'tredecilhões',\r\n    'quatordecilhão', 'quatordecilhões',\r\n    'quindecilhão', 'quindecilhões',\r\n    'sexdecilhão', 'sexdecilhões',\r\n    'septendecilhão', 'septendecilhões',\r\n    'octodecilhão', 'octodecilhões',\r\n    'nondecilhão', 'nondecilhões',\r\n    'vigintilhão', 'vigintilhões'\r\n];\r\n\r\n//--\r\n\r\nfunction convertInteger(integerNum: number): string {\r\n    if (integerNum === 0) return 'zero';\r\n    function convertChunk(chunk: number): string {\r\n        if (chunk === 0) return '';\r\n        if (chunk === 100) return 'cem';\r\n        \r\n        const words: string[] = [];\r\n        const hundred = floor(divide(chunk, 100));\r\n        const tenAndOne = chunk % 100;\r\n\r\n        if (hundred > 0) {\r\n            words.push(hundred === 1 && tenAndOne > 0 ? 'cento' : hundreds[hundred]);\r\n        }\r\n        if (tenAndOne > 0) {\r\n            if (tenAndOne < 20) {\r\n                words.push(ones[tenAndOne]);\r\n            } else {\r\n                const ten = floor(divide(tenAndOne, 10));\r\n                const one = tenAndOne % 10;\r\n                words.push(tens[ten]);\r\n                if (one > 0) {\r\n                    words.push(ones[one]);\r\n                }\r\n            }\r\n        }\r\n        return words.join(' e ');\r\n    }\r\n\r\n    const parts: string[] = [];\r\n    let scaleIndex = 0;\r\n    let tempNum = integerNum;\r\n\r\n    while (tempNum > 0) {\r\n        const chunk = tempNum % 1000;\r\n        if (chunk > 0) {\r\n            let chunkStr = convertChunk(chunk);\r\n            if (scaleIndex > 0) {\r\n                const scaleBaseIndex = scaleIndex * 2;\r\n                const scale = chunk === 1 ? scales[scaleBaseIndex] : scales[scaleBaseIndex + 1];\r\n                chunkStr = (chunk === 1 && scaleIndex === 1) ? scale : `${chunkStr} ${scale}`;\r\n            }\r\n            parts.unshift(chunkStr);\r\n        }\r\n        tempNum = floor(divide(tempNum, 1000));\r\n        scaleIndex++;\r\n    }\r\n\r\n    if (parts.length === 1) {\r\n        return parts[0];\r\n    }\r\n    \r\n    const lastPart = parts.pop() as string;\r\n    const mainPart = parts.join(', ');\r\n    return `${mainPart} e ${lastPart}`;\r\n}\r\n\r\n// --\r\n\r\nfunction pureConverter(n: number): string {\r\n    if (!Number.isSafeInteger(trunc(n))) {\r\n        return 'O número inteiro é muito grande ou não é um inteiro seguro.';\r\n    }\r\n    const isNegative = n < 0;\r\n    const num = absolute(n);\r\n    const integerPart = trunc(num);\r\n    const numberAsString = num.toString();\r\n    const fractionalString = numberAsString.includes('.') ? numberAsString.split('.')[1] : '';\r\n\r\n    let result = convertInteger(integerPart);\r\n\r\n    if (fractionalString.length > 0) {\r\n        const fractionalWords = fractionalString.split('').map(digit => ones[Number(digit)] || 'zero').join(' ');\r\n        result += ` vírgula ${fractionalWords}`;\r\n    }\r\n    \r\n    return (isNegative ? `menos ${result}` : result).trim();\r\n}\r\n\r\n//--\r\n\r\nfunction currencyConverter(n: number, options: any): string {\r\n    const isNegative = n < 0;\r\n    const num = absolute(n);\r\n    const roundedNum = divide(round(multiply(num, 100)), 100);\r\n    let integerPart = floor(roundedNum);\r\n    let fractionalPart = round(multiply(subtract(roundedNum, integerPart), 100));\r\n\r\n    if (fractionalPart === 100) {\r\n        integerPart += 1;\r\n        fractionalPart = 0;\r\n    }\r\n    \r\n    const majorUnit = integerPart === 1 ? options.majorSingular : options.majorPlural;\r\n    const minorUnit = fractionalPart === 1 ? options.minorSingular : options.minorPlural;\r\n\r\n    let parts = [];\r\n    if (integerPart > 0 || (integerPart === 0 && fractionalPart === 0)) {\r\n        const majorWords = convertInteger(integerPart);\r\n        parts.push(`${majorWords} ${majorUnit}`);\r\n    }\r\n    if (fractionalPart > 0) {\r\n        const minorWords = convertInteger(fractionalPart);\r\n        parts.push(`${minorWords} ${minorUnit}`);\r\n    }\r\n    \r\n    const result = parts.join(' e ');\r\n    \r\n    return (isNegative ? `menos ${result}` : result).trim();\r\n}\r\n\r\n\r\n// --- OBJECT EXPORT ---\r\n\r\nexport const ptBR = {\r\n    pureConverter,\r\n    currencyConverter,\r\n    currencyDefaults: {\r\n        majorSingular: 'real',\r\n        majorPlural: 'reais',\r\n        minorSingular: 'centavo',\r\n        minorPlural: 'centavos',\r\n    }\r\n};","// src/utils/toWords/es-ES.ts\r\n\r\nimport { absolute, divide, floor, multiply, round, subtract, trunc } from \"../../algebra/arithmetic\";\r\n\r\nexport const ones = [\r\n    'cero', 'uno', 'dos', 'tres', 'cuatro', 'cinco', 'seis', 'siete', 'ocho', 'nueve',\r\n    'diez', 'once', 'doce', 'trece', 'catorce', 'quince', 'dieciséis',\r\n    'diecisiete', 'dieciocho', 'diecinueve'\r\n];\r\n\r\nexport const tens = [\r\n    '', '', 'veinte', 'treinta', 'cuarenta', 'cincuenta', 'sesenta',\r\n    'setenta', 'ochenta', 'noventa'\r\n];\r\n\r\nexport const hundreds = [\r\n    '', 'cien', 'doscientos', 'trescientos', 'cuatrocientos', 'quinientos',\r\n    'seiscientos', 'setecientos', 'ochocientos', 'novecientos'\r\n];\r\n\r\nexport const scales = [\r\n    '', '', \r\n    'mil', 'mil', \r\n    'millón', 'millones', \r\n    'billón', 'billones',\r\n    'trillón', 'trillones',\r\n    'cuatrillón', 'cuatrillones',\r\n    'quintillón', 'quintillones',\r\n    'sextillón', 'sextillones',\r\n    'septillón', 'septillones',\r\n    'octillón', 'octillones',\r\n    'nonillón', 'nonillones',\r\n    'decillón', 'decillones',\r\n    'undecillón', 'undeciliones',\r\n    'duodecillón', 'duodecillones',\r\n    'tredecillón', 'tredecillones',\r\n    'cuatordecillón', 'cuatordecillones',\r\n    'quindecillón', 'quindecillones',\r\n    'sexdecillón', 'sexdecillones',\r\n    'septendecillón', 'septendecillones',\r\n    'octodecillón', 'octodecillones',\r\n    'nondecillón', 'nondecillones',\r\n    'vigintillón', 'vigintillones'\r\n];\r\n\r\n//--\r\n\r\nfunction convertInteger(integerNum: number): string {\r\n    if (integerNum === 0) return 'cero';\r\n\r\n    const parts: string[] = [];\r\n    let tempNum = integerNum;\r\n    let scaleIndex = 0;\r\n\r\n    while (tempNum > 0) {\r\n        const chunk = tempNum % 1000;\r\n        if (chunk > 0) {\r\n            let chunkWords: string[] = [];\r\n            const hundred = floor(divide(chunk, 100));\r\n            const tenAndOne = chunk % 100;\r\n\r\n            if (hundred > 0) {\r\n                if (hundred === 1 && tenAndOne > 0) {\r\n                    chunkWords.push('ciento');\r\n                } else {\r\n                    chunkWords.push(hundreds[hundred]);\r\n                }\r\n            }\r\n            if (tenAndOne > 0) {\r\n                if (tenAndOne < 20) {\r\n                    if (tenAndOne === 1 && scaleIndex > 0) {\r\n                        chunkWords.push('un');\r\n                    } else {\r\n                        chunkWords.push(ones[tenAndOne]);\r\n                    }\r\n                } else {\r\n                    const ten = floor(divide(tenAndOne, 10));\r\n                    const one = tenAndOne % 10;\r\n                    \r\n                    // Lógica para os números 21-29 com ortografia correta\r\n                    if (ten === 2 && one > 0) {\r\n                        switch (one) {\r\n                            case 1:\r\n                                chunkWords.push(scaleIndex > 0 ? 'veintiún' : 'veintiuno');\r\n                                break;\r\n                            case 2:\r\n                                chunkWords.push('veintidós');\r\n                                break;\r\n                            case 3:\r\n                                chunkWords.push('veintitrés');\r\n                                break;\r\n                            case 6:\r\n                                chunkWords.push('veintiséis');\r\n                                break;\r\n                            default:\r\n                                chunkWords.push(`veinti${ones[one]}`);\r\n                        }\r\n                    } else {\r\n                        chunkWords.push(tens[ten]);\r\n                        if (one > 0) {\r\n                            chunkWords.push(`y ${ones[one]}`);\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n            let chunkStr = chunkWords.join(' ');\r\n            if (scaleIndex > 0) {\r\n                const scaleBaseIndex = scaleIndex * 2;\r\n                const scale = chunk === 1 ? scales[scaleBaseIndex] : scales[scaleBaseIndex + 1];\r\n                if (chunk === 1 && scaleIndex === 1) {\r\n                    chunkStr = scale;\r\n                } else {\r\n                    chunkStr = `${chunkStr} ${scale}`;\r\n                }\r\n            }\r\n            parts.unshift(chunkStr);\r\n        }\r\n        tempNum = floor(divide(tempNum, 1000));\r\n        scaleIndex++;\r\n    }\r\n    return parts.join(' ').trim();\r\n}\r\n\r\n//--\r\n\r\n// --- CONVERSORES (EXPORTADOS VIA OBJETO) ---\r\n\r\nfunction pureConverter(n: number): string {\r\n    const isNegative = n < 0;\r\n    const num = absolute(n);\r\n    \r\n    const integerPart = trunc(num);\r\n    const numberAsString = num.toString();\r\n    const fractionalString = numberAsString.includes('.') ? numberAsString.split('.')[1] : '';\r\n\r\n    let result = convertInteger(integerPart);\r\n\r\n    if (fractionalString.length > 0) {\r\n        // A regra para o espanhol é ler dígito por dígito, igual ao português.\r\n        const fractionalWords = fractionalString.split('').map(digit => ones[Number(digit)] || 'cero').join(' ');\r\n        result += ` coma ${fractionalWords}`;\r\n    }\r\n    \r\n    return (isNegative ? `menos ${result}` : result).trim();\r\n}\r\n\r\n//--\r\n\r\nfunction currencyConverter(n: number, options: any): string {\r\n    const isNegative = n < 0;\r\n    const num = absolute(n);\r\n    \r\n    const roundedNum = divide(round(multiply(num, 100)), 100);\r\n    let integerPart = floor(roundedNum);\r\n    let fractionalPart = round(multiply(subtract(roundedNum, integerPart), 100));\r\n\r\n    if (fractionalPart === 100) {\r\n        integerPart += 1;\r\n        fractionalPart = 0;\r\n    }\r\n    \r\n    const majorUnit = integerPart === 1 ? options.majorSingular : options.majorPlural;\r\n    const minorUnit = fractionalPart === 1 ? options.minorSingular : options.minorPlural;\r\n\r\n    let parts = [];\r\n\r\n    if (integerPart > 0 || (integerPart === 0 && fractionalPart === 0)) {\r\n        let majorWords = convertInteger(integerPart);\r\n        // Aplica a regra do \"uno\" -> \"un\"\r\n        if (integerPart % 10 === 1 && integerPart % 100 !== 11) {\r\n            majorWords = majorWords.replace(/uno$/, 'un');\r\n        }\r\n        // Aplica a regra do \"de\" para milhões\r\n        if (integerPart >= 1000000 && integerPart % 1000000 === 0) {\r\n            parts.push(`${majorWords} de ${majorUnit}`);\r\n        } else {\r\n            parts.push(`${majorWords} ${majorUnit}`);\r\n        }\r\n    }\r\n\r\n    if (fractionalPart > 0) {\r\n        let minorWords = convertInteger(fractionalPart);\r\n        // Aplica a regra do \"uno\" -> \"un\" também para os centavos\r\n        if (fractionalPart % 10 === 1 && fractionalPart % 100 !== 11) {\r\n            minorWords = minorWords.replace(/uno$/, 'un');\r\n        }\r\n        parts.push(`${minorWords} ${minorUnit}`);\r\n    }\r\n    \r\n    const result = parts.join(' con ');\r\n    \r\n    return (isNegative ? `menos ${result}` : result).trim();\r\n}\r\n\r\n//--\r\n\r\n// --- OBJETO DO DICIONÁRIO ---\r\n\r\nexport const esES = {\r\n    pureConverter,\r\n    currencyConverter,\r\n    currencyDefaults: {\r\n        majorSingular: 'euro',\r\n        majorPlural: 'euros',\r\n        minorSingular: 'céntimo',\r\n        minorPlural: 'céntimos',\r\n    }\r\n};\r\n\r\n","// src/utils/toWords/index.ts\r\n\r\nimport { enUS } from './en-US';\r\nimport { ptBR } from './pt-BR';\r\nimport { esES } from './es-ES';\r\n/**\r\n * import { bnBD } from './bn-BD';\r\nimport { deDE } from './de-DE';\r\nimport { enUS } from './en-US';\r\nimport { enGB } from './en-GB';\r\nimport { esES } from './es-ES';\r\nimport { faIR } from './fa-IR';\r\nimport { frFR } from './fr-FR';\r\nimport { guIN } from './gu-IN';\r\nimport { haNG } from './ha-NG';\r\nimport { hiIN } from './hi-IN';\r\nimport { idID } from './id-ID';\r\nimport { itIT } from './it-IT';\r\nimport { jaJP } from './ja-JP';\r\nimport { jvID } from './jv-ID';\r\nimport { koKR } from './ko-KR';\r\nimport { mrIN } from './mr-IN';\r\nimport { paIN } from './pa-IN';\r\nimport { ptBR } from './pt-BR';\r\n */\r\nexport const dictionaries = {\r\n    'en-us': enUS,\r\n    'pt-br': ptBR,\r\n    'es-es': esES,\r\n    /**\r\n     *     'bn-bd': bnBD,\r\n    'de-de': deDE,\r\n    'en-us': enUS,\r\n    'en-gb': enGB,\r\n    'es-es': esES,\r\n    'fa-ir': faIR,\r\n    'fr-fr': frFR,\r\n    'gu-in': guIN,\r\n    'ha-ng': haNG,\r\n    'hi-in': hiIN,\r\n    'id-id': idID,\r\n    'it-it': itIT,\r\n    'ja-jp': jaJP,\r\n    'jv-id': jvID,\r\n    'ko-kr': koKR,\r\n    'mr-in': mrIN,\r\n    'pa-in': paIN,\r\n    'pt-br': ptBR,\r\n     */\r\n\r\n};\r\n","// src/utils/utils.ts\r\n\r\nimport {\r\n   absolute,\r\n   divide,\r\n   floor,\r\n   log2,\r\n   multiply,\r\n   power,\r\n   round,\r\n   sqrt,\r\n   subtract,\r\n   sum,\r\n   trunc,\r\n} from \"../algebra/arithmetic\";\r\nimport { dictionaries } from \"./toWords/index\";\r\n\r\n/**\r\n * @fileoverview A collection of high-level utility, statistical, and real-world calculation functions.\r\n * @version 0.8.0\r\n * @license MIT\r\n * @author Jackson Douglas de Souza\r\n * @see {@link https://www.linkedin.com/in/jacksondouglasdsouza/|LinkedIn}\r\n * @see {@link https://github.com/jacksondouglasdesouza/codymath|GitHub}\r\n * @description\r\n * This module provides a wide range of high-level utility functions designed to solve\r\n * common, practical problems in domains like statistics, finance, animation, natural\r\n * language processing (number-to-word), and data formatting.\r\n * * @see\r\n * Sources & References:\r\n * * // Mathematical & Computational Foundations\r\n * 1. National Institute of Standards and Technology (NIST). (2023). *Digital Library of Mathematical Functions*. U.S. Department of Commerce.\r\n * 2. Wolfram Research, Inc. *Wolfram MathWorld*.\r\n * 3. Spiegel, M. R., et al. (2018). *Schaum's Outline of Mathematical Handbook of Formulas and Tables, 5th Edition*. McGraw-Hill Education.\r\n * 4. ECMA International. (2025). *ECMAScript® 2025 Language Specification*.\r\n * * // Linguistic & Number-to-Word Rules\r\n * 5. Real Academia Española (RAE). *Diccionario panhispánico de dudas*. for Spanish numeral writing rules.\r\n * 6. Academia Brasileira de Letras (ABL). *Vocabulário Ortográfico da Língua Portuguesa*. for Portuguese vocabulary and standards.\r\n * 7. Cunha, C., & Cintra, L. F. L. *Nova Gramática do Português Contemporâneo*. for detailed Portuguese grammar rules.\r\n * 8. The University of Chicago. *The Chicago Manual of Style, 17th Edition*. for English numeral writing conventions.\r\n */\r\n\r\n/**\r\n * Re-maps a number from one range to another.\r\n * @param {number} value The incoming value to be converted.\r\n * @param {number} inMin The lower bound of the value's current range.\r\n * @param {number} inMax The upper bound of the value's current range.\r\n * @param {number} outMin The lower bound of the value's target range.\r\n * @param {number} outMax The upper bound of the value's target range.\r\n * @returns {number} The re-mapped number.\r\n */\r\nexport function map(\r\n   value: number,\r\n   inMin: number,\r\n   inMax: number,\r\n   outMin: number,\r\n   outMax: number,\r\n): number {\r\n   if (inMin === inMax) {\r\n      return outMin;\r\n   }\r\n   const term1 = subtract(value, inMin);\r\n   const term2 = subtract(outMax, outMin);\r\n   const term3 = subtract(inMax, inMin);\r\n\r\n   const multiplicationResult = multiply(term1, term2);\r\n   const divisionResult = divide(multiplicationResult, term3);\r\n   const finalResult = sum(divisionResult, outMin);\r\n\r\n   return finalResult;\r\n}\r\n\r\n/**\r\n * Generates a pseudo-random floating-point number within a specified range.\r\n *\r\n * @param {number} [min=0] The lower bound of the range (inclusive).\r\n * @param {number} [max=1] The upper bound of the range (exclusive).\r\n * @returns {number} A random number such that min <= result < max.\r\n * @description\r\n * If no arguments are provided, it behaves identically to `Math.random()`,\r\n * returning a value between 0 (inclusive) and 1 (exclusive).\r\n * The implementation uses the library's own arithmetic functions for consistency.\r\n */\r\nexport function random(min: number = 0, max: number = 1): number {\r\n   const baseRandom = Math.random();\r\n   const range = subtract(max, min);\r\n   const scaledRandom = multiply(baseRandom, range);\r\n   return sum(scaledRandom, min);\r\n}\r\n\r\n/**\r\n * Generates a pseudo-random floating-point number between 0 (inclusive) and 1 (exclusive).\r\n *\r\n * @returns {number} A random number in the range [0, 1).\r\n * @description\r\n * This is a direct wrapper for the standard `Math.random()` function,\r\n * providing a foundational random number generator for the library. It is\r\n * useful when a simple random float is needed without a specific range.\r\n */\r\nexport function randomFloat(): number {\r\n   return Math.random();\r\n}\r\n\r\n/**\r\n * Checks if two floating-point numbers are approximately equal within a given tolerance.\r\n * @param {number} a The first number.\r\n * @param {number} b The second number.\r\n * @param {number} [epsilon=0.00001] The small tolerance within which the numbers are considered equal. Defaults to 1e-5.\r\n * @returns {boolean} `true` if the absolute difference between a and b is less than epsilon, otherwise `false`.\r\n */\r\nexport function isNearlyEqual(\r\n   a: number,\r\n   b: number,\r\n   epsilon: number = 0.00001,\r\n): boolean {\r\n   const difference = subtract(a, b);\r\n   const absoluteDifference = absolute(difference);\r\n\r\n   return absoluteDifference < epsilon;\r\n}\r\n\r\n/**\r\n * Checks if a value is a power of two.\r\n * @param {number | bigint} n The number or BigInt to check.\r\n * @returns {boolean} `true` if the value is an integer power of two, otherwise `false`.\r\n * @description\r\n * This function is optimized for performance using bitwise operations and is robust for\r\n * both standard JavaScript numbers and arbitrarily large BigInts. It correctly\r\n\r\n * handles non-integers by returning false.\r\n */\r\nexport function isPowerOfTwo(n: number | bigint): boolean {\r\n   // A primeira verificação, que funciona para ambos os tipos, é se o número é positivo.\r\n   // Usamos `> 0` e `> 0n` para evitar erros de tipo.\r\n   if (n <= 0) {\r\n      return false;\r\n   }\r\n\r\n   // Se for do tipo 'number', primeiro garantimos que é um inteiro.\r\n   if (typeof n === \"number\") {\r\n      if (!Number.isInteger(n)) {\r\n         return false;\r\n      }\r\n      // Lógica bitwise para 'number'\r\n      return (n & (n - 1)) === 0;\r\n   }\r\n\r\n   // Se chegou aqui, 'n' é um 'bigint'. A lógica bitwise é a mesma, mas com literais BigInt.\r\n   // BigInts são sempre inteiros, então não precisamos da verificação isInteger.\r\n   return (n & (n - 1n)) === 0n;\r\n}\r\n\r\n/**\r\n * Calculates the Euclidean distance between two points in a 2D plane.\r\n * @param {number} x1 The x-coordinate of the first point.\r\n * @param {number} y1 The y-coordinate of the first point.\r\n * @param {number} x2 The x-coordinate of the second point.\r\n * @param {number} y2 The y-coordinate of the second point.\r\n * @returns {number} The Euclidean distance between the two points.\r\n */\r\nexport function distance(\r\n   x1: number,\r\n   y1: number,\r\n   x2: number,\r\n   y2: number,\r\n): number {\r\n   const deltaX = subtract(x2, x1);\r\n   const deltaY = subtract(y2, y1);\r\n   const xSquared = power(deltaX, 2);\r\n   const ySquared = power(deltaY, 2);\r\n   const sumOfSquares = sum(xSquared, ySquared);\r\n\r\n   return sqrt(sumOfSquares);\r\n}\r\n\r\n/**\r\n * Formats a number as a currency string.\r\n * @param {number} n The number to format.\r\n * @param {object} [options] Configuration options for formatting.\r\n * @param {string} [options.currencySymbol='$'] The currency symbol to prepend.\r\n * @param {string} [options.decimalSeparator='.'] The character to use for the decimal separator.\r\n * @param {string} [options.thousandsSeparator=','] The character to use for the thousands separator.\r\n * @param {number} [options.decimals=2] The number of decimal places.\r\n * @returns {string} The formatted currency string.\r\n */\r\nexport function formatCurrency(\r\n   n: number,\r\n   options: {\r\n      currencySymbol?: string;\r\n      decimalSeparator?: string;\r\n      thousandsSeparator?: string;\r\n      decimals?: number;\r\n   } = {},\r\n): string {\r\n   const {\r\n      currencySymbol = \"$\",\r\n      decimalSeparator = \".\",\r\n      thousandsSeparator = \",\",\r\n      decimals = 2,\r\n   } = options;\r\n\r\n   const formatter = new Intl.NumberFormat(\"en-US\", {\r\n      minimumFractionDigits: decimals,\r\n      maximumFractionDigits: decimals,\r\n   });\r\n\r\n   let formatted = formatter.format(n);\r\n\r\n   if (decimalSeparator !== \".\" || thousandsSeparator !== \",\") {\r\n      const parts = formatted.split(\".\");\r\n      parts[0] = parts[0].replace(/,/g, thousandsSeparator);\r\n      formatted = parts.join(decimalSeparator);\r\n   }\r\n\r\n   return `${currencySymbol}${formatted}`;\r\n}\r\n\r\n//-- toWordsPure and theWordsCurrency functions --//\r\n\r\n/**\r\n * @internal\r\n * Defines the required structure for a language dictionary.\r\n */\r\ninterface ToWordsDictionary {\r\n   pureConverter: (n: number) => string;\r\n   currencyConverter: (\r\n      n: number,\r\n      options: {\r\n         majorSingular: string;\r\n         majorPlural: string;\r\n         minorSingular: string;\r\n         minorPlural: string;\r\n      },\r\n   ) => string;\r\n\r\n   currencyDefaults: {\r\n      majorSingular: string;\r\n      majorPlural: string;\r\n      minorSingular: string;\r\n      minorPlural: string;\r\n   };\r\n}\r\n\r\n//-- toWordsPure --//\r\n\r\n/**\r\n * Converts a number into its written-out \"pure\" representation (e.g., 123.45 -> \"one hundred twenty-three point four five\").\r\n * @param {number} n The number to convert. The integer part must be a safe integer.\r\n * @param {string} [lang='en-US'] The target language code (e.g., 'en-US', 'pt-BR').\r\n * @returns {string} The number represented in words.\r\n */\r\nexport function toWordsPure(n: number, lang: string = \"en-US\"): string {\r\n   const dictionary: ToWordsDictionary =\r\n      dictionaries[lang.toLowerCase() as keyof typeof dictionaries];\r\n\r\n   if (!dictionary) {\r\n      return `Language '${lang}' is not supported.`;\r\n   }\r\n   if (typeof n !== \"number\" || !isFinite(n)) {\r\n      return \"Invalid number input.\";\r\n   }\r\n   return dictionary.pureConverter(n);\r\n}\r\n\r\n//-- toWordsCurrency --//\r\n\r\n/**\r\n * Converts a number into its written-out currency representation.\r\n * @param {number} n The number to convert. The integer part must be a safe integer.\r\n * @param {object} [options] Configuration for the currency conversion.\r\n * @param {string} [options.lang='en-US'] The target language code.\r\n * @param {string} [options.majorSingular] The singular name for the main currency unit (e.g., 'dollar').\r\n * @param {string} [options.majorPlural] The plural name for the main currency unit (e.g., 'dollars').\r\n * @param {string} [options.minorSingular] The singular name for the fractional unit (e.g., 'cent').\r\n * @param {string} [options.minorPlural] The plural name for the fractional unit (e.g., 'cents').\r\n * @returns {string} The number represented in currency words.\r\n */\r\nexport function toWordsCurrency(\r\n   n: number,\r\n   options: {\r\n      lang?: string;\r\n      majorSingular?: string;\r\n      majorPlural?: string;\r\n      minorSingular?: string;\r\n      minorPlural?: string;\r\n   } = {},\r\n): string {\r\n   const { lang = \"en-US\", ...currencyOptions } = options;\r\n   const dictionary =\r\n      dictionaries[lang.toLowerCase() as keyof typeof dictionaries];\r\n   if (!dictionary || !dictionary.currencyConverter) {\r\n      return `Currency conversion for language '${lang}' is not supported.`;\r\n   }\r\n   if (typeof n !== \"number\" || !isFinite(n)) {\r\n      return \"Invalid number input.\";\r\n   }\r\n   const finalCurrencyOptions = {\r\n      ...dictionary.currencyDefaults,\r\n      ...currencyOptions,\r\n   };\r\n   return dictionary.currencyConverter(n, finalCurrencyOptions);\r\n}\r\n\r\n//--\r\n\r\n/**\r\n * Returns the integer part of a number, throwing an error for unsafe integers.\r\n * @param {number} n The number to get the integer part from.\r\n * @returns {number} The integer part of the number.\r\n * @throws {Error} If the number is outside the safe integer range.\r\n * @description This function ensures safety by first checking if the number is within\r\n * JavaScript's safe integer bounds before returning the truncated value.\r\n * @see `trunc`\r\n */\r\nexport function getIntegerPart(n: number): number {\r\n   if (n > Number.MAX_SAFE_INTEGER || n < Number.MIN_SAFE_INTEGER) {\r\n      throw new Error(\r\n         \"Input number is outside the safe integer range and may cause precision loss.\",\r\n      );\r\n   }\r\n   return trunc(n);\r\n}\r\n\r\n//--\r\n\r\n/**\r\n * Returns the fractional part of a number, correcting for floating-point inaccuracies.\r\n * @param {number} n The number to get the fractional part from.\r\n * @returns {number} The fractional part of the number.\r\n * @description This function calculates the fractional part and cleans the result\r\n * to avoid common floating-point precision errors, such as those that occur in `0.1 + 0.2`.\r\n * It leverages the library's own `getIntegerPart` and `subtract`.\r\n */\r\nexport function getFractionalPart(n: number): number {\r\n   // Para números fora da faixa segura, a parte fracionária já foi perdida, então retornamos 0.\r\n   if (n > Number.MAX_SAFE_INTEGER || n < Number.MIN_SAFE_INTEGER) {\r\n      return 0;\r\n   }\r\n\r\n   const integerPart = getIntegerPart(n);\r\n   const fractional = subtract(n, integerPart);\r\n\r\n   return parseFloat(fractional.toFixed(12));\r\n}\r\n\r\n//--\r\n\r\n/**\r\n * Counts the number of digits in the integer part of a number.\r\n * @param {number} n The number to count the digits of.\r\n * @returns {number} The number of digits in the integer part.\r\n * @description This function counts the digits of the integer part of a number,\r\n * ignoring the sign and any fractional digits, as per our agreed-upon rules.\r\n * It leverages the library's own `absolute` and `getIntegerPart` functions.\r\n * @see `absolute`\r\n * @see `getIntegerPart`\r\n */\r\nexport function countDigits(n: number): number {\r\n   const absNum = absolute(n);\r\n   const integerPart = getIntegerPart(absNum);\r\n   return integerPart.toString().length;\r\n}\r\n\r\n//--\r\n\r\n/**\r\n * Counts the number of digits in both the integer and fractional parts of a number.\r\n * @param {number} n The number to analyze.\r\n * @returns {{integer: number, fractional: number}} An object containing the count of digits.\r\n * @description Returns an object with the count of digits for the integer and fractional\r\n * parts of a number, ignoring the sign.\r\n * e.g., `countDigitsDetailed(-123.45)` returns `{ integer: 3, fractional: 2 }`.\r\n * @see `countDigits`\r\n */\r\nexport function countDigitsDetailed(n: number): {\r\n   integer: number;\r\n   fractional: number;\r\n} {\r\n   const absNum = absolute(n);\r\n   const integerCount = countDigits(absNum);\r\n   let fractionalCount = 0;\r\n   const parts = absNum.toString().split(\".\");\r\n\r\n   if (parts.length > 1) {\r\n      fractionalCount = parts[1].length;\r\n   }\r\n\r\n   return {\r\n      integer: integerCount,\r\n      fractional: fractionalCount,\r\n   };\r\n}\r\n\r\n//--\r\n\r\n/**\r\n * Pads the integer part of a number with leading zeros to a specified length.\r\n * @param {number} n The number to pad.\r\n * @param {number} length The total desired length of the number's integer part as a string.\r\n * @returns {string} The zero-padded number as a string.\r\n * @description\r\n * Handles negative numbers by placing the sign before the padding (e.g., -15 -> \"-0015\").\r\n * Ignores the fractional part of the number, considering only the integer part.\r\n * If the number's integer part is already longer than the target length,\r\n * it returns the number as a string without modification.\r\n * @see `absolute`\r\n * @see `getIntegerPart`\r\n */\r\nexport function padZeroes(n: number, length: number): string {\r\n   const isNegative = n < 0;\r\n\r\n   // Usamos nossas funções para tratar negativos e decimais, como combinado (dogfooding).\r\n   const absNum = absolute(n);\r\n   const integerPart = getIntegerPart(absNum);\r\n\r\n   const numberString = integerPart.toString();\r\n   const paddedString = numberString.padStart(length, \"0\");\r\n\r\n   return isNegative ? `-${paddedString}` : paddedString;\r\n}\r\n\r\n//--\r\n","// src/utils/index.ts\r\n\r\nimport * as utilsFuncs from './utils';\r\n\r\nexport const utils = {\r\n    ...utilsFuncs\r\n};"],"mappings":"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"}