@eriveltondasilva/currency 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE.md ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Erivelton da Silva
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,215 @@
1
+ # Currency
2
+
3
+ [![npm version](https://img.shields.io/npm/v/@eriveltondasilva/currency)](https://www.npmjs.com/package/@eriveltondasilva/currency)
4
+ [![npm package minimized gzipped size (scoped)](https://img.shields.io/bundlejs/size/%40eriveltondasilva/currency?format=both)](https://www.npmjs.com/package/@eriveltondasilva/currency)
5
+ [![Pull Request](https://github.com/eriveltondasilva/currency/actions/workflows/pull-request.yml/badge.svg)](https://github.com/eriveltondasilva/currency/actions/workflows/pull-request.yml)
6
+ [![Checked with Biome](https://img.shields.io/badge/Checked_with-Biome-60a5fa?logo=biome)](https://biomejs.dev)
7
+ [![Zero Dependencies](https://img.shields.io/badge/dependencies-0-blue)](https://www.npmjs.com/package/@eriveltondasilva/currency)
8
+ [![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://opensource.org/licenses/MIT)
9
+
10
+ A lightweight TypeScript library for precise monetary operations. All values are stored internally as **minor-unit integers** to eliminate floating-point errors. Every operation returns a new instance — the API is fully immutable.
11
+
12
+ <p align="center">
13
+ <img src="https://raw.githubusercontent.com/eriveltondasilva/currency.js/main/src/assets/currency-banner.png" alt="Currency.js Banner" width="600">
14
+ </p>
15
+
16
+ ## Features
17
+
18
+ - 💰 **Precise calculations** — integer-based math eliminates floating-point errors
19
+ - 🔒 **Immutable API** — every operation returns a new instance
20
+ - 🌍 **Internationalization** — formatting support for 14 countries and 100+ locales
21
+ - 🧮 **Business operations** — discounts, surcharges, allocations, and more
22
+ - 📦 **Zero dependencies** — lightweight and focused (< 5KB min+gzip)
23
+ - 🎯 **Type-safe** — full TypeScript support with comprehensive type definitions
24
+
25
+ ## Quick Start
26
+
27
+ ### Installation
28
+
29
+ ```bash
30
+ npm install @eriveltonsilva/currency.js
31
+ ```
32
+
33
+ ```bash
34
+ bun add @eriveltonsilva/currency.js
35
+ ```
36
+
37
+ ### Import
38
+
39
+ ```typescript
40
+ // Named imports (recommended — better tree-shaking)
41
+ import { from, parse, sum, total, isMoney, ... } from '@eriveltonsilva/currency.js'
42
+
43
+ // Default namespace
44
+ import Money from '@eriveltonsilva/currency.js'
45
+
46
+ // Country presets
47
+ import { br, us, ... } from '@eriveltonsilva/currency.js/presets'
48
+
49
+ // Types
50
+ import type { MoneyContract, MoneyInput, FormatOptions, RoundingMode, PricedItem } from '@eriveltonsilva/currency.js'
51
+ ```
52
+
53
+ ### Basic Usage
54
+
55
+ ```typescript
56
+ // Create instances
57
+ const price = from(19.99, 'BR')
58
+ price.format() // => 'R$ 19,99'
59
+ price.amount() // => 19.99
60
+ price.minorUnits() // => 1999
61
+
62
+ // Arithmetic (all return new instances)
63
+ price.plus(5).format() // => 'R$ 24,99'
64
+ price.minus(4.99).format() // => 'R$ 15,00'
65
+ price.times(2).format() // => 'R$ 39,98'
66
+ price.divide(2).format() // => 'R$ 10,00'
67
+
68
+ // Business operations
69
+ price.applyDiscount(10).format() // => 'R$ 17,99' (10% off)
70
+ price.applySurcharge(5).format() // => 'R$ 20,99' (5% added)
71
+ price.percentOf(15).format() // => 'R$ 3,00' (15% of price)
72
+
73
+ // Comparison
74
+ price.equals(19.99) // => true
75
+ price.greaterThan(10) // => true
76
+ price.isBetween(10, 50) // => true
77
+
78
+ // Allocation (largest-remainder method)
79
+ from(10, 'BR').allocate(3).map((m) => m.amount())
80
+ // => [3.34, 3.33, 3.33]
81
+
82
+ from(100, 'US').allocateByRatio([1, 3]).map((m) => m.amount())
83
+ // => [25, 75]
84
+ ```
85
+
86
+ ### Collection Functions
87
+
88
+ ```typescript
89
+ import { sum, average, max, min, clamp } from '@eriveltonsilva/currency.js'
90
+
91
+ sum([10, 20.50, 5], 'BR').format() // => 'R$ 35,50'
92
+ average([10, 20, 30], 'US').format() // => '$20.00'
93
+ max([5, 30, 10], 'US').format() // => '$30.00'
94
+ min([5, 30, 10], 'US').format() // => '$5.00'
95
+ clamp(150, 0, 100, 'US').format() // => '$100.00'
96
+ ```
97
+
98
+ ### Business Functions
99
+
100
+ ```typescript
101
+ import { total, percent } from '@eriveltonsilva/currency.js'
102
+
103
+ const items = [
104
+ { price: 9.99, quantity: 3 },
105
+ { price: 4.99 },
106
+ ]
107
+ total(items, 'US').format() // => '$34.96'
108
+
109
+ percent(25, 200, 'US') // => 12.5 (25 is 12.5% of 200)
110
+ ```
111
+
112
+ ### Country Presets
113
+
114
+ ```typescript
115
+ import { br, us, de, jp } from '@eriveltonsilva/currency.js/presets'
116
+
117
+ // Accepts number (major units) or locale-formatted string
118
+ br(19.99).format() // => 'R$ 19,99'
119
+ us(19.99).format() // => '$19.99'
120
+
121
+ br('R$ 1.999,99').amount() // => 1999.99
122
+ us('$1,999.99').amount() // => 1999.99
123
+
124
+ de(1500).format() // => '1.500,00 €'
125
+ jp(500).format() // => '¥500'
126
+ ```
127
+
128
+ ### Formatting
129
+
130
+ ```typescript
131
+ const price = from(1999.9, 'BR')
132
+
133
+ price.format() // => 'R$ 1.999,90'
134
+ price.format({ currencyDisplay: 'code' }) // => 'BRL 1.999,90'
135
+ price.format({ currencyDisplay: 'none' }) // => '1.999,90'
136
+ price.format({ notation: 'compact' }) // => 'R$ 2 mil'
137
+ price.format({ signDisplay: 'always' }) // => '+R$ 1.999,90'
138
+ price.format({ currencySign: 'accounting' }) // => 'R$ 1.999,90'
139
+ ```
140
+
141
+ ### Serialization
142
+
143
+ ```typescript
144
+ const price = from(19.99, 'BR')
145
+
146
+ // JSON round-trip
147
+ const json = price.toJSON()
148
+ // => { minorUnits: 1999, currencyCode: 'BRL' }
149
+
150
+ const restored = fromMinorUnits(json.minorUnits, 'BR')
151
+ restored.equals(price) // => true
152
+
153
+ // String output
154
+ price.toString() // => '19.99'
155
+ price.format() // => 'R$ 19,99'
156
+ ```
157
+
158
+ ### Error Handling
159
+
160
+ ```typescript
161
+ import { from, MoneyError, CurrencyMismatchError } from '@eriveltonsilva/currency.js'
162
+
163
+ try {
164
+ from(10, 'BR').plus(from(10, 'US'))
165
+ } catch (err) {
166
+ if (err instanceof MoneyError) {
167
+ console.error(err.code) // => 'CURRENCY_MISMATCH'
168
+ console.error(err.message) // => 'Cannot operate on mismatched currencies: BRL and USD.'
169
+ }
170
+ }
171
+ ```
172
+
173
+ All errors extend `MoneyError` and expose a `code` property for programmatic handling:
174
+
175
+ | Error | Code |
176
+ | -------------------------- | ------------------------ |
177
+ | `InvalidInputError` | `'INVALID_INPUT'` |
178
+ | `InvalidPercentageError` | `'INVALID_PERCENTAGE'` |
179
+ | `DivisionByZeroError` | `'DIVISION_BY_ZERO'` |
180
+ | `InvalidAllocationError` | `'INVALID_ALLOCATION'` |
181
+ | `InvalidRangeError` | `'INVALID_RANGE'` |
182
+ | `CurrencyMismatchError` | `'CURRENCY_MISMATCH'` |
183
+ | `UnsupportedCurrencyError` | `'UNSUPPORTED_CURRENCY'` |
184
+ | `UnsafeIntegerError` | `'UNSAFE_INTEGER'` |
185
+
186
+ ## Supported Countries
187
+
188
+ | Code | Country | Currency |
189
+ | ---- | -------------- | -------- |
190
+ | `AU` | Australia | AUD |
191
+ | `BR` | Brazil | BRL |
192
+ | `CA` | Canada | CAD |
193
+ | `CH` | Switzerland | CHF |
194
+ | `CN` | China | CNY |
195
+ | `DE` | Germany | EUR |
196
+ | `FR` | France | EUR |
197
+ | `GB` | United Kingdom | GBP |
198
+ | `IN` | India | INR |
199
+ | `JP` | Japan | JPY |
200
+ | `MX` | Mexico | MXN |
201
+ | `PT` | Portugal | EUR |
202
+ | `SG` | Singapore | SGD |
203
+ | `US` | United States | USD |
204
+
205
+ ## Changelog
206
+
207
+ See [CHANGELOG.md](./CHANGELOG.md) for a detailed list of changes in each release.
208
+
209
+ ## Contributing
210
+
211
+ Contributions are welcome! Please read our [Contributing Guide](./CONTRIBUTING.md) for details.
212
+
213
+ ## License
214
+
215
+ MIT © [Erivelton Silva](https://github.com/eriveltondasilva)
@@ -0,0 +1,18 @@
1
+ /**
2
+ * @ERIVELTONDASILVA/CURRENCY v1.0.0
3
+ *
4
+ * A lightweight and reliable JavaScript library for precise currency operations, built to safely handle monetary values without floating point errors.
5
+ *
6
+ * @author Erivelton Silva <eriveltondasilva13@gmail.com>
7
+ * @license MIT
8
+ * @copyright 2026 Erivelton Silva
9
+ * @version 1.0.0
10
+ *
11
+ * @see https://github.com/eriveltondasilva/currency#readme - Documentation
12
+ *
13
+ * Inspired by:
14
+ * @see https://github.com/scurker/currency.js
15
+ */
16
+
17
+ var z=Object.defineProperty;var V=(r,n)=>{for(var e in n)z(r,e,{get:n[e],enumerable:true});};var f=class extends Error{code;input;constructor(n,e,t){super(n,t),this.code=e,this.input=t?.input;}},i=class extends f{name="InvalidInputError";constructor(n,e){super(n,"INVALID_INPUT",e);}},d=class extends f{name="InvalidPercentageError";constructor(n,e){super(n,"INVALID_PERCENTAGE",e);}},D=class extends f{name="DivisionByZeroError";constructor(n){super("Cannot divide by zero.","DIVISION_BY_ZERO",n);}},b=class extends f{name="InvalidAllocationError";constructor(n,e){super(n,"INVALID_ALLOCATION",e);}},x=class extends f{name="InvalidRangeError";constructor(n){super("The minimum value cannot be greater than the maximum value.","INVALID_RANGE",n);}},E=class extends f{name="CurrencyMismatchError";constructor(n,e,t){super(`Cannot operate on mismatched currencies: ${n} and ${e}.`,"CURRENCY_MISMATCH",t);}},O=class extends f{name="UnsupportedCurrencyError";constructor(n,e,t){super(`'${n}' is not a supported currency country. Supported codes: ${e}.`,"UNSUPPORTED_CURRENCY",t);}},U=class extends f{name="UnsafeIntegerError";constructor(n){super("The resulting amount exceeds the safe integer limit for precision.","UNSAFE_INTEGER",n);}};var S=Symbol("@eriveltondasilva/currency");function F(r){return typeof r=="object"&&r!=null&&!Array.isArray(r)}function g(r){return F(r)&&S in r}function v(r){return typeof r=="number"||g(r)}function Y(r){return r>=0?Math.ceil(r):Math.floor(r)}function k(r){return Math.sign(r)*Math.round(Math.abs(r))}function J(r){let n=Math.floor(r);return r-n!==.5?Math.round(r):n%2===0?n:n+1}function Z(r){return Math.ceil(r-.5)}function H(r){return r>=0?Math.ceil(r-.5):Math.floor(r+.5)}var I={ceil:Math.ceil,floor:Math.floor,trunc:Math.trunc,expand:Y,halfExpand:k,halfEven:J,halfCeil:Math.round,halfFloor:Z,halfTrunc:H},h="halfExpand",_=I[h];var $=r=>r.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),P=new Map;function q(r,n){let e=`${r}\0${n}`;return P.has(e)||P.set(e,new RegExp(`[^\\d${$(r)}${$(n)}]`,"g")),P.get(e)}function w(r,n){if(!Number.isFinite(r))throw new i("Value must be a finite number.",{input:r});if(r===0)return 0;let e=_(+`${r}e${n}`);if(!Number.isFinite(e))throw new i("Value is too large to be represented as a monetary amount.",{input:r});if(!Number.isSafeInteger(e))throw new i("Value exceeds safe integer range after conversion to minor units.",{input:r});return e}function G(r,n){let{group:e,decimal:t,fractionDigits:o}=n,[,s="",a=""]=/^([+-]?)(.*)$/.exec(r.trim())??[],u=q(e,t),C=a.replace(u,"").replaceAll(e,"");if(C.indexOf(t)!==C.lastIndexOf(t))throw new i("Cannot parse value as a monetary amount: multiple decimal separators found.",{input:r});let l=s+C.replace(t,"."),A=Number.parseFloat(l);if(Number.isNaN(A))throw new i(`Cannot parse value as a monetary amount. Expected "${t}" as decimal separator.`,{input:r});return w(A,o)}var B={AU:{name:"Australia",locale:"en-AU",currency:"AUD",decimal:".",group:","},BR:{name:"Brazil",locale:"pt-BR",currency:"BRL",decimal:",",group:"."},CA:{name:"Canada",locale:"en-CA",currency:"CAD",decimal:".",group:","},CH:{name:"Switzerland",locale:"de-CH",currency:"CHF",decimal:".",group:"'"},CN:{name:"China",locale:"zh-CN",currency:"CNY",decimal:".",group:","},DE:{name:"Germany",locale:"de-DE",currency:"EUR",decimal:",",group:"."},FR:{name:"France",locale:"fr-FR",currency:"EUR",decimal:",",group:" "},GB:{name:"United Kingdom",locale:"en-GB",currency:"GBP",decimal:".",group:","},IN:{name:"India",locale:"en-IN",currency:"INR",decimal:".",group:","},JP:{name:"Japan",locale:"ja-JP",currency:"JPY",decimal:".",group:","},MX:{name:"Mexico",locale:"es-MX",currency:"MXN",decimal:".",group:","},PT:{name:"Portugal",locale:"pt-PT",currency:"EUR",decimal:",",group:"."},SG:{name:"Singapore",locale:"en-SG",currency:"SGD",decimal:".",group:","},US:{name:"United States",locale:"en-US",currency:"USD",decimal:".",group:","}},X={AUD:{name:"Australian Dollar",fractionDigits:2},BRL:{name:"Brazilian Real",fractionDigits:2},CAD:{name:"Canadian Dollar",fractionDigits:2},CHF:{name:"Swiss Franc",fractionDigits:2},CNY:{name:"Chinese Yuan",fractionDigits:2},EUR:{name:"Euro",fractionDigits:2},GBP:{name:"British Pound",fractionDigits:2},INR:{name:"Indian Rupee",fractionDigits:2},JPY:{name:"Japanese Yen",fractionDigits:0},MXN:{name:"Mexican Peso",fractionDigits:2},SGD:{name:"Singapore Dollar",fractionDigits:2},USD:{name:"US Dollar",fractionDigits:2}},j=Object.keys(B).join(", ");function y(r){let n=B[r];if(!n)throw new O(r,j);let{locale:e,currency:t,decimal:o,group:s}=n,{fractionDigits:a}=X[t];return {locale:e,code:t,decimal:o,group:s,fractionDigits:a}}function L(r,n,e={}){let t=e.locale??n.locale,o=e.currencyDisplay==="none",s=e.notation==="compact";return new Intl.NumberFormat(t,{style:o?"decimal":"currency",currency:o?void 0:n.code,currencySign:e.currencySign??"standard",currencyDisplay:o?void 0:e.currencyDisplay??"symbol",notation:e.notation??"standard",compactDisplay:e.compactDisplay??"short",signDisplay:e.signDisplay??"auto",useGrouping:e.useGrouping??true,minimumFractionDigits:e.minimumFractionDigits??(s?0:n.fractionDigits),maximumFractionDigits:e.maximumFractionDigits??(s?Math.min(1,n.fractionDigits):n.fractionDigits),trailingZeroDisplay:e.trailingZeroDisplay??"auto",roundingMode:e.roundingMode??"halfExpand"}).format(r)}var m=class r{#r;#i;#n;[S]=true;constructor(n,e){this.#i=10**e.fractionDigits,this.#r=e,this.#n=n;}static fromMinorUnits(n,e){if(!Number.isFinite(n))throw new i("Expected a finite number of minor units.",{input:n});if(!Number.isInteger(n))throw new i("Minor units must be an integer.",{input:n});if(!Number.isSafeInteger(n))throw new U({input:n});return new r(n,e)}static zero(n){return new r(0,n)}#a(n){if(n.currencyCode()!==this.#r.code)throw new E(this.#r.code,n.currencyCode())}#e(n){return g(n)?(this.#a(n),n.minorUnits()):w(n,this.#r.fractionDigits)}#t(n){if(!Number.isFinite(n))throw new i("Operation produced a non-finite result.",{input:n});if(!Number.isSafeInteger(n))throw new U({input:n});return new r(n,this.#r)}#o(){return new r(this.#n,this.#r)}#s(){return r.zero(this.#r)}minorUnits(){return this.#n}amount(){return this.#n/this.#i}units(){return Math.floor(Math.abs(this.#n)/this.#i)}subunits(){return Math.abs(this.#n)%this.#i}toParts(){return {units:this.units(),subunits:this.subunits(),isNegative:this.isNegative()}}currencyCode(){return this.#r.code}locale(){return this.#r.locale}isZero(){return this.#n===0}isPositive(){return this.#n>0}isNegative(){return this.#n<0}plus(n){return this.#t(this.#n+this.#e(n))}minus(n){return this.#t(this.#n-this.#e(n))}times(n,e=h){if(!Number.isFinite(n))throw new i("Factor must be a finite number.",{input:n});return n===0?this.#s():n===1?this.#o():this.#t(I[e](this.#n*n))}divide(n,e=h){if(n===0)throw new D;if(!Number.isFinite(n))throw new i("Divisor must be a finite number.",{input:n});return n===1?this.#o():this.#t(I[e](this.#n/n))}abs(){return this.#t(Math.abs(this.#n))}negate(){return this.#t(-this.#n)}max(n){let e=this.#e(n);return this.#n>=e?this.#o():this.#t(e)}min(n){let e=this.#e(n);return this.#n<=e?this.#o():this.#t(e)}round(n,e=h){if(!Number.isFinite(n)||n<=0)throw new i("Step must be a positive finite number.",{input:n});if(this.isZero())return this.#o();let t=Math.round(n*this.#i);if(t<1)throw new i("Step is too small to be represented in minor units for this currency.",{input:n});return t===1?this.#o():this.#t(I[e](this.#n/t)*t)}equals(n){return g(n)&&n.currencyCode()!==this.#r.code?false:this.#n===this.#e(n)}compare(n){let e=this.#e(n);return this.#n<e?-1:this.#n>e?1:0}greaterThan(n){return this.#n>this.#e(n)}lessThan(n){return this.#n<this.#e(n)}greaterThanOrEqual(n){return this.#n>=this.#e(n)}lessThanOrEqual(n){return this.#n<=this.#e(n)}isBetween(n,e){let t=this.#e(n),o=this.#e(e);if(t>o)throw new x;return this.#n>=t&&this.#n<=o}hasSameCurrency(n){return g(n)?this.#r.code===n.currencyCode():false}percentOf(n,e=h){if(!Number.isFinite(n))throw new d("Percentage must be a finite number.",{input:n});if(n<0)throw new d("Percentage must be non-negative.",{input:n});return n===0?this.#s():n===100?this.#o():this.#t(I[e](this.#n*(n/100)))}applyDiscount(n,e=h){if(!Number.isFinite(n))throw new d("Discount must be a finite number.",{input:n});if(n<0)throw new d("Discount cannot be negative.",{input:n});if(n>100)throw new d("Discount cannot exceed 100%.",{input:n});return n===0?this.#o():n===100?this.#s():this.minus(this.percentOf(n,e))}applySurcharge(n,e=h){if(!Number.isFinite(n))throw new d("Surcharge must be a finite number.",{input:n});if(n<0)throw new d("Surcharge must be non-negative.",{input:n});return n===0?this.#o():this.plus(this.percentOf(n,e))}allocate(n){if(!Number.isInteger(n)||n<1)throw new b("Number of parts must be a positive integer.");if(n===1)return [this.#o()];if(this.isZero())return Array.from({length:n},()=>this.#s());let t=this.isNegative(),o=Math.abs(this.#n),s=Math.floor(o/n),a=o%n;return Array.from({length:n},(u,M)=>{let C=s+(M<a?1:0);return this.#t(t?-C:C)})}allocateByRatio(n){if(n.length===0||n.some(c=>!Number.isFinite(c)||c<0))throw new b("Ratios must be a non-empty array of non-negative finite numbers.");if(n.some(c=>!Number.isInteger(c)))throw new b("Ratios must be integers. Use whole numbers like [1, 2, 3] or [30, 70].");let o=n.reduce((c,l)=>c+l,0);if(!Number.isSafeInteger(o))throw new b("The sum of ratios exceeds the safe integer range.");if(o===0)throw new b("The sum of ratios cannot be zero.");if(this.isZero())return n.map(()=>this.#s());let s=this.isNegative(),a=Math.abs(this.#n),u=n.map(c=>{let l=a*c;if(!Number.isSafeInteger(l))throw new U({input:l});return Math.floor(l/o)}),M=u.reduce((c,l)=>c+l,0),C=a-M;return u.map((c,l)=>{let A=c+(l<C?1:0);return this.#t(s?-A:A)})}format(n){return L(this.amount(),this.#r,n)}toString(){return `${this.#r.code} ${this.amount().toFixed(this.#r.fractionDigits)}`}toJSON(){return {minorUnits:this.#n,currencyCode:this.#r.code}}};function T(r){if(r==null)throw new i("Value cannot be null or undefined.",{input:r})}function Q(r,n){if(T(r),typeof r!="number")throw new i("Expected a number.",{input:r});let e=y(n),t=w(r,e.fractionDigits);return m.fromMinorUnits(t,e)}function K(r,n){if(T(r),typeof r!="string")throw new i("Expected a string.",{input:r});let e=y(n),t=G(r,e);return m.fromMinorUnits(t,e)}function W(r,n){if(T(r),!Number.isFinite(r))throw new i("fromMinorUnits(): value must be a finite number.",{input:r});if(!Number.isInteger(r))throw new i("fromMinorUnits(): value must be an integer.",{input:r});if(!Number.isSafeInteger(r))throw new i("fromMinorUnits(): value exceeds safe integer range.",{input:r});let e=y(n);return m.fromMinorUnits(r,e)}function R(r){let n=y(r);return m.zero(n)}function N(r){return !Array.isArray(r)||r.length===0}function p(r,n,e){if(r==null)throw new i(`${e} \u2014 value cannot be null or undefined.`,{input:r});if(g(r)){if(r.currencyCode()!==n.code)throw new E(n.code,r.currencyCode());return r.minorUnits()}if(typeof r!="number")throw new i(`${e} \u2014 expected a number or MoneyContract.`,{input:r});try{return w(r,n.fractionDigits)}catch(t){if(t instanceof f)throw t;throw new i(`${e} \u2014 invalid value.`,{input:r,cause:t})}}function nn(r,n){if(N(r))return R(n);let e=y(n),t=r.reduce((o,s,a)=>{if(!F(s))throw new i(`total(): index ${a} \u2014 expected { price, quantity? }.`,{input:s});let{price:u,quantity:M=1}=s;if(!Number.isInteger(M)||M<0)throw new i(`total(): index ${a} \u2014 quantity must be an integer. Fractional quantities produce ambiguous sub-minor-unit values.`,{input:M});let c=p(u,e,`total(): index ${a} \u2014 price`);return o+c*M},0);return m.fromMinorUnits(t,e)}function rn(r,n,e){let t=y(e),o=p(n,t,"percent(): total");if(o===0)throw new D;return p(r,t,"percent(): part")/o*100}function en(r,n){if(N(r))return R(n);let e=y(n),t=r.reduce((o,s,a)=>o+p(s,e,`sum(): index ${a}`),0);return m.fromMinorUnits(t,e)}function tn(r,n,e=h){if(N(r))return R(n);let t=y(n),o=r.reduce((s,a,u)=>s+p(a,t,`average(): index ${u}`),0);return m.fromMinorUnits(I[e](o/r.length),t)}function on(r,n){if(N(r))throw new i("max(): array must have at least one element.",{input:r});let e=y(n),t=r.slice(1).reduce((o,s,a)=>{let u=p(s,e,`max(): index ${a+1}`);return u>o?u:o},p(r[0],e,"max(): index 0"));return m.fromMinorUnits(t,e)}function sn(r,n){if(N(r))throw new i("min(): array must have at least one element.",{input:r});let e=y(n),t=r.slice(1).reduce((o,s,a)=>{let u=p(s,e,`min(): index ${a+1}`);return u<o?u:o},p(r[0],e,"min(): index 0"));return m.fromMinorUnits(t,e)}function an(r,n,e,t){let o=y(t),s=p(n,o,"clamp(): min"),a=p(e,o,"clamp(): max");if(s>a)throw new x;return m.fromMinorUnits(Math.min(Math.max(p(r,o,"clamp(): value"),s),a),o)}var un={};V(un,{average:()=>tn,clamp:()=>an,from:()=>Q,fromMinorUnits:()=>W,isMoney:()=>g,isMoneyInput:()=>v,max:()=>on,min:()=>sn,parse:()=>K,percent:()=>rn,sum:()=>en,total:()=>nn,zero:()=>R});/* v8 ignore if -- @preserve */
18
+ /* v8 ignore next -- @preserve */export{f as a,i as b,d as c,D as d,b as e,x as f,E as g,O as h,U as i,g as j,v as k,Q as l,K as m,W as n,R as o,nn as p,rn as q,en as r,tn as s,on as t,sn as u,an as v,un as w};