@ducatjs/money 0.2.1 → 0.3.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.
Files changed (1332) hide show
  1. package/NOTICE +47 -11
  2. package/README.md +346 -44
  3. package/data/cldr-territories.json +2791 -0
  4. package/data/crypto-units.json +68 -0
  5. package/data/rbnf/de.txt +243 -0
  6. package/data/rbnf/en.txt +166 -0
  7. package/data/rbnf/es.txt +261 -0
  8. package/data/rbnf/fr.txt +159 -0
  9. package/data/rbnf/it.txt +502 -0
  10. package/data/rbnf/nl.txt +103 -0
  11. package/data/rbnf/pt.txt +171 -0
  12. package/dist/adyen-fx.js +1 -1
  13. package/dist/adyen-fx.js.map +1 -1
  14. package/dist/allocate.d.ts.map +1 -1
  15. package/dist/allocate.js +2 -3
  16. package/dist/allocate.js.map +1 -1
  17. package/dist/cash.d.ts +15 -0
  18. package/dist/cash.d.ts.map +1 -1
  19. package/dist/cash.js +17 -0
  20. package/dist/cash.js.map +1 -1
  21. package/dist/convert.d.ts.map +1 -1
  22. package/dist/convert.js +2 -3
  23. package/dist/convert.js.map +1 -1
  24. package/dist/crypto.d.ts +54 -0
  25. package/dist/crypto.d.ts.map +1 -0
  26. package/dist/crypto.js +89 -0
  27. package/dist/crypto.js.map +1 -0
  28. package/dist/currencies.d.ts +43 -0
  29. package/dist/currencies.d.ts.map +1 -0
  30. package/dist/currencies.js +91 -0
  31. package/dist/currencies.js.map +1 -0
  32. package/dist/currency.d.ts +9 -1
  33. package/dist/currency.d.ts.map +1 -1
  34. package/dist/currency.js +41 -14
  35. package/dist/currency.js.map +1 -1
  36. package/dist/decimal.d.ts +25 -3
  37. package/dist/decimal.d.ts.map +1 -1
  38. package/dist/decimal.js +78 -8
  39. package/dist/decimal.js.map +1 -1
  40. package/dist/ecb.d.ts +23 -8
  41. package/dist/ecb.d.ts.map +1 -1
  42. package/dist/ecb.js +46 -15
  43. package/dist/ecb.js.map +1 -1
  44. package/dist/entries/adyen-fx.d.ts +3 -0
  45. package/dist/entries/adyen-fx.d.ts.map +1 -0
  46. package/dist/entries/adyen-fx.js +5 -0
  47. package/dist/entries/adyen-fx.js.map +1 -0
  48. package/dist/entries/boc.d.ts +3 -0
  49. package/dist/entries/boc.d.ts.map +1 -0
  50. package/dist/entries/boc.js +5 -0
  51. package/dist/entries/boc.js.map +1 -0
  52. package/dist/entries/boe.d.ts +3 -0
  53. package/dist/entries/boe.d.ts.map +1 -0
  54. package/dist/entries/boe.js +5 -0
  55. package/dist/entries/boe.js.map +1 -0
  56. package/dist/entries/crypto.d.ts +3 -0
  57. package/dist/entries/crypto.d.ts.map +1 -0
  58. package/dist/entries/crypto.js +5 -0
  59. package/dist/entries/crypto.js.map +1 -0
  60. package/dist/entries/currencies.d.ts +3 -0
  61. package/dist/entries/currencies.d.ts.map +1 -0
  62. package/dist/entries/currencies.js +5 -0
  63. package/dist/entries/currencies.js.map +1 -0
  64. package/dist/entries/drizzle-mysql.d.ts +3 -0
  65. package/dist/entries/drizzle-mysql.d.ts.map +1 -0
  66. package/dist/entries/drizzle-mysql.js +5 -0
  67. package/dist/entries/drizzle-mysql.js.map +1 -0
  68. package/dist/entries/drizzle-pg.d.ts +3 -0
  69. package/dist/entries/drizzle-pg.d.ts.map +1 -0
  70. package/dist/entries/drizzle-pg.js +5 -0
  71. package/dist/entries/drizzle-pg.js.map +1 -0
  72. package/dist/entries/drizzle-sqlite.d.ts +3 -0
  73. package/dist/entries/drizzle-sqlite.d.ts.map +1 -0
  74. package/dist/entries/drizzle-sqlite.js +5 -0
  75. package/dist/entries/drizzle-sqlite.js.map +1 -0
  76. package/dist/entries/ecb.d.ts +3 -0
  77. package/dist/entries/ecb.d.ts.map +1 -0
  78. package/dist/entries/ecb.js +5 -0
  79. package/dist/entries/ecb.js.map +1 -0
  80. package/dist/entries/fed.d.ts +3 -0
  81. package/dist/entries/fed.d.ts.map +1 -0
  82. package/dist/entries/fed.js +5 -0
  83. package/dist/entries/fed.js.map +1 -0
  84. package/dist/entries/fetch.d.ts +3 -0
  85. package/dist/entries/fetch.d.ts.map +1 -0
  86. package/dist/entries/fetch.js +5 -0
  87. package/dist/entries/fetch.js.map +1 -0
  88. package/dist/entries/finance.d.ts +3 -0
  89. package/dist/entries/finance.d.ts.map +1 -0
  90. package/dist/entries/finance.js +5 -0
  91. package/dist/entries/finance.js.map +1 -0
  92. package/dist/entries/historic.d.ts +3 -0
  93. package/dist/entries/historic.d.ts.map +1 -0
  94. package/dist/entries/historic.js +5 -0
  95. package/dist/entries/historic.js.map +1 -0
  96. package/dist/entries/history.d.ts +3 -0
  97. package/dist/entries/history.d.ts.map +1 -0
  98. package/dist/entries/history.js +5 -0
  99. package/dist/entries/history.js.map +1 -0
  100. package/dist/entries/hmrc.d.ts +3 -0
  101. package/dist/entries/hmrc.d.ts.map +1 -0
  102. package/dist/entries/hmrc.js +5 -0
  103. package/dist/entries/hmrc.js.map +1 -0
  104. package/dist/entries/kysely.d.ts +3 -0
  105. package/dist/entries/kysely.d.ts.map +1 -0
  106. package/dist/entries/kysely.js +5 -0
  107. package/dist/entries/kysely.js.map +1 -0
  108. package/dist/entries/parse.d.ts +3 -0
  109. package/dist/entries/parse.d.ts.map +1 -0
  110. package/dist/entries/parse.js +5 -0
  111. package/dist/entries/parse.js.map +1 -0
  112. package/dist/entries/pg.d.ts +3 -0
  113. package/dist/entries/pg.d.ts.map +1 -0
  114. package/dist/entries/pg.js +5 -0
  115. package/dist/entries/pg.js.map +1 -0
  116. package/dist/entries/policy.d.ts +3 -0
  117. package/dist/entries/policy.d.ts.map +1 -0
  118. package/dist/entries/policy.js +5 -0
  119. package/dist/entries/policy.js.map +1 -0
  120. package/dist/entries/pricing.d.ts +3 -0
  121. package/dist/entries/pricing.d.ts.map +1 -0
  122. package/dist/entries/pricing.js +5 -0
  123. package/dist/entries/pricing.js.map +1 -0
  124. package/dist/entries/stripe-fx.d.ts +3 -0
  125. package/dist/entries/stripe-fx.d.ts.map +1 -0
  126. package/dist/entries/stripe-fx.js +5 -0
  127. package/dist/entries/stripe-fx.js.map +1 -0
  128. package/dist/entries/testing-arbitraries.d.ts +3 -0
  129. package/dist/entries/testing-arbitraries.d.ts.map +1 -0
  130. package/dist/entries/testing-arbitraries.js +5 -0
  131. package/dist/entries/testing-arbitraries.js.map +1 -0
  132. package/dist/entries/testing-index.d.ts +3 -0
  133. package/dist/entries/testing-index.d.ts.map +1 -0
  134. package/dist/entries/testing-index.js +5 -0
  135. package/dist/entries/testing-index.js.map +1 -0
  136. package/dist/entries/testing-jest.d.ts +3 -0
  137. package/dist/entries/testing-jest.d.ts.map +1 -0
  138. package/dist/entries/testing-jest.js +5 -0
  139. package/dist/entries/testing-jest.js.map +1 -0
  140. package/dist/entries/testing-vitest.d.ts +3 -0
  141. package/dist/entries/testing-vitest.d.ts.map +1 -0
  142. package/dist/entries/testing-vitest.js +5 -0
  143. package/dist/entries/testing-vitest.js.map +1 -0
  144. package/dist/entries/valibot.d.ts +3 -0
  145. package/dist/entries/valibot.d.ts.map +1 -0
  146. package/dist/entries/valibot.js +5 -0
  147. package/dist/entries/valibot.js.map +1 -0
  148. package/dist/entries/wire.d.ts +3 -0
  149. package/dist/entries/wire.d.ts.map +1 -0
  150. package/dist/entries/wire.js +5 -0
  151. package/dist/entries/wire.js.map +1 -0
  152. package/dist/entries/zod.d.ts +3 -0
  153. package/dist/entries/zod.d.ts.map +1 -0
  154. package/dist/entries/zod.js +5 -0
  155. package/dist/entries/zod.js.map +1 -0
  156. package/dist/exact.d.ts.map +1 -1
  157. package/dist/exact.js +3 -3
  158. package/dist/exact.js.map +1 -1
  159. package/dist/fetch.d.ts +7 -1
  160. package/dist/fetch.d.ts.map +1 -1
  161. package/dist/fetch.js +11 -2
  162. package/dist/fetch.js.map +1 -1
  163. package/dist/finance.d.ts +296 -0
  164. package/dist/finance.d.ts.map +1 -0
  165. package/dist/finance.js +825 -0
  166. package/dist/finance.js.map +1 -0
  167. package/dist/fixed-money.d.ts +12 -0
  168. package/dist/fixed-money.d.ts.map +1 -0
  169. package/dist/fixed-money.js +32 -0
  170. package/dist/fixed-money.js.map +1 -0
  171. package/dist/fixed.d.ts +26 -9
  172. package/dist/fixed.d.ts.map +1 -1
  173. package/dist/fixed.js +75 -49
  174. package/dist/fixed.js.map +1 -1
  175. package/dist/fn.d.ts +17 -1
  176. package/dist/fn.d.ts.map +1 -1
  177. package/dist/fn.js +17 -1
  178. package/dist/fn.js.map +1 -1
  179. package/dist/format.d.ts.map +1 -1
  180. package/dist/format.js +28 -9
  181. package/dist/format.js.map +1 -1
  182. package/dist/generated/crypto.d.ts +58 -0
  183. package/dist/generated/crypto.d.ts.map +1 -0
  184. package/dist/generated/crypto.js +15 -0
  185. package/dist/generated/crypto.js.map +1 -0
  186. package/dist/generated/iso/AED.d.ts +2 -0
  187. package/dist/generated/iso/AED.d.ts.map +1 -0
  188. package/dist/generated/iso/AED.js +5 -0
  189. package/dist/generated/iso/AED.js.map +1 -0
  190. package/dist/generated/iso/AFN.d.ts +2 -0
  191. package/dist/generated/iso/AFN.d.ts.map +1 -0
  192. package/dist/generated/iso/AFN.js +5 -0
  193. package/dist/generated/iso/AFN.js.map +1 -0
  194. package/dist/generated/iso/ALL.d.ts +2 -0
  195. package/dist/generated/iso/ALL.d.ts.map +1 -0
  196. package/dist/generated/iso/ALL.js +5 -0
  197. package/dist/generated/iso/ALL.js.map +1 -0
  198. package/dist/generated/iso/AMD.d.ts +2 -0
  199. package/dist/generated/iso/AMD.d.ts.map +1 -0
  200. package/dist/generated/iso/AMD.js +5 -0
  201. package/dist/generated/iso/AMD.js.map +1 -0
  202. package/dist/generated/iso/AOA.d.ts +2 -0
  203. package/dist/generated/iso/AOA.d.ts.map +1 -0
  204. package/dist/generated/iso/AOA.js +5 -0
  205. package/dist/generated/iso/AOA.js.map +1 -0
  206. package/dist/generated/iso/ARS.d.ts +2 -0
  207. package/dist/generated/iso/ARS.d.ts.map +1 -0
  208. package/dist/generated/iso/ARS.js +5 -0
  209. package/dist/generated/iso/ARS.js.map +1 -0
  210. package/dist/generated/iso/AUD.d.ts +2 -0
  211. package/dist/generated/iso/AUD.d.ts.map +1 -0
  212. package/dist/generated/iso/AUD.js +5 -0
  213. package/dist/generated/iso/AUD.js.map +1 -0
  214. package/dist/generated/iso/AWG.d.ts +2 -0
  215. package/dist/generated/iso/AWG.d.ts.map +1 -0
  216. package/dist/generated/iso/AWG.js +5 -0
  217. package/dist/generated/iso/AWG.js.map +1 -0
  218. package/dist/generated/iso/AZN.d.ts +2 -0
  219. package/dist/generated/iso/AZN.d.ts.map +1 -0
  220. package/dist/generated/iso/AZN.js +5 -0
  221. package/dist/generated/iso/AZN.js.map +1 -0
  222. package/dist/generated/iso/BAM.d.ts +2 -0
  223. package/dist/generated/iso/BAM.d.ts.map +1 -0
  224. package/dist/generated/iso/BAM.js +5 -0
  225. package/dist/generated/iso/BAM.js.map +1 -0
  226. package/dist/generated/iso/BBD.d.ts +2 -0
  227. package/dist/generated/iso/BBD.d.ts.map +1 -0
  228. package/dist/generated/iso/BBD.js +5 -0
  229. package/dist/generated/iso/BBD.js.map +1 -0
  230. package/dist/generated/iso/BDT.d.ts +2 -0
  231. package/dist/generated/iso/BDT.d.ts.map +1 -0
  232. package/dist/generated/iso/BDT.js +5 -0
  233. package/dist/generated/iso/BDT.js.map +1 -0
  234. package/dist/generated/iso/BHD.d.ts +2 -0
  235. package/dist/generated/iso/BHD.d.ts.map +1 -0
  236. package/dist/generated/iso/BHD.js +5 -0
  237. package/dist/generated/iso/BHD.js.map +1 -0
  238. package/dist/generated/iso/BIF.d.ts +2 -0
  239. package/dist/generated/iso/BIF.d.ts.map +1 -0
  240. package/dist/generated/iso/BIF.js +5 -0
  241. package/dist/generated/iso/BIF.js.map +1 -0
  242. package/dist/generated/iso/BMD.d.ts +2 -0
  243. package/dist/generated/iso/BMD.d.ts.map +1 -0
  244. package/dist/generated/iso/BMD.js +5 -0
  245. package/dist/generated/iso/BMD.js.map +1 -0
  246. package/dist/generated/iso/BND.d.ts +2 -0
  247. package/dist/generated/iso/BND.d.ts.map +1 -0
  248. package/dist/generated/iso/BND.js +5 -0
  249. package/dist/generated/iso/BND.js.map +1 -0
  250. package/dist/generated/iso/BOB.d.ts +2 -0
  251. package/dist/generated/iso/BOB.d.ts.map +1 -0
  252. package/dist/generated/iso/BOB.js +5 -0
  253. package/dist/generated/iso/BOB.js.map +1 -0
  254. package/dist/generated/iso/BOV.d.ts +2 -0
  255. package/dist/generated/iso/BOV.d.ts.map +1 -0
  256. package/dist/generated/iso/BOV.js +5 -0
  257. package/dist/generated/iso/BOV.js.map +1 -0
  258. package/dist/generated/iso/BRL.d.ts +2 -0
  259. package/dist/generated/iso/BRL.d.ts.map +1 -0
  260. package/dist/generated/iso/BRL.js +5 -0
  261. package/dist/generated/iso/BRL.js.map +1 -0
  262. package/dist/generated/iso/BSD.d.ts +2 -0
  263. package/dist/generated/iso/BSD.d.ts.map +1 -0
  264. package/dist/generated/iso/BSD.js +5 -0
  265. package/dist/generated/iso/BSD.js.map +1 -0
  266. package/dist/generated/iso/BTN.d.ts +2 -0
  267. package/dist/generated/iso/BTN.d.ts.map +1 -0
  268. package/dist/generated/iso/BTN.js +5 -0
  269. package/dist/generated/iso/BTN.js.map +1 -0
  270. package/dist/generated/iso/BWP.d.ts +2 -0
  271. package/dist/generated/iso/BWP.d.ts.map +1 -0
  272. package/dist/generated/iso/BWP.js +5 -0
  273. package/dist/generated/iso/BWP.js.map +1 -0
  274. package/dist/generated/iso/BYN.d.ts +2 -0
  275. package/dist/generated/iso/BYN.d.ts.map +1 -0
  276. package/dist/generated/iso/BYN.js +5 -0
  277. package/dist/generated/iso/BYN.js.map +1 -0
  278. package/dist/generated/iso/BZD.d.ts +2 -0
  279. package/dist/generated/iso/BZD.d.ts.map +1 -0
  280. package/dist/generated/iso/BZD.js +5 -0
  281. package/dist/generated/iso/BZD.js.map +1 -0
  282. package/dist/generated/iso/CAD.d.ts +2 -0
  283. package/dist/generated/iso/CAD.d.ts.map +1 -0
  284. package/dist/generated/iso/CAD.js +5 -0
  285. package/dist/generated/iso/CAD.js.map +1 -0
  286. package/dist/generated/iso/CDF.d.ts +2 -0
  287. package/dist/generated/iso/CDF.d.ts.map +1 -0
  288. package/dist/generated/iso/CDF.js +5 -0
  289. package/dist/generated/iso/CDF.js.map +1 -0
  290. package/dist/generated/iso/CHE.d.ts +2 -0
  291. package/dist/generated/iso/CHE.d.ts.map +1 -0
  292. package/dist/generated/iso/CHE.js +5 -0
  293. package/dist/generated/iso/CHE.js.map +1 -0
  294. package/dist/generated/iso/CHF.d.ts +2 -0
  295. package/dist/generated/iso/CHF.d.ts.map +1 -0
  296. package/dist/generated/iso/CHF.js +5 -0
  297. package/dist/generated/iso/CHF.js.map +1 -0
  298. package/dist/generated/iso/CHW.d.ts +2 -0
  299. package/dist/generated/iso/CHW.d.ts.map +1 -0
  300. package/dist/generated/iso/CHW.js +5 -0
  301. package/dist/generated/iso/CHW.js.map +1 -0
  302. package/dist/generated/iso/CLF.d.ts +2 -0
  303. package/dist/generated/iso/CLF.d.ts.map +1 -0
  304. package/dist/generated/iso/CLF.js +5 -0
  305. package/dist/generated/iso/CLF.js.map +1 -0
  306. package/dist/generated/iso/CLP.d.ts +2 -0
  307. package/dist/generated/iso/CLP.d.ts.map +1 -0
  308. package/dist/generated/iso/CLP.js +5 -0
  309. package/dist/generated/iso/CLP.js.map +1 -0
  310. package/dist/generated/iso/CNY.d.ts +2 -0
  311. package/dist/generated/iso/CNY.d.ts.map +1 -0
  312. package/dist/generated/iso/CNY.js +5 -0
  313. package/dist/generated/iso/CNY.js.map +1 -0
  314. package/dist/generated/iso/COP.d.ts +2 -0
  315. package/dist/generated/iso/COP.d.ts.map +1 -0
  316. package/dist/generated/iso/COP.js +5 -0
  317. package/dist/generated/iso/COP.js.map +1 -0
  318. package/dist/generated/iso/COU.d.ts +2 -0
  319. package/dist/generated/iso/COU.d.ts.map +1 -0
  320. package/dist/generated/iso/COU.js +5 -0
  321. package/dist/generated/iso/COU.js.map +1 -0
  322. package/dist/generated/iso/CRC.d.ts +2 -0
  323. package/dist/generated/iso/CRC.d.ts.map +1 -0
  324. package/dist/generated/iso/CRC.js +5 -0
  325. package/dist/generated/iso/CRC.js.map +1 -0
  326. package/dist/generated/iso/CUP.d.ts +2 -0
  327. package/dist/generated/iso/CUP.d.ts.map +1 -0
  328. package/dist/generated/iso/CUP.js +5 -0
  329. package/dist/generated/iso/CUP.js.map +1 -0
  330. package/dist/generated/iso/CVE.d.ts +2 -0
  331. package/dist/generated/iso/CVE.d.ts.map +1 -0
  332. package/dist/generated/iso/CVE.js +5 -0
  333. package/dist/generated/iso/CVE.js.map +1 -0
  334. package/dist/generated/iso/CZK.d.ts +2 -0
  335. package/dist/generated/iso/CZK.d.ts.map +1 -0
  336. package/dist/generated/iso/CZK.js +5 -0
  337. package/dist/generated/iso/CZK.js.map +1 -0
  338. package/dist/generated/iso/DJF.d.ts +2 -0
  339. package/dist/generated/iso/DJF.d.ts.map +1 -0
  340. package/dist/generated/iso/DJF.js +5 -0
  341. package/dist/generated/iso/DJF.js.map +1 -0
  342. package/dist/generated/iso/DKK.d.ts +2 -0
  343. package/dist/generated/iso/DKK.d.ts.map +1 -0
  344. package/dist/generated/iso/DKK.js +5 -0
  345. package/dist/generated/iso/DKK.js.map +1 -0
  346. package/dist/generated/iso/DOP.d.ts +2 -0
  347. package/dist/generated/iso/DOP.d.ts.map +1 -0
  348. package/dist/generated/iso/DOP.js +5 -0
  349. package/dist/generated/iso/DOP.js.map +1 -0
  350. package/dist/generated/iso/DZD.d.ts +2 -0
  351. package/dist/generated/iso/DZD.d.ts.map +1 -0
  352. package/dist/generated/iso/DZD.js +5 -0
  353. package/dist/generated/iso/DZD.js.map +1 -0
  354. package/dist/generated/iso/EGP.d.ts +2 -0
  355. package/dist/generated/iso/EGP.d.ts.map +1 -0
  356. package/dist/generated/iso/EGP.js +5 -0
  357. package/dist/generated/iso/EGP.js.map +1 -0
  358. package/dist/generated/iso/ERN.d.ts +2 -0
  359. package/dist/generated/iso/ERN.d.ts.map +1 -0
  360. package/dist/generated/iso/ERN.js +5 -0
  361. package/dist/generated/iso/ERN.js.map +1 -0
  362. package/dist/generated/iso/ETB.d.ts +2 -0
  363. package/dist/generated/iso/ETB.d.ts.map +1 -0
  364. package/dist/generated/iso/ETB.js +5 -0
  365. package/dist/generated/iso/ETB.js.map +1 -0
  366. package/dist/generated/iso/EUR.d.ts +2 -0
  367. package/dist/generated/iso/EUR.d.ts.map +1 -0
  368. package/dist/generated/iso/EUR.js +5 -0
  369. package/dist/generated/iso/EUR.js.map +1 -0
  370. package/dist/generated/iso/FJD.d.ts +2 -0
  371. package/dist/generated/iso/FJD.d.ts.map +1 -0
  372. package/dist/generated/iso/FJD.js +5 -0
  373. package/dist/generated/iso/FJD.js.map +1 -0
  374. package/dist/generated/iso/FKP.d.ts +2 -0
  375. package/dist/generated/iso/FKP.d.ts.map +1 -0
  376. package/dist/generated/iso/FKP.js +5 -0
  377. package/dist/generated/iso/FKP.js.map +1 -0
  378. package/dist/generated/iso/GBP.d.ts +2 -0
  379. package/dist/generated/iso/GBP.d.ts.map +1 -0
  380. package/dist/generated/iso/GBP.js +5 -0
  381. package/dist/generated/iso/GBP.js.map +1 -0
  382. package/dist/generated/iso/GEL.d.ts +2 -0
  383. package/dist/generated/iso/GEL.d.ts.map +1 -0
  384. package/dist/generated/iso/GEL.js +5 -0
  385. package/dist/generated/iso/GEL.js.map +1 -0
  386. package/dist/generated/iso/GHS.d.ts +2 -0
  387. package/dist/generated/iso/GHS.d.ts.map +1 -0
  388. package/dist/generated/iso/GHS.js +5 -0
  389. package/dist/generated/iso/GHS.js.map +1 -0
  390. package/dist/generated/iso/GIP.d.ts +2 -0
  391. package/dist/generated/iso/GIP.d.ts.map +1 -0
  392. package/dist/generated/iso/GIP.js +5 -0
  393. package/dist/generated/iso/GIP.js.map +1 -0
  394. package/dist/generated/iso/GMD.d.ts +2 -0
  395. package/dist/generated/iso/GMD.d.ts.map +1 -0
  396. package/dist/generated/iso/GMD.js +5 -0
  397. package/dist/generated/iso/GMD.js.map +1 -0
  398. package/dist/generated/iso/GNF.d.ts +2 -0
  399. package/dist/generated/iso/GNF.d.ts.map +1 -0
  400. package/dist/generated/iso/GNF.js +5 -0
  401. package/dist/generated/iso/GNF.js.map +1 -0
  402. package/dist/generated/iso/GTQ.d.ts +2 -0
  403. package/dist/generated/iso/GTQ.d.ts.map +1 -0
  404. package/dist/generated/iso/GTQ.js +5 -0
  405. package/dist/generated/iso/GTQ.js.map +1 -0
  406. package/dist/generated/iso/GYD.d.ts +2 -0
  407. package/dist/generated/iso/GYD.d.ts.map +1 -0
  408. package/dist/generated/iso/GYD.js +5 -0
  409. package/dist/generated/iso/GYD.js.map +1 -0
  410. package/dist/generated/iso/HKD.d.ts +2 -0
  411. package/dist/generated/iso/HKD.d.ts.map +1 -0
  412. package/dist/generated/iso/HKD.js +5 -0
  413. package/dist/generated/iso/HKD.js.map +1 -0
  414. package/dist/generated/iso/HNL.d.ts +2 -0
  415. package/dist/generated/iso/HNL.d.ts.map +1 -0
  416. package/dist/generated/iso/HNL.js +5 -0
  417. package/dist/generated/iso/HNL.js.map +1 -0
  418. package/dist/generated/iso/HTG.d.ts +2 -0
  419. package/dist/generated/iso/HTG.d.ts.map +1 -0
  420. package/dist/generated/iso/HTG.js +5 -0
  421. package/dist/generated/iso/HTG.js.map +1 -0
  422. package/dist/generated/iso/HUF.d.ts +2 -0
  423. package/dist/generated/iso/HUF.d.ts.map +1 -0
  424. package/dist/generated/iso/HUF.js +5 -0
  425. package/dist/generated/iso/HUF.js.map +1 -0
  426. package/dist/generated/iso/IDR.d.ts +2 -0
  427. package/dist/generated/iso/IDR.d.ts.map +1 -0
  428. package/dist/generated/iso/IDR.js +5 -0
  429. package/dist/generated/iso/IDR.js.map +1 -0
  430. package/dist/generated/iso/ILS.d.ts +2 -0
  431. package/dist/generated/iso/ILS.d.ts.map +1 -0
  432. package/dist/generated/iso/ILS.js +5 -0
  433. package/dist/generated/iso/ILS.js.map +1 -0
  434. package/dist/generated/iso/INR.d.ts +2 -0
  435. package/dist/generated/iso/INR.d.ts.map +1 -0
  436. package/dist/generated/iso/INR.js +5 -0
  437. package/dist/generated/iso/INR.js.map +1 -0
  438. package/dist/generated/iso/IQD.d.ts +2 -0
  439. package/dist/generated/iso/IQD.d.ts.map +1 -0
  440. package/dist/generated/iso/IQD.js +5 -0
  441. package/dist/generated/iso/IQD.js.map +1 -0
  442. package/dist/generated/iso/IRR.d.ts +2 -0
  443. package/dist/generated/iso/IRR.d.ts.map +1 -0
  444. package/dist/generated/iso/IRR.js +5 -0
  445. package/dist/generated/iso/IRR.js.map +1 -0
  446. package/dist/generated/iso/ISK.d.ts +2 -0
  447. package/dist/generated/iso/ISK.d.ts.map +1 -0
  448. package/dist/generated/iso/ISK.js +5 -0
  449. package/dist/generated/iso/ISK.js.map +1 -0
  450. package/dist/generated/iso/JMD.d.ts +2 -0
  451. package/dist/generated/iso/JMD.d.ts.map +1 -0
  452. package/dist/generated/iso/JMD.js +5 -0
  453. package/dist/generated/iso/JMD.js.map +1 -0
  454. package/dist/generated/iso/JOD.d.ts +2 -0
  455. package/dist/generated/iso/JOD.d.ts.map +1 -0
  456. package/dist/generated/iso/JOD.js +5 -0
  457. package/dist/generated/iso/JOD.js.map +1 -0
  458. package/dist/generated/iso/JPY.d.ts +2 -0
  459. package/dist/generated/iso/JPY.d.ts.map +1 -0
  460. package/dist/generated/iso/JPY.js +5 -0
  461. package/dist/generated/iso/JPY.js.map +1 -0
  462. package/dist/generated/iso/KES.d.ts +2 -0
  463. package/dist/generated/iso/KES.d.ts.map +1 -0
  464. package/dist/generated/iso/KES.js +5 -0
  465. package/dist/generated/iso/KES.js.map +1 -0
  466. package/dist/generated/iso/KGS.d.ts +2 -0
  467. package/dist/generated/iso/KGS.d.ts.map +1 -0
  468. package/dist/generated/iso/KGS.js +5 -0
  469. package/dist/generated/iso/KGS.js.map +1 -0
  470. package/dist/generated/iso/KHR.d.ts +2 -0
  471. package/dist/generated/iso/KHR.d.ts.map +1 -0
  472. package/dist/generated/iso/KHR.js +5 -0
  473. package/dist/generated/iso/KHR.js.map +1 -0
  474. package/dist/generated/iso/KMF.d.ts +2 -0
  475. package/dist/generated/iso/KMF.d.ts.map +1 -0
  476. package/dist/generated/iso/KMF.js +5 -0
  477. package/dist/generated/iso/KMF.js.map +1 -0
  478. package/dist/generated/iso/KPW.d.ts +2 -0
  479. package/dist/generated/iso/KPW.d.ts.map +1 -0
  480. package/dist/generated/iso/KPW.js +5 -0
  481. package/dist/generated/iso/KPW.js.map +1 -0
  482. package/dist/generated/iso/KRW.d.ts +2 -0
  483. package/dist/generated/iso/KRW.d.ts.map +1 -0
  484. package/dist/generated/iso/KRW.js +5 -0
  485. package/dist/generated/iso/KRW.js.map +1 -0
  486. package/dist/generated/iso/KWD.d.ts +2 -0
  487. package/dist/generated/iso/KWD.d.ts.map +1 -0
  488. package/dist/generated/iso/KWD.js +5 -0
  489. package/dist/generated/iso/KWD.js.map +1 -0
  490. package/dist/generated/iso/KYD.d.ts +2 -0
  491. package/dist/generated/iso/KYD.d.ts.map +1 -0
  492. package/dist/generated/iso/KYD.js +5 -0
  493. package/dist/generated/iso/KYD.js.map +1 -0
  494. package/dist/generated/iso/KZT.d.ts +2 -0
  495. package/dist/generated/iso/KZT.d.ts.map +1 -0
  496. package/dist/generated/iso/KZT.js +5 -0
  497. package/dist/generated/iso/KZT.js.map +1 -0
  498. package/dist/generated/iso/LAK.d.ts +2 -0
  499. package/dist/generated/iso/LAK.d.ts.map +1 -0
  500. package/dist/generated/iso/LAK.js +5 -0
  501. package/dist/generated/iso/LAK.js.map +1 -0
  502. package/dist/generated/iso/LBP.d.ts +2 -0
  503. package/dist/generated/iso/LBP.d.ts.map +1 -0
  504. package/dist/generated/iso/LBP.js +5 -0
  505. package/dist/generated/iso/LBP.js.map +1 -0
  506. package/dist/generated/iso/LKR.d.ts +2 -0
  507. package/dist/generated/iso/LKR.d.ts.map +1 -0
  508. package/dist/generated/iso/LKR.js +5 -0
  509. package/dist/generated/iso/LKR.js.map +1 -0
  510. package/dist/generated/iso/LRD.d.ts +2 -0
  511. package/dist/generated/iso/LRD.d.ts.map +1 -0
  512. package/dist/generated/iso/LRD.js +5 -0
  513. package/dist/generated/iso/LRD.js.map +1 -0
  514. package/dist/generated/iso/LSL.d.ts +2 -0
  515. package/dist/generated/iso/LSL.d.ts.map +1 -0
  516. package/dist/generated/iso/LSL.js +5 -0
  517. package/dist/generated/iso/LSL.js.map +1 -0
  518. package/dist/generated/iso/LYD.d.ts +2 -0
  519. package/dist/generated/iso/LYD.d.ts.map +1 -0
  520. package/dist/generated/iso/LYD.js +5 -0
  521. package/dist/generated/iso/LYD.js.map +1 -0
  522. package/dist/generated/iso/MAD.d.ts +2 -0
  523. package/dist/generated/iso/MAD.d.ts.map +1 -0
  524. package/dist/generated/iso/MAD.js +5 -0
  525. package/dist/generated/iso/MAD.js.map +1 -0
  526. package/dist/generated/iso/MDL.d.ts +2 -0
  527. package/dist/generated/iso/MDL.d.ts.map +1 -0
  528. package/dist/generated/iso/MDL.js +5 -0
  529. package/dist/generated/iso/MDL.js.map +1 -0
  530. package/dist/generated/iso/MGA.d.ts +2 -0
  531. package/dist/generated/iso/MGA.d.ts.map +1 -0
  532. package/dist/generated/iso/MGA.js +5 -0
  533. package/dist/generated/iso/MGA.js.map +1 -0
  534. package/dist/generated/iso/MKD.d.ts +2 -0
  535. package/dist/generated/iso/MKD.d.ts.map +1 -0
  536. package/dist/generated/iso/MKD.js +5 -0
  537. package/dist/generated/iso/MKD.js.map +1 -0
  538. package/dist/generated/iso/MMK.d.ts +2 -0
  539. package/dist/generated/iso/MMK.d.ts.map +1 -0
  540. package/dist/generated/iso/MMK.js +5 -0
  541. package/dist/generated/iso/MMK.js.map +1 -0
  542. package/dist/generated/iso/MNT.d.ts +2 -0
  543. package/dist/generated/iso/MNT.d.ts.map +1 -0
  544. package/dist/generated/iso/MNT.js +5 -0
  545. package/dist/generated/iso/MNT.js.map +1 -0
  546. package/dist/generated/iso/MOP.d.ts +2 -0
  547. package/dist/generated/iso/MOP.d.ts.map +1 -0
  548. package/dist/generated/iso/MOP.js +5 -0
  549. package/dist/generated/iso/MOP.js.map +1 -0
  550. package/dist/generated/iso/MRU.d.ts +2 -0
  551. package/dist/generated/iso/MRU.d.ts.map +1 -0
  552. package/dist/generated/iso/MRU.js +5 -0
  553. package/dist/generated/iso/MRU.js.map +1 -0
  554. package/dist/generated/iso/MUR.d.ts +2 -0
  555. package/dist/generated/iso/MUR.d.ts.map +1 -0
  556. package/dist/generated/iso/MUR.js +5 -0
  557. package/dist/generated/iso/MUR.js.map +1 -0
  558. package/dist/generated/iso/MVR.d.ts +2 -0
  559. package/dist/generated/iso/MVR.d.ts.map +1 -0
  560. package/dist/generated/iso/MVR.js +5 -0
  561. package/dist/generated/iso/MVR.js.map +1 -0
  562. package/dist/generated/iso/MWK.d.ts +2 -0
  563. package/dist/generated/iso/MWK.d.ts.map +1 -0
  564. package/dist/generated/iso/MWK.js +5 -0
  565. package/dist/generated/iso/MWK.js.map +1 -0
  566. package/dist/generated/iso/MXN.d.ts +2 -0
  567. package/dist/generated/iso/MXN.d.ts.map +1 -0
  568. package/dist/generated/iso/MXN.js +5 -0
  569. package/dist/generated/iso/MXN.js.map +1 -0
  570. package/dist/generated/iso/MXV.d.ts +2 -0
  571. package/dist/generated/iso/MXV.d.ts.map +1 -0
  572. package/dist/generated/iso/MXV.js +5 -0
  573. package/dist/generated/iso/MXV.js.map +1 -0
  574. package/dist/generated/iso/MYR.d.ts +2 -0
  575. package/dist/generated/iso/MYR.d.ts.map +1 -0
  576. package/dist/generated/iso/MYR.js +5 -0
  577. package/dist/generated/iso/MYR.js.map +1 -0
  578. package/dist/generated/iso/MZN.d.ts +2 -0
  579. package/dist/generated/iso/MZN.d.ts.map +1 -0
  580. package/dist/generated/iso/MZN.js +5 -0
  581. package/dist/generated/iso/MZN.js.map +1 -0
  582. package/dist/generated/iso/NAD.d.ts +2 -0
  583. package/dist/generated/iso/NAD.d.ts.map +1 -0
  584. package/dist/generated/iso/NAD.js +5 -0
  585. package/dist/generated/iso/NAD.js.map +1 -0
  586. package/dist/generated/iso/NGN.d.ts +2 -0
  587. package/dist/generated/iso/NGN.d.ts.map +1 -0
  588. package/dist/generated/iso/NGN.js +5 -0
  589. package/dist/generated/iso/NGN.js.map +1 -0
  590. package/dist/generated/iso/NIO.d.ts +2 -0
  591. package/dist/generated/iso/NIO.d.ts.map +1 -0
  592. package/dist/generated/iso/NIO.js +5 -0
  593. package/dist/generated/iso/NIO.js.map +1 -0
  594. package/dist/generated/iso/NOK.d.ts +2 -0
  595. package/dist/generated/iso/NOK.d.ts.map +1 -0
  596. package/dist/generated/iso/NOK.js +5 -0
  597. package/dist/generated/iso/NOK.js.map +1 -0
  598. package/dist/generated/iso/NPR.d.ts +2 -0
  599. package/dist/generated/iso/NPR.d.ts.map +1 -0
  600. package/dist/generated/iso/NPR.js +5 -0
  601. package/dist/generated/iso/NPR.js.map +1 -0
  602. package/dist/generated/iso/NZD.d.ts +2 -0
  603. package/dist/generated/iso/NZD.d.ts.map +1 -0
  604. package/dist/generated/iso/NZD.js +5 -0
  605. package/dist/generated/iso/NZD.js.map +1 -0
  606. package/dist/generated/iso/OMR.d.ts +2 -0
  607. package/dist/generated/iso/OMR.d.ts.map +1 -0
  608. package/dist/generated/iso/OMR.js +5 -0
  609. package/dist/generated/iso/OMR.js.map +1 -0
  610. package/dist/generated/iso/PAB.d.ts +2 -0
  611. package/dist/generated/iso/PAB.d.ts.map +1 -0
  612. package/dist/generated/iso/PAB.js +5 -0
  613. package/dist/generated/iso/PAB.js.map +1 -0
  614. package/dist/generated/iso/PEN.d.ts +2 -0
  615. package/dist/generated/iso/PEN.d.ts.map +1 -0
  616. package/dist/generated/iso/PEN.js +5 -0
  617. package/dist/generated/iso/PEN.js.map +1 -0
  618. package/dist/generated/iso/PGK.d.ts +2 -0
  619. package/dist/generated/iso/PGK.d.ts.map +1 -0
  620. package/dist/generated/iso/PGK.js +5 -0
  621. package/dist/generated/iso/PGK.js.map +1 -0
  622. package/dist/generated/iso/PHP.d.ts +2 -0
  623. package/dist/generated/iso/PHP.d.ts.map +1 -0
  624. package/dist/generated/iso/PHP.js +5 -0
  625. package/dist/generated/iso/PHP.js.map +1 -0
  626. package/dist/generated/iso/PKR.d.ts +2 -0
  627. package/dist/generated/iso/PKR.d.ts.map +1 -0
  628. package/dist/generated/iso/PKR.js +5 -0
  629. package/dist/generated/iso/PKR.js.map +1 -0
  630. package/dist/generated/iso/PLN.d.ts +2 -0
  631. package/dist/generated/iso/PLN.d.ts.map +1 -0
  632. package/dist/generated/iso/PLN.js +5 -0
  633. package/dist/generated/iso/PLN.js.map +1 -0
  634. package/dist/generated/iso/PYG.d.ts +2 -0
  635. package/dist/generated/iso/PYG.d.ts.map +1 -0
  636. package/dist/generated/iso/PYG.js +5 -0
  637. package/dist/generated/iso/PYG.js.map +1 -0
  638. package/dist/generated/iso/QAR.d.ts +2 -0
  639. package/dist/generated/iso/QAR.d.ts.map +1 -0
  640. package/dist/generated/iso/QAR.js +5 -0
  641. package/dist/generated/iso/QAR.js.map +1 -0
  642. package/dist/generated/iso/RON.d.ts +2 -0
  643. package/dist/generated/iso/RON.d.ts.map +1 -0
  644. package/dist/generated/iso/RON.js +5 -0
  645. package/dist/generated/iso/RON.js.map +1 -0
  646. package/dist/generated/iso/RSD.d.ts +2 -0
  647. package/dist/generated/iso/RSD.d.ts.map +1 -0
  648. package/dist/generated/iso/RSD.js +5 -0
  649. package/dist/generated/iso/RSD.js.map +1 -0
  650. package/dist/generated/iso/RUB.d.ts +2 -0
  651. package/dist/generated/iso/RUB.d.ts.map +1 -0
  652. package/dist/generated/iso/RUB.js +5 -0
  653. package/dist/generated/iso/RUB.js.map +1 -0
  654. package/dist/generated/iso/RWF.d.ts +2 -0
  655. package/dist/generated/iso/RWF.d.ts.map +1 -0
  656. package/dist/generated/iso/RWF.js +5 -0
  657. package/dist/generated/iso/RWF.js.map +1 -0
  658. package/dist/generated/iso/SAR.d.ts +2 -0
  659. package/dist/generated/iso/SAR.d.ts.map +1 -0
  660. package/dist/generated/iso/SAR.js +5 -0
  661. package/dist/generated/iso/SAR.js.map +1 -0
  662. package/dist/generated/iso/SBD.d.ts +2 -0
  663. package/dist/generated/iso/SBD.d.ts.map +1 -0
  664. package/dist/generated/iso/SBD.js +5 -0
  665. package/dist/generated/iso/SBD.js.map +1 -0
  666. package/dist/generated/iso/SCR.d.ts +2 -0
  667. package/dist/generated/iso/SCR.d.ts.map +1 -0
  668. package/dist/generated/iso/SCR.js +5 -0
  669. package/dist/generated/iso/SCR.js.map +1 -0
  670. package/dist/generated/iso/SDG.d.ts +2 -0
  671. package/dist/generated/iso/SDG.d.ts.map +1 -0
  672. package/dist/generated/iso/SDG.js +5 -0
  673. package/dist/generated/iso/SDG.js.map +1 -0
  674. package/dist/generated/iso/SEK.d.ts +2 -0
  675. package/dist/generated/iso/SEK.d.ts.map +1 -0
  676. package/dist/generated/iso/SEK.js +5 -0
  677. package/dist/generated/iso/SEK.js.map +1 -0
  678. package/dist/generated/iso/SGD.d.ts +2 -0
  679. package/dist/generated/iso/SGD.d.ts.map +1 -0
  680. package/dist/generated/iso/SGD.js +5 -0
  681. package/dist/generated/iso/SGD.js.map +1 -0
  682. package/dist/generated/iso/SHP.d.ts +2 -0
  683. package/dist/generated/iso/SHP.d.ts.map +1 -0
  684. package/dist/generated/iso/SHP.js +5 -0
  685. package/dist/generated/iso/SHP.js.map +1 -0
  686. package/dist/generated/iso/SLE.d.ts +2 -0
  687. package/dist/generated/iso/SLE.d.ts.map +1 -0
  688. package/dist/generated/iso/SLE.js +5 -0
  689. package/dist/generated/iso/SLE.js.map +1 -0
  690. package/dist/generated/iso/SOS.d.ts +2 -0
  691. package/dist/generated/iso/SOS.d.ts.map +1 -0
  692. package/dist/generated/iso/SOS.js +5 -0
  693. package/dist/generated/iso/SOS.js.map +1 -0
  694. package/dist/generated/iso/SRD.d.ts +2 -0
  695. package/dist/generated/iso/SRD.d.ts.map +1 -0
  696. package/dist/generated/iso/SRD.js +5 -0
  697. package/dist/generated/iso/SRD.js.map +1 -0
  698. package/dist/generated/iso/SSP.d.ts +2 -0
  699. package/dist/generated/iso/SSP.d.ts.map +1 -0
  700. package/dist/generated/iso/SSP.js +5 -0
  701. package/dist/generated/iso/SSP.js.map +1 -0
  702. package/dist/generated/iso/STN.d.ts +2 -0
  703. package/dist/generated/iso/STN.d.ts.map +1 -0
  704. package/dist/generated/iso/STN.js +5 -0
  705. package/dist/generated/iso/STN.js.map +1 -0
  706. package/dist/generated/iso/SVC.d.ts +2 -0
  707. package/dist/generated/iso/SVC.d.ts.map +1 -0
  708. package/dist/generated/iso/SVC.js +5 -0
  709. package/dist/generated/iso/SVC.js.map +1 -0
  710. package/dist/generated/iso/SYP.d.ts +2 -0
  711. package/dist/generated/iso/SYP.d.ts.map +1 -0
  712. package/dist/generated/iso/SYP.js +5 -0
  713. package/dist/generated/iso/SYP.js.map +1 -0
  714. package/dist/generated/iso/SZL.d.ts +2 -0
  715. package/dist/generated/iso/SZL.d.ts.map +1 -0
  716. package/dist/generated/iso/SZL.js +5 -0
  717. package/dist/generated/iso/SZL.js.map +1 -0
  718. package/dist/generated/iso/THB.d.ts +2 -0
  719. package/dist/generated/iso/THB.d.ts.map +1 -0
  720. package/dist/generated/iso/THB.js +5 -0
  721. package/dist/generated/iso/THB.js.map +1 -0
  722. package/dist/generated/iso/TJS.d.ts +2 -0
  723. package/dist/generated/iso/TJS.d.ts.map +1 -0
  724. package/dist/generated/iso/TJS.js +5 -0
  725. package/dist/generated/iso/TJS.js.map +1 -0
  726. package/dist/generated/iso/TMT.d.ts +2 -0
  727. package/dist/generated/iso/TMT.d.ts.map +1 -0
  728. package/dist/generated/iso/TMT.js +5 -0
  729. package/dist/generated/iso/TMT.js.map +1 -0
  730. package/dist/generated/iso/TND.d.ts +2 -0
  731. package/dist/generated/iso/TND.d.ts.map +1 -0
  732. package/dist/generated/iso/TND.js +5 -0
  733. package/dist/generated/iso/TND.js.map +1 -0
  734. package/dist/generated/iso/TOP.d.ts +2 -0
  735. package/dist/generated/iso/TOP.d.ts.map +1 -0
  736. package/dist/generated/iso/TOP.js +5 -0
  737. package/dist/generated/iso/TOP.js.map +1 -0
  738. package/dist/generated/iso/TRY.d.ts +2 -0
  739. package/dist/generated/iso/TRY.d.ts.map +1 -0
  740. package/dist/generated/iso/TRY.js +5 -0
  741. package/dist/generated/iso/TRY.js.map +1 -0
  742. package/dist/generated/iso/TTD.d.ts +2 -0
  743. package/dist/generated/iso/TTD.d.ts.map +1 -0
  744. package/dist/generated/iso/TTD.js +5 -0
  745. package/dist/generated/iso/TTD.js.map +1 -0
  746. package/dist/generated/iso/TWD.d.ts +2 -0
  747. package/dist/generated/iso/TWD.d.ts.map +1 -0
  748. package/dist/generated/iso/TWD.js +5 -0
  749. package/dist/generated/iso/TWD.js.map +1 -0
  750. package/dist/generated/iso/TZS.d.ts +2 -0
  751. package/dist/generated/iso/TZS.d.ts.map +1 -0
  752. package/dist/generated/iso/TZS.js +5 -0
  753. package/dist/generated/iso/TZS.js.map +1 -0
  754. package/dist/generated/iso/UAH.d.ts +2 -0
  755. package/dist/generated/iso/UAH.d.ts.map +1 -0
  756. package/dist/generated/iso/UAH.js +5 -0
  757. package/dist/generated/iso/UAH.js.map +1 -0
  758. package/dist/generated/iso/UGX.d.ts +2 -0
  759. package/dist/generated/iso/UGX.d.ts.map +1 -0
  760. package/dist/generated/iso/UGX.js +5 -0
  761. package/dist/generated/iso/UGX.js.map +1 -0
  762. package/dist/generated/iso/USD.d.ts +2 -0
  763. package/dist/generated/iso/USD.d.ts.map +1 -0
  764. package/dist/generated/iso/USD.js +5 -0
  765. package/dist/generated/iso/USD.js.map +1 -0
  766. package/dist/generated/iso/USN.d.ts +2 -0
  767. package/dist/generated/iso/USN.d.ts.map +1 -0
  768. package/dist/generated/iso/USN.js +5 -0
  769. package/dist/generated/iso/USN.js.map +1 -0
  770. package/dist/generated/iso/UYI.d.ts +2 -0
  771. package/dist/generated/iso/UYI.d.ts.map +1 -0
  772. package/dist/generated/iso/UYI.js +5 -0
  773. package/dist/generated/iso/UYI.js.map +1 -0
  774. package/dist/generated/iso/UYU.d.ts +2 -0
  775. package/dist/generated/iso/UYU.d.ts.map +1 -0
  776. package/dist/generated/iso/UYU.js +5 -0
  777. package/dist/generated/iso/UYU.js.map +1 -0
  778. package/dist/generated/iso/UYW.d.ts +2 -0
  779. package/dist/generated/iso/UYW.d.ts.map +1 -0
  780. package/dist/generated/iso/UYW.js +5 -0
  781. package/dist/generated/iso/UYW.js.map +1 -0
  782. package/dist/generated/iso/UZS.d.ts +2 -0
  783. package/dist/generated/iso/UZS.d.ts.map +1 -0
  784. package/dist/generated/iso/UZS.js +5 -0
  785. package/dist/generated/iso/UZS.js.map +1 -0
  786. package/dist/generated/iso/VED.d.ts +2 -0
  787. package/dist/generated/iso/VED.d.ts.map +1 -0
  788. package/dist/generated/iso/VED.js +5 -0
  789. package/dist/generated/iso/VED.js.map +1 -0
  790. package/dist/generated/iso/VES.d.ts +2 -0
  791. package/dist/generated/iso/VES.d.ts.map +1 -0
  792. package/dist/generated/iso/VES.js +5 -0
  793. package/dist/generated/iso/VES.js.map +1 -0
  794. package/dist/generated/iso/VND.d.ts +2 -0
  795. package/dist/generated/iso/VND.d.ts.map +1 -0
  796. package/dist/generated/iso/VND.js +5 -0
  797. package/dist/generated/iso/VND.js.map +1 -0
  798. package/dist/generated/iso/VUV.d.ts +2 -0
  799. package/dist/generated/iso/VUV.d.ts.map +1 -0
  800. package/dist/generated/iso/VUV.js +5 -0
  801. package/dist/generated/iso/VUV.js.map +1 -0
  802. package/dist/generated/iso/WST.d.ts +2 -0
  803. package/dist/generated/iso/WST.d.ts.map +1 -0
  804. package/dist/generated/iso/WST.js +5 -0
  805. package/dist/generated/iso/WST.js.map +1 -0
  806. package/dist/generated/iso/XAD.d.ts +2 -0
  807. package/dist/generated/iso/XAD.d.ts.map +1 -0
  808. package/dist/generated/iso/XAD.js +5 -0
  809. package/dist/generated/iso/XAD.js.map +1 -0
  810. package/dist/generated/iso/XAF.d.ts +2 -0
  811. package/dist/generated/iso/XAF.d.ts.map +1 -0
  812. package/dist/generated/iso/XAF.js +5 -0
  813. package/dist/generated/iso/XAF.js.map +1 -0
  814. package/dist/generated/iso/XCD.d.ts +2 -0
  815. package/dist/generated/iso/XCD.d.ts.map +1 -0
  816. package/dist/generated/iso/XCD.js +5 -0
  817. package/dist/generated/iso/XCD.js.map +1 -0
  818. package/dist/generated/iso/XCG.d.ts +2 -0
  819. package/dist/generated/iso/XCG.d.ts.map +1 -0
  820. package/dist/generated/iso/XCG.js +5 -0
  821. package/dist/generated/iso/XCG.js.map +1 -0
  822. package/dist/generated/iso/XOF.d.ts +2 -0
  823. package/dist/generated/iso/XOF.d.ts.map +1 -0
  824. package/dist/generated/iso/XOF.js +5 -0
  825. package/dist/generated/iso/XOF.js.map +1 -0
  826. package/dist/generated/iso/XPF.d.ts +2 -0
  827. package/dist/generated/iso/XPF.d.ts.map +1 -0
  828. package/dist/generated/iso/XPF.js +5 -0
  829. package/dist/generated/iso/XPF.js.map +1 -0
  830. package/dist/generated/iso/YER.d.ts +2 -0
  831. package/dist/generated/iso/YER.d.ts.map +1 -0
  832. package/dist/generated/iso/YER.js +5 -0
  833. package/dist/generated/iso/YER.js.map +1 -0
  834. package/dist/generated/iso/ZAR.d.ts +2 -0
  835. package/dist/generated/iso/ZAR.d.ts.map +1 -0
  836. package/dist/generated/iso/ZAR.js +5 -0
  837. package/dist/generated/iso/ZAR.js.map +1 -0
  838. package/dist/generated/iso/ZMW.d.ts +2 -0
  839. package/dist/generated/iso/ZMW.d.ts.map +1 -0
  840. package/dist/generated/iso/ZMW.js +5 -0
  841. package/dist/generated/iso/ZMW.js.map +1 -0
  842. package/dist/generated/iso/ZWG.d.ts +2 -0
  843. package/dist/generated/iso/ZWG.d.ts.map +1 -0
  844. package/dist/generated/iso/ZWG.js +5 -0
  845. package/dist/generated/iso/ZWG.js.map +1 -0
  846. package/dist/generated/iso4217-numeric.d.ts +3 -0
  847. package/dist/generated/iso4217-numeric.d.ts.map +1 -0
  848. package/dist/generated/iso4217-numeric.js +184 -0
  849. package/dist/generated/iso4217-numeric.js.map +1 -0
  850. package/dist/generated/rbnf-de.d.ts +3 -0
  851. package/dist/generated/rbnf-de.d.ts.map +1 -0
  852. package/dist/generated/rbnf-de.js +5 -0
  853. package/dist/generated/rbnf-de.js.map +1 -0
  854. package/dist/generated/rbnf-en.d.ts +3 -0
  855. package/dist/generated/rbnf-en.d.ts.map +1 -0
  856. package/dist/generated/rbnf-en.js +5 -0
  857. package/dist/generated/rbnf-en.js.map +1 -0
  858. package/dist/generated/rbnf-es.d.ts +3 -0
  859. package/dist/generated/rbnf-es.d.ts.map +1 -0
  860. package/dist/generated/rbnf-es.js +5 -0
  861. package/dist/generated/rbnf-es.js.map +1 -0
  862. package/dist/generated/rbnf-fr.d.ts +3 -0
  863. package/dist/generated/rbnf-fr.d.ts.map +1 -0
  864. package/dist/generated/rbnf-fr.js +5 -0
  865. package/dist/generated/rbnf-fr.js.map +1 -0
  866. package/dist/generated/rbnf-it.d.ts +3 -0
  867. package/dist/generated/rbnf-it.d.ts.map +1 -0
  868. package/dist/generated/rbnf-it.js +5 -0
  869. package/dist/generated/rbnf-it.js.map +1 -0
  870. package/dist/generated/rbnf-nl.d.ts +3 -0
  871. package/dist/generated/rbnf-nl.d.ts.map +1 -0
  872. package/dist/generated/rbnf-nl.js +5 -0
  873. package/dist/generated/rbnf-nl.js.map +1 -0
  874. package/dist/generated/rbnf-pt.d.ts +3 -0
  875. package/dist/generated/rbnf-pt.d.ts.map +1 -0
  876. package/dist/generated/rbnf-pt.js +5 -0
  877. package/dist/generated/rbnf-pt.js.map +1 -0
  878. package/dist/generated/territories.d.ts +6 -0
  879. package/dist/generated/territories.d.ts.map +1 -0
  880. package/dist/generated/territories.js +275 -0
  881. package/dist/generated/territories.js.map +1 -0
  882. package/dist/index.d.ts +1 -0
  883. package/dist/index.d.ts.map +1 -1
  884. package/dist/index.js +2 -0
  885. package/dist/index.js.map +1 -1
  886. package/dist/kysely.d.ts.map +1 -1
  887. package/dist/kysely.js +2 -2
  888. package/dist/kysely.js.map +1 -1
  889. package/dist/math.d.ts +41 -0
  890. package/dist/math.d.ts.map +1 -0
  891. package/dist/math.js +132 -0
  892. package/dist/math.js.map +1 -0
  893. package/dist/money.d.ts +39 -57
  894. package/dist/money.d.ts.map +1 -1
  895. package/dist/money.js +118 -128
  896. package/dist/money.js.map +1 -1
  897. package/dist/parse.js +7 -7
  898. package/dist/parse.js.map +1 -1
  899. package/dist/plugins/adyen.d.ts +2 -0
  900. package/dist/plugins/adyen.d.ts.map +1 -1
  901. package/dist/plugins/adyen.js +2 -0
  902. package/dist/plugins/adyen.js.map +1 -1
  903. package/dist/plugins/all.d.ts +18 -2
  904. package/dist/plugins/all.d.ts.map +1 -1
  905. package/dist/plugins/all.js +19 -2
  906. package/dist/plugins/all.js.map +1 -1
  907. package/dist/plugins/allocate.d.ts +1 -0
  908. package/dist/plugins/allocate.d.ts.map +1 -1
  909. package/dist/plugins/allocate.js +2 -0
  910. package/dist/plugins/allocate.js.map +1 -1
  911. package/dist/plugins/braintree.d.ts +1 -0
  912. package/dist/plugins/braintree.d.ts.map +1 -1
  913. package/dist/plugins/braintree.js +2 -0
  914. package/dist/plugins/braintree.js.map +1 -1
  915. package/dist/plugins/cash.d.ts +1 -0
  916. package/dist/plugins/cash.d.ts.map +1 -1
  917. package/dist/plugins/cash.js +2 -0
  918. package/dist/plugins/cash.js.map +1 -1
  919. package/dist/plugins/checkout.d.ts +1 -0
  920. package/dist/plugins/checkout.d.ts.map +1 -1
  921. package/dist/plugins/checkout.js +2 -0
  922. package/dist/plugins/checkout.js.map +1 -1
  923. package/dist/plugins/convert.d.ts +5 -0
  924. package/dist/plugins/convert.d.ts.map +1 -1
  925. package/dist/plugins/convert.js +2 -0
  926. package/dist/plugins/convert.js.map +1 -1
  927. package/dist/plugins/core.d.ts +78 -0
  928. package/dist/plugins/core.d.ts.map +1 -0
  929. package/dist/plugins/core.js +104 -0
  930. package/dist/plugins/core.js.map +1 -0
  931. package/dist/plugins/exact.d.ts +1 -0
  932. package/dist/plugins/exact.d.ts.map +1 -1
  933. package/dist/plugins/exact.js +2 -0
  934. package/dist/plugins/exact.js.map +1 -1
  935. package/dist/plugins/fixed-money.d.ts +31 -0
  936. package/dist/plugins/fixed-money.d.ts.map +1 -0
  937. package/dist/plugins/fixed-money.js +29 -0
  938. package/dist/plugins/fixed-money.js.map +1 -0
  939. package/dist/plugins/format.d.ts +5 -0
  940. package/dist/plugins/format.d.ts.map +1 -1
  941. package/dist/plugins/format.js +2 -0
  942. package/dist/plugins/format.js.map +1 -1
  943. package/dist/plugins/iso.d.ts +2 -0
  944. package/dist/plugins/iso.d.ts.map +1 -0
  945. package/dist/plugins/iso.js +9 -0
  946. package/dist/plugins/iso.js.map +1 -0
  947. package/dist/plugins/klarna.d.ts +1 -0
  948. package/dist/plugins/klarna.d.ts.map +1 -1
  949. package/dist/plugins/klarna.js +2 -0
  950. package/dist/plugins/klarna.js.map +1 -1
  951. package/dist/plugins/math.d.ts +20 -0
  952. package/dist/plugins/math.d.ts.map +1 -0
  953. package/dist/plugins/math.js +24 -0
  954. package/dist/plugins/math.js.map +1 -0
  955. package/dist/plugins/paypal.d.ts +5 -0
  956. package/dist/plugins/paypal.d.ts.map +1 -1
  957. package/dist/plugins/paypal.js +6 -0
  958. package/dist/plugins/paypal.js.map +1 -1
  959. package/dist/plugins/prisma.d.ts +5 -0
  960. package/dist/plugins/prisma.d.ts.map +1 -1
  961. package/dist/plugins/prisma.js +6 -0
  962. package/dist/plugins/prisma.js.map +1 -1
  963. package/dist/plugins/stripe.d.ts +5 -0
  964. package/dist/plugins/stripe.d.ts.map +1 -1
  965. package/dist/plugins/stripe.js +6 -0
  966. package/dist/plugins/stripe.js.map +1 -1
  967. package/dist/plugins/tax.d.ts +1 -0
  968. package/dist/plugins/tax.d.ts.map +1 -1
  969. package/dist/plugins/tax.js +6 -0
  970. package/dist/plugins/tax.js.map +1 -1
  971. package/dist/policy.d.ts.map +1 -1
  972. package/dist/policy.js +5 -6
  973. package/dist/policy.js.map +1 -1
  974. package/dist/pricing.d.ts +52 -0
  975. package/dist/pricing.d.ts.map +1 -0
  976. package/dist/pricing.js +100 -0
  977. package/dist/pricing.js.map +1 -0
  978. package/dist/prisma.d.ts.map +1 -1
  979. package/dist/prisma.js +6 -2
  980. package/dist/prisma.js.map +1 -1
  981. package/dist/provider.js +2 -2
  982. package/dist/provider.js.map +1 -1
  983. package/dist/rate-text.d.ts +6 -0
  984. package/dist/rate-text.d.ts.map +1 -1
  985. package/dist/rate-text.js +24 -1
  986. package/dist/rate-text.js.map +1 -1
  987. package/dist/rate.d.ts.map +1 -1
  988. package/dist/rate.js +2 -3
  989. package/dist/rate.js.map +1 -1
  990. package/dist/rbnf.d.ts +29 -0
  991. package/dist/rbnf.d.ts.map +1 -0
  992. package/dist/rbnf.js +301 -0
  993. package/dist/rbnf.js.map +1 -0
  994. package/dist/rounding.d.ts +15 -0
  995. package/dist/rounding.d.ts.map +1 -1
  996. package/dist/rounding.js +32 -0
  997. package/dist/rounding.js.map +1 -1
  998. package/dist/scale.d.ts +8 -0
  999. package/dist/scale.d.ts.map +1 -0
  1000. package/dist/scale.js +34 -0
  1001. package/dist/scale.js.map +1 -0
  1002. package/dist/schema.d.ts.map +1 -1
  1003. package/dist/schema.js +4 -5
  1004. package/dist/schema.js.map +1 -1
  1005. package/dist/territories.d.ts +40 -0
  1006. package/dist/territories.d.ts.map +1 -0
  1007. package/dist/territories.js +71 -0
  1008. package/dist/territories.js.map +1 -0
  1009. package/dist/testing/arbitraries.d.ts.map +1 -1
  1010. package/dist/testing/arbitraries.js +4 -4
  1011. package/dist/testing/arbitraries.js.map +1 -1
  1012. package/dist/testing/index.js +1 -1
  1013. package/dist/testing/index.js.map +1 -1
  1014. package/dist/tiers.d.ts +95 -0
  1015. package/dist/tiers.d.ts.map +1 -0
  1016. package/dist/tiers.js +173 -0
  1017. package/dist/tiers.js.map +1 -0
  1018. package/dist/valibot.d.ts.map +1 -1
  1019. package/dist/valibot.js +4 -1
  1020. package/dist/valibot.js.map +1 -1
  1021. package/dist/wire.d.ts +105 -0
  1022. package/dist/wire.d.ts.map +1 -0
  1023. package/dist/wire.js +212 -0
  1024. package/dist/wire.js.map +1 -0
  1025. package/dist/words/de.d.ts +4 -0
  1026. package/dist/words/de.d.ts.map +1 -0
  1027. package/dist/words/de.js +8 -0
  1028. package/dist/words/de.js.map +1 -0
  1029. package/dist/words/en.d.ts +4 -0
  1030. package/dist/words/en.d.ts.map +1 -0
  1031. package/dist/words/en.js +8 -0
  1032. package/dist/words/en.js.map +1 -0
  1033. package/dist/words/es.d.ts +4 -0
  1034. package/dist/words/es.d.ts.map +1 -0
  1035. package/dist/words/es.js +8 -0
  1036. package/dist/words/es.js.map +1 -0
  1037. package/dist/words/fr.d.ts +4 -0
  1038. package/dist/words/fr.d.ts.map +1 -0
  1039. package/dist/words/fr.js +8 -0
  1040. package/dist/words/fr.js.map +1 -0
  1041. package/dist/words/it.d.ts +4 -0
  1042. package/dist/words/it.d.ts.map +1 -0
  1043. package/dist/words/it.js +8 -0
  1044. package/dist/words/it.js.map +1 -0
  1045. package/dist/words/nl.d.ts +4 -0
  1046. package/dist/words/nl.d.ts.map +1 -0
  1047. package/dist/words/nl.js +8 -0
  1048. package/dist/words/nl.js.map +1 -0
  1049. package/dist/words/pt.d.ts +4 -0
  1050. package/dist/words/pt.d.ts.map +1 -0
  1051. package/dist/words/pt.js +8 -0
  1052. package/dist/words/pt.js.map +1 -0
  1053. package/dist/words.d.ts +63 -0
  1054. package/dist/words.d.ts.map +1 -0
  1055. package/dist/words.js +107 -0
  1056. package/dist/words.js.map +1 -0
  1057. package/dist/zod.d.ts.map +1 -1
  1058. package/dist/zod.js +1 -1
  1059. package/dist/zod.js.map +1 -1
  1060. package/package.json +312 -54
  1061. package/src/adyen-fx.ts +1 -1
  1062. package/src/allocate.ts +4 -3
  1063. package/src/cash.ts +26 -0
  1064. package/src/convert.ts +2 -3
  1065. package/src/crypto.ts +129 -0
  1066. package/src/currencies.ts +123 -0
  1067. package/src/currency.ts +45 -14
  1068. package/src/decimal.ts +98 -10
  1069. package/src/ecb.ts +75 -16
  1070. package/src/entries/adyen-fx.ts +5 -0
  1071. package/src/entries/boc.ts +5 -0
  1072. package/src/entries/boe.ts +5 -0
  1073. package/src/entries/crypto.ts +5 -0
  1074. package/src/entries/currencies.ts +5 -0
  1075. package/src/entries/drizzle-mysql.ts +5 -0
  1076. package/src/entries/drizzle-pg.ts +5 -0
  1077. package/src/entries/drizzle-sqlite.ts +5 -0
  1078. package/src/entries/ecb.ts +5 -0
  1079. package/src/entries/fed.ts +5 -0
  1080. package/src/entries/fetch.ts +5 -0
  1081. package/src/entries/finance.ts +5 -0
  1082. package/src/entries/historic.ts +5 -0
  1083. package/src/entries/history.ts +5 -0
  1084. package/src/entries/hmrc.ts +5 -0
  1085. package/src/entries/kysely.ts +5 -0
  1086. package/src/entries/parse.ts +5 -0
  1087. package/src/entries/pg.ts +5 -0
  1088. package/src/entries/policy.ts +5 -0
  1089. package/src/entries/pricing.ts +5 -0
  1090. package/src/entries/stripe-fx.ts +5 -0
  1091. package/src/entries/testing-arbitraries.ts +5 -0
  1092. package/src/entries/testing-index.ts +5 -0
  1093. package/src/entries/testing-jest.ts +5 -0
  1094. package/src/entries/testing-vitest.ts +5 -0
  1095. package/src/entries/valibot.ts +5 -0
  1096. package/src/entries/wire.ts +5 -0
  1097. package/src/entries/zod.ts +5 -0
  1098. package/src/exact.ts +3 -3
  1099. package/src/fetch.ts +20 -4
  1100. package/src/finance.ts +1219 -0
  1101. package/src/fixed-money.ts +38 -0
  1102. package/src/fixed.ts +86 -66
  1103. package/src/fn.ts +17 -0
  1104. package/src/format.ts +28 -9
  1105. package/src/generated/crypto.ts +15 -0
  1106. package/src/generated/iso/AED.ts +5 -0
  1107. package/src/generated/iso/AFN.ts +5 -0
  1108. package/src/generated/iso/ALL.ts +5 -0
  1109. package/src/generated/iso/AMD.ts +5 -0
  1110. package/src/generated/iso/AOA.ts +5 -0
  1111. package/src/generated/iso/ARS.ts +5 -0
  1112. package/src/generated/iso/AUD.ts +5 -0
  1113. package/src/generated/iso/AWG.ts +5 -0
  1114. package/src/generated/iso/AZN.ts +5 -0
  1115. package/src/generated/iso/BAM.ts +5 -0
  1116. package/src/generated/iso/BBD.ts +5 -0
  1117. package/src/generated/iso/BDT.ts +5 -0
  1118. package/src/generated/iso/BHD.ts +5 -0
  1119. package/src/generated/iso/BIF.ts +5 -0
  1120. package/src/generated/iso/BMD.ts +5 -0
  1121. package/src/generated/iso/BND.ts +5 -0
  1122. package/src/generated/iso/BOB.ts +5 -0
  1123. package/src/generated/iso/BOV.ts +5 -0
  1124. package/src/generated/iso/BRL.ts +5 -0
  1125. package/src/generated/iso/BSD.ts +5 -0
  1126. package/src/generated/iso/BTN.ts +5 -0
  1127. package/src/generated/iso/BWP.ts +5 -0
  1128. package/src/generated/iso/BYN.ts +5 -0
  1129. package/src/generated/iso/BZD.ts +5 -0
  1130. package/src/generated/iso/CAD.ts +5 -0
  1131. package/src/generated/iso/CDF.ts +5 -0
  1132. package/src/generated/iso/CHE.ts +5 -0
  1133. package/src/generated/iso/CHF.ts +5 -0
  1134. package/src/generated/iso/CHW.ts +5 -0
  1135. package/src/generated/iso/CLF.ts +5 -0
  1136. package/src/generated/iso/CLP.ts +5 -0
  1137. package/src/generated/iso/CNY.ts +5 -0
  1138. package/src/generated/iso/COP.ts +5 -0
  1139. package/src/generated/iso/COU.ts +5 -0
  1140. package/src/generated/iso/CRC.ts +5 -0
  1141. package/src/generated/iso/CUP.ts +5 -0
  1142. package/src/generated/iso/CVE.ts +5 -0
  1143. package/src/generated/iso/CZK.ts +5 -0
  1144. package/src/generated/iso/DJF.ts +5 -0
  1145. package/src/generated/iso/DKK.ts +5 -0
  1146. package/src/generated/iso/DOP.ts +5 -0
  1147. package/src/generated/iso/DZD.ts +5 -0
  1148. package/src/generated/iso/EGP.ts +5 -0
  1149. package/src/generated/iso/ERN.ts +5 -0
  1150. package/src/generated/iso/ETB.ts +5 -0
  1151. package/src/generated/iso/EUR.ts +5 -0
  1152. package/src/generated/iso/FJD.ts +5 -0
  1153. package/src/generated/iso/FKP.ts +5 -0
  1154. package/src/generated/iso/GBP.ts +5 -0
  1155. package/src/generated/iso/GEL.ts +5 -0
  1156. package/src/generated/iso/GHS.ts +5 -0
  1157. package/src/generated/iso/GIP.ts +5 -0
  1158. package/src/generated/iso/GMD.ts +5 -0
  1159. package/src/generated/iso/GNF.ts +5 -0
  1160. package/src/generated/iso/GTQ.ts +5 -0
  1161. package/src/generated/iso/GYD.ts +5 -0
  1162. package/src/generated/iso/HKD.ts +5 -0
  1163. package/src/generated/iso/HNL.ts +5 -0
  1164. package/src/generated/iso/HTG.ts +5 -0
  1165. package/src/generated/iso/HUF.ts +5 -0
  1166. package/src/generated/iso/IDR.ts +5 -0
  1167. package/src/generated/iso/ILS.ts +5 -0
  1168. package/src/generated/iso/INR.ts +5 -0
  1169. package/src/generated/iso/IQD.ts +5 -0
  1170. package/src/generated/iso/IRR.ts +5 -0
  1171. package/src/generated/iso/ISK.ts +5 -0
  1172. package/src/generated/iso/JMD.ts +5 -0
  1173. package/src/generated/iso/JOD.ts +5 -0
  1174. package/src/generated/iso/JPY.ts +5 -0
  1175. package/src/generated/iso/KES.ts +5 -0
  1176. package/src/generated/iso/KGS.ts +5 -0
  1177. package/src/generated/iso/KHR.ts +5 -0
  1178. package/src/generated/iso/KMF.ts +5 -0
  1179. package/src/generated/iso/KPW.ts +5 -0
  1180. package/src/generated/iso/KRW.ts +5 -0
  1181. package/src/generated/iso/KWD.ts +5 -0
  1182. package/src/generated/iso/KYD.ts +5 -0
  1183. package/src/generated/iso/KZT.ts +5 -0
  1184. package/src/generated/iso/LAK.ts +5 -0
  1185. package/src/generated/iso/LBP.ts +5 -0
  1186. package/src/generated/iso/LKR.ts +5 -0
  1187. package/src/generated/iso/LRD.ts +5 -0
  1188. package/src/generated/iso/LSL.ts +5 -0
  1189. package/src/generated/iso/LYD.ts +5 -0
  1190. package/src/generated/iso/MAD.ts +5 -0
  1191. package/src/generated/iso/MDL.ts +5 -0
  1192. package/src/generated/iso/MGA.ts +5 -0
  1193. package/src/generated/iso/MKD.ts +5 -0
  1194. package/src/generated/iso/MMK.ts +5 -0
  1195. package/src/generated/iso/MNT.ts +5 -0
  1196. package/src/generated/iso/MOP.ts +5 -0
  1197. package/src/generated/iso/MRU.ts +5 -0
  1198. package/src/generated/iso/MUR.ts +5 -0
  1199. package/src/generated/iso/MVR.ts +5 -0
  1200. package/src/generated/iso/MWK.ts +5 -0
  1201. package/src/generated/iso/MXN.ts +5 -0
  1202. package/src/generated/iso/MXV.ts +5 -0
  1203. package/src/generated/iso/MYR.ts +5 -0
  1204. package/src/generated/iso/MZN.ts +5 -0
  1205. package/src/generated/iso/NAD.ts +5 -0
  1206. package/src/generated/iso/NGN.ts +5 -0
  1207. package/src/generated/iso/NIO.ts +5 -0
  1208. package/src/generated/iso/NOK.ts +5 -0
  1209. package/src/generated/iso/NPR.ts +5 -0
  1210. package/src/generated/iso/NZD.ts +5 -0
  1211. package/src/generated/iso/OMR.ts +5 -0
  1212. package/src/generated/iso/PAB.ts +5 -0
  1213. package/src/generated/iso/PEN.ts +5 -0
  1214. package/src/generated/iso/PGK.ts +5 -0
  1215. package/src/generated/iso/PHP.ts +5 -0
  1216. package/src/generated/iso/PKR.ts +5 -0
  1217. package/src/generated/iso/PLN.ts +5 -0
  1218. package/src/generated/iso/PYG.ts +5 -0
  1219. package/src/generated/iso/QAR.ts +5 -0
  1220. package/src/generated/iso/RON.ts +5 -0
  1221. package/src/generated/iso/RSD.ts +5 -0
  1222. package/src/generated/iso/RUB.ts +5 -0
  1223. package/src/generated/iso/RWF.ts +5 -0
  1224. package/src/generated/iso/SAR.ts +5 -0
  1225. package/src/generated/iso/SBD.ts +5 -0
  1226. package/src/generated/iso/SCR.ts +5 -0
  1227. package/src/generated/iso/SDG.ts +5 -0
  1228. package/src/generated/iso/SEK.ts +5 -0
  1229. package/src/generated/iso/SGD.ts +5 -0
  1230. package/src/generated/iso/SHP.ts +5 -0
  1231. package/src/generated/iso/SLE.ts +5 -0
  1232. package/src/generated/iso/SOS.ts +5 -0
  1233. package/src/generated/iso/SRD.ts +5 -0
  1234. package/src/generated/iso/SSP.ts +5 -0
  1235. package/src/generated/iso/STN.ts +5 -0
  1236. package/src/generated/iso/SVC.ts +5 -0
  1237. package/src/generated/iso/SYP.ts +5 -0
  1238. package/src/generated/iso/SZL.ts +5 -0
  1239. package/src/generated/iso/THB.ts +5 -0
  1240. package/src/generated/iso/TJS.ts +5 -0
  1241. package/src/generated/iso/TMT.ts +5 -0
  1242. package/src/generated/iso/TND.ts +5 -0
  1243. package/src/generated/iso/TOP.ts +5 -0
  1244. package/src/generated/iso/TRY.ts +5 -0
  1245. package/src/generated/iso/TTD.ts +5 -0
  1246. package/src/generated/iso/TWD.ts +5 -0
  1247. package/src/generated/iso/TZS.ts +5 -0
  1248. package/src/generated/iso/UAH.ts +5 -0
  1249. package/src/generated/iso/UGX.ts +5 -0
  1250. package/src/generated/iso/USD.ts +5 -0
  1251. package/src/generated/iso/USN.ts +5 -0
  1252. package/src/generated/iso/UYI.ts +5 -0
  1253. package/src/generated/iso/UYU.ts +5 -0
  1254. package/src/generated/iso/UYW.ts +5 -0
  1255. package/src/generated/iso/UZS.ts +5 -0
  1256. package/src/generated/iso/VED.ts +5 -0
  1257. package/src/generated/iso/VES.ts +5 -0
  1258. package/src/generated/iso/VND.ts +5 -0
  1259. package/src/generated/iso/VUV.ts +5 -0
  1260. package/src/generated/iso/WST.ts +5 -0
  1261. package/src/generated/iso/XAD.ts +5 -0
  1262. package/src/generated/iso/XAF.ts +5 -0
  1263. package/src/generated/iso/XCD.ts +5 -0
  1264. package/src/generated/iso/XCG.ts +5 -0
  1265. package/src/generated/iso/XOF.ts +5 -0
  1266. package/src/generated/iso/XPF.ts +5 -0
  1267. package/src/generated/iso/YER.ts +5 -0
  1268. package/src/generated/iso/ZAR.ts +5 -0
  1269. package/src/generated/iso/ZMW.ts +5 -0
  1270. package/src/generated/iso/ZWG.ts +5 -0
  1271. package/src/generated/iso4217-numeric.ts +184 -0
  1272. package/src/generated/rbnf-de.ts +5 -0
  1273. package/src/generated/rbnf-en.ts +5 -0
  1274. package/src/generated/rbnf-es.ts +5 -0
  1275. package/src/generated/rbnf-fr.ts +5 -0
  1276. package/src/generated/rbnf-it.ts +5 -0
  1277. package/src/generated/rbnf-nl.ts +5 -0
  1278. package/src/generated/rbnf-pt.ts +5 -0
  1279. package/src/generated/territories.ts +277 -0
  1280. package/src/index.ts +3 -0
  1281. package/src/kysely.ts +4 -3
  1282. package/src/math.ts +167 -0
  1283. package/src/money.ts +138 -140
  1284. package/src/parse.ts +7 -7
  1285. package/src/plugins/adyen.ts +2 -0
  1286. package/src/plugins/all.ts +19 -1
  1287. package/src/plugins/allocate.ts +2 -0
  1288. package/src/plugins/braintree.ts +2 -0
  1289. package/src/plugins/cash.ts +2 -0
  1290. package/src/plugins/checkout.ts +2 -0
  1291. package/src/plugins/convert.ts +2 -0
  1292. package/src/plugins/core.ts +195 -0
  1293. package/src/plugins/exact.ts +2 -0
  1294. package/src/plugins/fixed-money.ts +57 -0
  1295. package/src/plugins/format.ts +2 -0
  1296. package/src/plugins/iso.ts +9 -0
  1297. package/src/plugins/klarna.ts +2 -0
  1298. package/src/plugins/math.ts +43 -0
  1299. package/src/plugins/paypal.ts +2 -0
  1300. package/src/plugins/prisma.ts +2 -0
  1301. package/src/plugins/stripe.ts +2 -0
  1302. package/src/plugins/tax.ts +2 -0
  1303. package/src/policy.ts +5 -8
  1304. package/src/pricing.ts +155 -0
  1305. package/src/prisma.ts +6 -1
  1306. package/src/provider.ts +2 -2
  1307. package/src/rate-text.ts +27 -1
  1308. package/src/rate.ts +2 -2
  1309. package/src/rbnf.ts +389 -0
  1310. package/src/rounding.ts +34 -0
  1311. package/src/scale.ts +42 -0
  1312. package/src/schema.ts +4 -7
  1313. package/src/territories.ts +102 -0
  1314. package/src/testing/arbitraries.ts +4 -4
  1315. package/src/testing/index.ts +1 -1
  1316. package/src/tiers.ts +284 -0
  1317. package/src/valibot.ts +4 -1
  1318. package/src/wire.ts +322 -0
  1319. package/src/words/de.ts +9 -0
  1320. package/src/words/en.ts +9 -0
  1321. package/src/words/es.ts +9 -0
  1322. package/src/words/fr.ts +9 -0
  1323. package/src/words/it.ts +9 -0
  1324. package/src/words/nl.ts +9 -0
  1325. package/src/words/pt.ts +9 -0
  1326. package/src/words.ts +168 -0
  1327. package/src/zod.ts +1 -1
  1328. package/dist/plugins/fixed.d.ts +0 -17
  1329. package/dist/plugins/fixed.d.ts.map +0 -1
  1330. package/dist/plugins/fixed.js +0 -13
  1331. package/dist/plugins/fixed.js.map +0 -1
  1332. package/src/plugins/fixed.ts +0 -29
package/src/finance.ts ADDED
@@ -0,0 +1,1219 @@
1
+ /**
2
+ * `@ducatjs/money/finance`: day counts, simple and compound interest, loan schedules, NPV and IRR,
3
+ * and subscription proration, in exact arithmetic. Every amount that is paid or booked is rounded
4
+ * once from its exact value; nothing in between is rounded, and no floats are used. Dates are
5
+ * calendar dates ('YYYY-MM-DD' or `{ year, month, day }`, so a `Temporal.PlainDate` works), never
6
+ * `Date`. Free functions only: nothing is added to Money.
7
+ */
8
+ import { currencyExponent } from './currency.js';
9
+ import { formatScaled, pow10n, ratio, type Factor, type Ratio } from './decimal.js';
10
+ import { ExactMoney, exact } from './exact.js';
11
+ import { allocate, instalments, type Remainder } from './allocate.js';
12
+ import {
13
+ add,
14
+ compare,
15
+ CurrencyMismatchError,
16
+ make,
17
+ multiplyByRatio,
18
+ subtract,
19
+ sum,
20
+ type Money,
21
+ type RoundingInput,
22
+ } from './money.js';
23
+ import { DEFAULT_ROUNDING } from './rounding.js';
24
+
25
+ // ---------------------------------------------------------------------------------------------
26
+ // Calendar dates
27
+ // ---------------------------------------------------------------------------------------------
28
+
29
+ /**
30
+ * A calendar date: a 'YYYY-MM-DD' string or an object with `year`, `month` (1-12) and `day`
31
+ * fields, such as a `Temporal.PlainDate` in the ISO calendar. Proleptic Gregorian, years 0 to 9999,
32
+ * no time and no time zone.
33
+ */
34
+ export type CalendarDate =
35
+ | string
36
+ | { readonly year: number; readonly month: number; readonly day: number };
37
+
38
+ /** A calendar date split into its fields, checked. */
39
+ interface DateFields {
40
+ readonly year: number;
41
+ readonly month: number;
42
+ readonly day: number;
43
+ }
44
+
45
+ const DATE_RE = /^(\d{4})-(\d{2})-(\d{2})$/;
46
+
47
+ function isLeapYear(year: number): boolean {
48
+ return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
49
+ }
50
+
51
+ function daysInMonth(year: number, month: number): number {
52
+ if (month === 2) {
53
+ return isLeapYear(year) ? 29 : 28;
54
+ }
55
+ // April, June, September and November have 30 days
56
+ return month === 4 || month === 6 || month === 9 || month === 11 ? 30 : 31;
57
+ }
58
+
59
+ function daysInYear(year: number): number {
60
+ return isLeapYear(year) ? 366 : 365;
61
+ }
62
+
63
+ /** The fields of a calendar date, or a RangeError for anything that is not a real date. */
64
+ function dateFields(date: CalendarDate): DateFields {
65
+ let year: number;
66
+ let month: number;
67
+ let day: number;
68
+ if (typeof date === 'string') {
69
+ const match = DATE_RE.exec(date);
70
+ if (match === null) {
71
+ throw new RangeError(`Invalid date "${date}"; expected YYYY-MM-DD`);
72
+ }
73
+ year = Number(match[1]);
74
+ month = Number(match[2]);
75
+ day = Number(match[3]);
76
+ } else {
77
+ // a Temporal.PlainDate in another calendar has that calendar's fields, not Gregorian ones
78
+ const calendar = (date as { calendarId?: unknown }).calendarId;
79
+ if (calendar !== undefined && calendar !== 'iso8601') {
80
+ throw new RangeError(`Dates must be in the ISO calendar; got ${String(calendar)}`);
81
+ }
82
+ year = date.year;
83
+ month = date.month;
84
+ day = date.day;
85
+ }
86
+ // years 0-9999, as 'YYYY-MM-DD' writes them, keep every day and second count exact
87
+ const valid =
88
+ Number.isInteger(year) &&
89
+ year >= 0 &&
90
+ year <= 9999 &&
91
+ Number.isInteger(month) &&
92
+ Number.isInteger(day) &&
93
+ month >= 1 &&
94
+ month <= 12 &&
95
+ day >= 1 &&
96
+ day <= daysInMonth(year, month);
97
+ if (!valid) {
98
+ throw new RangeError(`Invalid date ${formatFields(year, month, day)}`);
99
+ }
100
+ return { year, month, day };
101
+ }
102
+
103
+ function formatFields(year: number, month: number, day: number): string {
104
+ const pad = (value: number) => String(value).padStart(2, '0');
105
+ return `${String(year).padStart(4, '0')}-${pad(month)}-${pad(day)}`;
106
+ }
107
+
108
+ /**
109
+ * Days from 1970-01-01 to the date, in integers (Howard Hinnant's `days_from_civil`): the year is
110
+ * counted from March, so the leap day falls at the end of the counting year.
111
+ */
112
+ function dayNumber({ year, month, day }: DateFields): number {
113
+ const shiftedYear = month <= 2 ? year - 1 : year;
114
+ const era = Math.floor(shiftedYear / 400);
115
+ const yearOfEra = shiftedYear - era * 400;
116
+ const monthFromMarch = month > 2 ? month - 3 : month + 9;
117
+ const dayOfYear = Math.floor((153 * monthFromMarch + 2) / 5) + day - 1;
118
+ const dayOfEra = yearOfEra * 365 + Math.floor(yearOfEra / 4) - Math.floor(yearOfEra / 100);
119
+ return era * 146_097 + dayOfEra + dayOfYear - 719_468;
120
+ }
121
+
122
+ /** Days from `start` to `end` (end exclusive): negative when `end` is earlier. */
123
+ function daysBetween(start: DateFields, end: DateFields): number {
124
+ return dayNumber(end) - dayNumber(start);
125
+ }
126
+
127
+ function assertNotBefore(start: DateFields, end: DateFields): void {
128
+ if (dayNumber(end) < dayNumber(start)) {
129
+ throw new RangeError('The end date is before the start date');
130
+ }
131
+ }
132
+
133
+ // ---------------------------------------------------------------------------------------------
134
+ // Day counts
135
+ // ---------------------------------------------------------------------------------------------
136
+
137
+ /**
138
+ * A day-count convention, as defined in the 2006 ISDA Definitions §4.16:
139
+ * - 'ACT/360' and 'ACT/365F': actual days over 360 or 365;
140
+ * - 'ACT/ACT ISDA': days in leap years over 366 plus days in other years over 365;
141
+ * - '30/360': Bond Basis, §4.16(f);
142
+ * - '30E/360': Eurobond Basis, §4.16(g);
143
+ * - '30E/360 ISDA': §4.16(h), which treats the last day of February as the 30th except on the
144
+ * termination date: when `end` is the last day of February, say whether it is with `maturity`.
145
+ */
146
+ export type DayCount =
147
+ | 'ACT/360'
148
+ | 'ACT/365F'
149
+ | 'ACT/ACT ISDA'
150
+ | '30/360'
151
+ | '30E/360'
152
+ | '30E/360 ISDA';
153
+
154
+ /** Options for `yearFraction`. */
155
+ export interface YearFractionOptions {
156
+ /**
157
+ * '30E/360 ISDA' only: whether `end` is the termination (maturity) date, whose last day of
158
+ * February is kept as is. Required when `end` is the last day of February, because the two
159
+ * readings differ by up to two days and neither is a safe default.
160
+ */
161
+ readonly maturity?: boolean;
162
+ }
163
+
164
+ function isLastDayOfFebruary({ year, month, day }: DateFields): boolean {
165
+ return month === 2 && day === daysInMonth(year, 2);
166
+ }
167
+
168
+ /** The 30/360 family's day count: 360 × years + 30 × months + days, after adjusting the days. */
169
+ function thirty360Days(
170
+ start: DateFields,
171
+ end: DateFields,
172
+ startDay: number,
173
+ endDay: number,
174
+ ): number {
175
+ return 360 * (end.year - start.year) + 30 * (end.month - start.month) + (endDay - startDay);
176
+ }
177
+
178
+ /**
179
+ * The fraction of a year from `start` to `end` under `convention`, as an exact ratio. `end` may not
180
+ * be before `start`. This is not Excel's YEARFRAC: its basis 0 is the US (NASD) 30/360 with
181
+ * end-of-February rules rather than Bond Basis, its basis 1 divides by an average year length
182
+ * rather than splitting days by calendar year as ACT/ACT ISDA does, and it swaps reversed dates.
183
+ *
184
+ * yearFraction('2026-01-15', '2026-07-15', 'ACT/360') // 181/360
185
+ */
186
+ export function yearFraction(
187
+ start: CalendarDate,
188
+ end: CalendarDate,
189
+ convention: DayCount,
190
+ options?: YearFractionOptions,
191
+ ): Ratio {
192
+ const from = dateFields(start);
193
+ const to = dateFields(end);
194
+ assertNotBefore(from, to);
195
+
196
+ switch (convention) {
197
+ case 'ACT/360':
198
+ return ratio(BigInt(daysBetween(from, to)), 360n);
199
+ case 'ACT/365F':
200
+ return ratio(BigInt(daysBetween(from, to)), 365n);
201
+ case 'ACT/ACT ISDA':
202
+ return actualActualIsda(from, to);
203
+ case '30/360': {
204
+ // §4.16(f): D1 = 31 becomes 30; D2 = 31 becomes 30 only when D1 is then 30 (or was 31)
205
+ const startDay = from.day === 31 ? 30 : from.day;
206
+ const endDay = to.day === 31 && startDay === 30 ? 30 : to.day;
207
+ return ratio(BigInt(thirty360Days(from, to, startDay, endDay)), 360n);
208
+ }
209
+ case '30E/360': {
210
+ // §4.16(g): a 31st on either side becomes the 30th
211
+ const startDay = from.day === 31 ? 30 : from.day;
212
+ const endDay = to.day === 31 ? 30 : to.day;
213
+ return ratio(BigInt(thirty360Days(from, to, startDay, endDay)), 360n);
214
+ }
215
+ case '30E/360 ISDA': {
216
+ // §4.16(h): the last day of a month becomes the 30th, except the last day of February when
217
+ // it is the termination date
218
+ const startDay = from.day === 31 || isLastDayOfFebruary(from) ? 30 : from.day;
219
+ let endDay = to.day === 31 ? 30 : to.day;
220
+ if (isLastDayOfFebruary(to)) {
221
+ const maturity = options?.maturity;
222
+ if (typeof maturity !== 'boolean') {
223
+ throw new RangeError(
224
+ "'30E/360 ISDA' ending on the last day of February needs the option maturity: true or false",
225
+ );
226
+ }
227
+ endDay = maturity ? to.day : 30;
228
+ }
229
+ return ratio(BigInt(thirty360Days(from, to, startDay, endDay)), 360n);
230
+ }
231
+ }
232
+ return invalid('day count', convention);
233
+ }
234
+
235
+ /** ACT/ACT ISDA: the days in each calendar year over that year's length, summed exactly. */
236
+ function actualActualIsda(from: DateFields, to: DateFields): Ratio {
237
+ if (from.year === to.year) {
238
+ return ratio(BigInt(daysBetween(from, to)), BigInt(daysInYear(from.year)));
239
+ }
240
+ const startYearEnd = { year: from.year + 1, month: 1, day: 1 };
241
+ const endYearStart = { year: to.year, month: 1, day: 1 };
242
+ const firstYearLength = BigInt(daysInYear(from.year));
243
+ const lastYearLength = BigInt(daysInYear(to.year));
244
+ const firstYearDays = BigInt(daysBetween(from, startYearEnd));
245
+ const lastYearDays = BigInt(daysBetween(endYearStart, to));
246
+ const wholeYears = BigInt(to.year - from.year - 1);
247
+ // firstYearDays/firstYearLength + wholeYears + lastYearDays/lastYearLength over one denominator
248
+ const denominator = firstYearLength * lastYearLength;
249
+ const numerator =
250
+ firstYearDays * lastYearLength + wholeYears * denominator + lastYearDays * firstYearLength;
251
+ return ratio(numerator, denominator);
252
+ }
253
+
254
+ // ---------------------------------------------------------------------------------------------
255
+ // Rounding helpers
256
+ // ---------------------------------------------------------------------------------------------
257
+
258
+ /**
259
+ * numerator / denominator major units (denominator > 0) rounded once: with a mode, to the
260
+ * currency's exponent; with a policy, to the policy's scale and increment. The fraction is not
261
+ * reduced first: rounding divides once either way, and a gcd of the thousands-of-bits integers a
262
+ * long schedule or NPV builds would cost more than everything else.
263
+ */
264
+ function roundQuotient<C extends string>(
265
+ currency: C,
266
+ numerator: bigint,
267
+ denominator: bigint,
268
+ rounding: RoundingInput,
269
+ ): Money<C> {
270
+ // one major unit times the fraction, so the rounding applies to the fraction itself
271
+ return multiplyAndRound(make(currency, 1, 0), unreducedRatio(numerator, denominator), rounding);
272
+ }
273
+
274
+ /** money × factor rounded once, at the currency's exponent or the policy's scale. */
275
+ function multiplyAndRound<C extends string>(
276
+ money: Money<C>,
277
+ factor: Ratio,
278
+ rounding: RoundingInput,
279
+ ): Money<C> {
280
+ return multiplyByRatio(money, factor, rounding, currencyExponent(money.currency));
281
+ }
282
+
283
+ /**
284
+ * A ratio built without a gcd, for rounding once: multiplyByRatio divides by it, which gives the
285
+ * same result for any representation of the fraction.
286
+ */
287
+ function unreducedRatio(numerator: bigint, denominator: bigint): Ratio {
288
+ const toNumber = (value: bigint) =>
289
+ value <= 9_007_199_254_740_991n && value >= -9_007_199_254_740_991n ? Number(value) : NaN;
290
+ return { num: numerator, den: denominator, n: toNumber(numerator), d: toNumber(denominator) };
291
+ }
292
+
293
+ /**
294
+ * The most periods a schedule or compounding may have: (1 + r)^n has about n times the bits of
295
+ * 1 + r, so this bounds the integers (a 30-year daily schedule is about 11,000 periods).
296
+ */
297
+ const MAX_PERIODS = 100_000;
298
+
299
+ function assertPeriods(periods: number, minimum: number): void {
300
+ if (!(Number.isInteger(periods) && periods >= minimum && periods <= MAX_PERIODS)) {
301
+ invalid('periods', periods);
302
+ }
303
+ }
304
+
305
+ /** Whether `money` is a whole number of `unit`s (both of one currency, unit positive). */
306
+ function isMultipleOf(money: Money, unit: Money): boolean {
307
+ const scale = Math.max(money.scale, unit.scale);
308
+ const minor = BigInt(money.minor) * pow10n(scale - money.scale);
309
+ const unitMinor = BigInt(unit.minor) * pow10n(scale - unit.scale);
310
+ return minor % unitMinor === 0n;
311
+ }
312
+
313
+ /** Throws a RangeError naming the option and the value it was given. */
314
+ function invalid(name: string, value: unknown): never {
315
+ throw new RangeError(`Invalid ${name} ${String(value)}`);
316
+ }
317
+
318
+ function assertPositiveInteger(value: number, name: string): void {
319
+ if (!(Number.isSafeInteger(value) && value >= 1)) {
320
+ invalid(name, value);
321
+ }
322
+ }
323
+
324
+ function assertSameCurrency(money: Money, other: Money): void {
325
+ if (money.currency !== other.currency) {
326
+ throw new CurrencyMismatchError(money.currency, other.currency);
327
+ }
328
+ }
329
+
330
+ // ---------------------------------------------------------------------------------------------
331
+ // Interest
332
+ // ---------------------------------------------------------------------------------------------
333
+
334
+ /** The accrual period of `interest` and `interestExact`. */
335
+ export interface InterestPeriod extends YearFractionOptions {
336
+ /** The first day of interest. */
337
+ readonly from: CalendarDate;
338
+ /** The day interest runs to (exclusive, as in every day count). */
339
+ readonly to: CalendarDate;
340
+ /** The day-count convention. */
341
+ readonly dayCount: DayCount;
342
+ }
343
+
344
+ /**
345
+ * Simple interest, `principal × rate × yearFraction`, exactly. `rate` is an annual rate as a
346
+ * `Factor` ('0.05' for 5%).
347
+ */
348
+ export function interestExact<C extends string>(
349
+ principal: Money<C>,
350
+ rate: Factor,
351
+ period: InterestPeriod,
352
+ ): ExactMoney<C> {
353
+ const fraction = yearFraction(period.from, period.to, period.dayCount, period);
354
+ return exact(principal).multiply(rate).multiply(fraction);
355
+ }
356
+
357
+ /**
358
+ * Simple interest, `principal × rate × yearFraction`, rounded once (to the currency's exponent with
359
+ * a mode, or to a policy's scale; default 'halfExpand').
360
+ *
361
+ * interest(money('10000', 'EUR'), '0.05',
362
+ * { from: '2026-01-15', to: '2026-07-15', dayCount: 'ACT/365F' }, 'halfEven') // 247.95 EUR
363
+ */
364
+ export function interest<C extends string>(
365
+ principal: Money<C>,
366
+ rate: Factor,
367
+ period: InterestPeriod,
368
+ rounding: RoundingInput = DEFAULT_ROUNDING,
369
+ ): Money<C> {
370
+ const fraction = yearFraction(period.from, period.to, period.dayCount, period);
371
+ const rateRatio = ratio(rate);
372
+ return multiplyAndRound(
373
+ principal,
374
+ ratio(rateRatio.num * fraction.num, rateRatio.den * fraction.den),
375
+ rounding,
376
+ );
377
+ }
378
+
379
+ /** The compounding of `compound`: how many periods, and how many make a year. */
380
+ export interface CompoundOptions {
381
+ /** A non-negative integer number of compounding periods. */
382
+ readonly periods: number;
383
+ /** Compounding periods per year (12 for monthly): the periodic rate is `rate / perYear`. */
384
+ readonly perYear: number;
385
+ }
386
+
387
+ /** (1 + rate/perYear) as a reduced ratio, checked to be positive. */
388
+ function growthFactor(rate: Factor, perYear: number): Ratio {
389
+ assertPositiveInteger(perYear, 'perYear');
390
+ const rateRatio = ratio(rate);
391
+ const perYearBig = BigInt(perYear);
392
+ const growth = ratio(rateRatio.num + rateRatio.den * perYearBig, rateRatio.den * perYearBig);
393
+ if (growth.num <= 0n) {
394
+ throw new RangeError(`A rate of ${rate} per year loses everything in one period`);
395
+ }
396
+ return growth;
397
+ }
398
+
399
+ /**
400
+ * Periodic compounding: `principal × (1 + rate/perYear)^periods` (at most 100,000 periods), an
401
+ * exact integer power, rounded once. Fractional periods and continuous compounding are irrational, so they are not offered.
402
+ *
403
+ * compound(money('1000', 'EUR'), '0.05', { periods: 12, perYear: 12 }, 'halfEven') // 1051.16 EUR
404
+ */
405
+ export function compound<C extends string>(
406
+ principal: Money<C>,
407
+ rate: Factor,
408
+ options: CompoundOptions,
409
+ rounding: RoundingInput = DEFAULT_ROUNDING,
410
+ ): Money<C> {
411
+ const periods = options.periods;
412
+ assertPeriods(periods, 0);
413
+ const growth = growthFactor(rate, options.perYear);
414
+ const exponent = BigInt(periods);
415
+ // a power of a reduced ratio is reduced, so no gcd is needed on the large integers
416
+ const power = unreducedRatio(growth.num ** exponent, growth.den ** exponent);
417
+ return multiplyAndRound(principal, power, rounding);
418
+ }
419
+
420
+ // ---------------------------------------------------------------------------------------------
421
+ // Amortisation
422
+ // ---------------------------------------------------------------------------------------------
423
+
424
+ /**
425
+ * How a loan is repaid:
426
+ * - 'annuity' (French): equal payments of interest and principal;
427
+ * - 'linear' (German): equal principal parts, with interest on top, so payments fall;
428
+ * - 'interestOnly' (bullet): interest every period, and the principal with the last payment.
429
+ */
430
+ export type AmortisationMethod = 'annuity' | 'linear' | 'interestOnly';
431
+
432
+ /**
433
+ * Where an annuity's rounding residual goes: the last payment (the default, which most lenders
434
+ * use), or the last period's interest, which keeps the last payment equal to the others.
435
+ */
436
+ export type AmortisationResidual = 'lastPayment' | 'lastInterest';
437
+
438
+ /** Options for `amortise`. */
439
+ export interface AmortiseOptions<C extends string> {
440
+ /** The nominal annual rate, as a `Factor` ('0.045' for 4.5%). Not negative. */
441
+ readonly rate: Factor;
442
+ /** Payments per year (12 for monthly): the periodic rate is `rate / perYear`. */
443
+ readonly perYear: number;
444
+ /** The number of payments. */
445
+ readonly periods: number;
446
+ /** How the loan is repaid (default 'annuity'). */
447
+ readonly method?: AmortisationMethod;
448
+ /**
449
+ * How every payment and interest charge is rounded: a mode, to the currency's exponent, or a
450
+ * rounding policy (default 'halfExpand').
451
+ */
452
+ readonly rounding?: RoundingInput;
453
+ /**
454
+ * An amount still owed after the regular payments, paid with the last one ('annuity' and
455
+ * 'linear' only).
456
+ */
457
+ readonly balloon?: Money<C>;
458
+ /**
459
+ * The date of the first payment. With `perYear` 1, 2, 3, 4, 6 or 12 the later ones follow
460
+ * monthly, on this date's day of the month, clamped to shorter months (31 January, 28 February,
461
+ * 31 March). That is not the end-of-month rule: from 30 November, quarterly dates are 28 or 29
462
+ * February and then 30 May, not 31 May; pass an anchor of 31 for month ends. With 26 or 52, the
463
+ * payments are every 14 or 7 days.
464
+ */
465
+ readonly firstPayment?: CalendarDate;
466
+ /**
467
+ * Where an annuity's rounding residual goes (default 'lastPayment'). 'lastInterest' applies to
468
+ * annuities only: linear and interest-only schedules have no residual.
469
+ */
470
+ readonly residual?: AmortisationResidual;
471
+ }
472
+
473
+ /** One payment of an amortisation schedule. */
474
+ export interface AmortisationRow<C extends string> {
475
+ /** 1 for the first payment. */
476
+ readonly period: number;
477
+ /** The payment date ('YYYY-MM-DD'), when `firstPayment` is given. */
478
+ readonly date?: string;
479
+ /** Interest plus principal. */
480
+ readonly payment: Money<C>;
481
+ /** This period's interest: the balance before the payment times the periodic rate, rounded. */
482
+ readonly interest: Money<C>;
483
+ /** The part of the payment that repays the loan. */
484
+ readonly principal: Money<C>;
485
+ /** What is still owed after the payment. */
486
+ readonly balance: Money<C>;
487
+ /** Reserved for interest from a day count between payment dates; not set yet. */
488
+ readonly days?: number;
489
+ /** Reserved for interest from a day count between payment dates; not set yet. */
490
+ readonly yearFraction?: Ratio;
491
+ }
492
+
493
+ /** The result of `amortise`. */
494
+ export interface Amortisation<C extends string> {
495
+ /**
496
+ * The regular payment: for 'annuity' every payment but possibly the last; for 'linear' the
497
+ * first (the largest); for 'interestOnly' the interest payment.
498
+ */
499
+ readonly payment: Money<C>;
500
+ /** One row per payment. */
501
+ readonly rows: AmortisationRow<C>[];
502
+ /** The sum of the interest column, exactly. */
503
+ readonly totalInterest: Money<C>;
504
+ }
505
+
506
+ /** The minor unit a rounding produces, for loans whose parts must be multiples of it. */
507
+ function roundingUnit<C extends string>(currency: C, rounding: RoundingInput): Money<C> {
508
+ if (typeof rounding === 'string') {
509
+ return make(currency, 1, currencyExponent(currency));
510
+ }
511
+ return make(currency, rounding.increment, rounding.scale ?? currencyExponent(currency));
512
+ }
513
+
514
+ /** The payment dates: monthly steps from the anchor date, clamped to month ends, or 7 or 14 days. */
515
+ function paymentDates(first: CalendarDate, perYear: number, count: number): string[] {
516
+ const anchor = dateFields(first);
517
+ const dates: string[] = [];
518
+ if (perYear === 26 || perYear === 52) {
519
+ const step = perYear === 52 ? 7 : 14;
520
+ const anchorDay = dayNumber(anchor);
521
+ for (let i = 0; i < count; i++) {
522
+ dates.push(dateFromDayNumber(anchorDay + i * step));
523
+ }
524
+ return checkedDates(dates);
525
+ }
526
+ if (!(Number.isSafeInteger(perYear) && 12 % perYear === 0)) {
527
+ // payment dates step by whole months, or by 7 or 14 days
528
+ invalid('perYear for payment dates', perYear);
529
+ }
530
+ const monthStep = 12 / perYear;
531
+ for (let i = 0; i < count; i++) {
532
+ const monthIndex = anchor.month - 1 + i * monthStep;
533
+ const year = anchor.year + Math.floor(monthIndex / 12);
534
+ const month = (monthIndex % 12) + 1;
535
+ const day = Math.min(anchor.day, daysInMonth(year, month));
536
+ dates.push(formatFields(year, month, day));
537
+ }
538
+ return checkedDates(dates);
539
+ }
540
+
541
+ /** The dates, unless the last (and latest) is past the year 9999, which dates can't hold. */
542
+ function checkedDates(dates: string[]): string[] {
543
+ if (dates[dates.length - 1]!.length !== 10) {
544
+ throw new RangeError('The payment dates run past the year 9999');
545
+ }
546
+ return dates;
547
+ }
548
+
549
+ /** The inverse of `dayNumber` (Howard Hinnant's `civil_from_days`). */
550
+ function dateFromDayNumber(days: number): string {
551
+ const shifted = days + 719_468;
552
+ const era = Math.floor(shifted / 146_097);
553
+ const dayOfEra = shifted - era * 146_097;
554
+ const yearOfEra = Math.floor(
555
+ (dayOfEra -
556
+ Math.floor(dayOfEra / 1460) +
557
+ Math.floor(dayOfEra / 36_524) -
558
+ Math.floor(dayOfEra / 146_096)) /
559
+ 365,
560
+ );
561
+ const dayOfYear =
562
+ dayOfEra - (365 * yearOfEra + Math.floor(yearOfEra / 4) - Math.floor(yearOfEra / 100));
563
+ const monthFromMarch = Math.floor((5 * dayOfYear + 2) / 153);
564
+ const day = dayOfYear - Math.floor((153 * monthFromMarch + 2) / 5) + 1;
565
+ const month = monthFromMarch < 10 ? monthFromMarch + 3 : monthFromMarch - 9;
566
+ const year = yearOfEra + era * 400 + (month <= 2 ? 1 : 0);
567
+ return formatFields(year, month, day);
568
+ }
569
+
570
+ /**
571
+ * A loan's repayment schedule. Each period's interest is the balance times `rate / perYear`,
572
+ * rounded once; the principal part is the payment minus the interest. The principal parts sum
573
+ * exactly to the loan, the balance never goes negative, and it ends at exactly zero: the rounding
574
+ * residual goes to the last payment (or, with `residual: 'lastInterest'`, to the last interest). If
575
+ * rounded payments clear the loan early, the schedule ends with the payment that clears it, so it
576
+ * can have fewer rows than `periods`. With a zero rate, the payments are
577
+ * `instalments(loan, periods, { remainder: 'toLast' })` (there is no interest to take a residual).
578
+ * The loan and the balloon must be multiples of the rounding's unit (0.01 EUR, or a policy's
579
+ * increment), so that every amount in the schedule is too. At most 100,000 periods.
580
+ *
581
+ * amortise(money('200000', 'EUR'), { rate: '0.045', perYear: 12, periods: 300 }).payment
582
+ * // 1111.66 EUR
583
+ */
584
+ export function amortise<C extends string>(
585
+ loan: Money<C>,
586
+ options: AmortiseOptions<NoInfer<C>>,
587
+ ): Amortisation<C> {
588
+ const periods = options.periods;
589
+ const perYear = options.perYear;
590
+ const method = options.method ?? 'annuity';
591
+ const rounding = options.rounding ?? DEFAULT_ROUNDING;
592
+ const residual = options.residual ?? 'lastPayment';
593
+ const currency = loan.currency;
594
+ const zeroAmount = make(currency, 0, currencyExponent(currency));
595
+ const balloon = options.balloon ?? zeroAmount;
596
+
597
+ assertPeriods(periods, 1);
598
+ assertPositiveInteger(perYear, 'perYear');
599
+ if (!(loan.minor > 0)) {
600
+ throw new RangeError(`The loan must be positive; got ${loan}`);
601
+ }
602
+ assertSameCurrency(loan, balloon);
603
+ if (balloon.minor < 0 || compare(balloon, loan) > 0) {
604
+ throw new RangeError(`The balloon must be between zero and the loan; got ${balloon}`);
605
+ }
606
+ if (options.balloon !== undefined && method === 'interestOnly') {
607
+ throw new RangeError("An 'interestOnly' loan repays all of it at the end; drop the balloon");
608
+ }
609
+ if (method !== 'annuity' && method !== 'linear' && method !== 'interestOnly') {
610
+ invalid('method', method);
611
+ }
612
+ if (residual !== 'lastPayment' && residual !== 'lastInterest') {
613
+ invalid('residual', residual);
614
+ }
615
+ const unit = roundingUnit(currency, rounding);
616
+ if (!isMultipleOf(loan, unit) || !isMultipleOf(balloon, unit)) {
617
+ throw new RangeError(`The loan and the balloon must be multiples of ${unit}`);
618
+ }
619
+ const rateRatio = ratio(options.rate);
620
+ if (rateRatio.num < 0n) {
621
+ throw new RangeError(`The rate must not be negative; got ${options.rate}`);
622
+ }
623
+ // with no interest to round, there is no residual to put in it
624
+ if (residual === 'lastInterest' && (method !== 'annuity' || rateRatio.num === 0n)) {
625
+ throw new RangeError("residual 'lastInterest' applies to annuities with a non-zero rate only");
626
+ }
627
+ const dates =
628
+ options.firstPayment === undefined
629
+ ? undefined
630
+ : paymentDates(options.firstPayment, perYear, periods);
631
+ const periodicRate = ratio(rateRatio.num, rateRatio.den * BigInt(perYear));
632
+
633
+ const rows: AmortisationRow<C>[] = [];
634
+ const pushRow = (
635
+ payment: Money<C>,
636
+ interestPart: Money<C>,
637
+ principal: Money<C>,
638
+ balance: Money<C>,
639
+ ) => {
640
+ const period = rows.length + 1;
641
+ const row: AmortisationRow<C> =
642
+ dates === undefined
643
+ ? { period, payment, interest: interestPart, principal, balance }
644
+ : { period, date: dates[period - 1]!, payment, interest: interestPart, principal, balance };
645
+ rows.push(row);
646
+ };
647
+
648
+ // The principal parts of a linear loan, or of any loan at a zero rate: equal parts that sum to
649
+ // the loan exactly, each a multiple of the rounding's unit, the remainder in the last one.
650
+ const isZeroRate = rateRatio.num === 0n;
651
+ if (method === 'linear' || (method === 'annuity' && isZeroRate)) {
652
+ const parts = instalments(subtract(loan, balloon), periods, {
653
+ remainder: 'toLast',
654
+ unit,
655
+ });
656
+ let balance = loan;
657
+ for (let i = 0; i < periods; i++) {
658
+ const isLast = i === periods - 1;
659
+ const principal = isLast ? balance : parts[i]!;
660
+ const interestPart = multiplyAndRound(balance, periodicRate, rounding);
661
+ balance = subtract(balance, principal);
662
+ pushRow(add(principal, interestPart), interestPart, principal, balance);
663
+ }
664
+ return finish(rows, currency);
665
+ }
666
+
667
+ if (method === 'interestOnly') {
668
+ const interestPart = multiplyAndRound(loan, periodicRate, rounding);
669
+ for (let i = 0; i < periods; i++) {
670
+ const isLast = i === periods - 1;
671
+ const principal = isLast ? loan : zeroAmount;
672
+ const balance = isLast ? zeroAmount : loan;
673
+ pushRow(add(principal, interestPart), interestPart, principal, balance);
674
+ }
675
+ return { payment: interestPart, rows, totalInterest: sumInterest(rows, currency) };
676
+ }
677
+
678
+ // Annuity: payment = (P·g^n − B)·r / (g^n − 1), with r = a/b and g = 1 + r = (a + b)/b. With
679
+ // G = (a + b)^n and H = b^n that is (P·G − B·H)·a / (b·(G − H)), and P and B are minor units
680
+ // over 10^scale, so the exact payment is one fraction of integers, rounded once.
681
+ const scale = Math.max(loan.scale, balloon.scale);
682
+ const loanMinor = BigInt(loan.minor) * pow10n(scale - loan.scale);
683
+ const balloonMinor = BigInt(balloon.minor) * pow10n(scale - balloon.scale);
684
+ const exponent = BigInt(periods);
685
+ const growthPower = (periodicRate.num + periodicRate.den) ** exponent;
686
+ const basePower = periodicRate.den ** exponent;
687
+ const payment = roundQuotient(
688
+ currency,
689
+ (loanMinor * growthPower - balloonMinor * basePower) * periodicRate.num,
690
+ pow10n(scale) * periodicRate.den * (growthPower - basePower),
691
+ rounding,
692
+ );
693
+
694
+ let balance = loan;
695
+ for (let i = 0; i < periods; i++) {
696
+ const interestPart = multiplyAndRound(balance, periodicRate, rounding);
697
+ const isLast = i === periods - 1;
698
+ const owed = add(balance, interestPart);
699
+ // the last payment, or a regular payment that would clear more than is owed, settles the loan
700
+ if (isLast || compare(payment, owed) >= 0) {
701
+ if (isLast && residual === 'lastInterest') {
702
+ const lastPayment = add(payment, balloon);
703
+ const lastInterest = subtract(lastPayment, balance);
704
+ if (lastInterest.minor < 0) {
705
+ throw new RangeError(
706
+ "The residual exceeds the last interest; use residual 'lastPayment'",
707
+ );
708
+ }
709
+ pushRow(lastPayment, lastInterest, balance, subtract(balance, balance));
710
+ } else {
711
+ pushRow(owed, interestPart, balance, subtract(balance, balance));
712
+ }
713
+ break;
714
+ }
715
+ const principal = subtract(payment, interestPart);
716
+ balance = subtract(balance, principal);
717
+ pushRow(payment, interestPart, principal, balance);
718
+ }
719
+ return { payment, rows, totalInterest: sumInterest(rows, currency) };
720
+ }
721
+
722
+ function sumInterest<C extends string>(rows: readonly AmortisationRow<C>[], currency: C): Money<C> {
723
+ // the rows share one currency, which the generic C cannot show the type checker
724
+ const interestColumn = rows.map((row) => row.interest as Money<string>);
725
+ return sum(interestColumn, currency) as Money<C>;
726
+ }
727
+
728
+ function finish<C extends string>(rows: AmortisationRow<C>[], currency: C): Amortisation<C> {
729
+ return { payment: rows[0]!.payment, rows, totalInterest: sumInterest(rows, currency) };
730
+ }
731
+
732
+ // ---------------------------------------------------------------------------------------------
733
+ // NPV and IRR
734
+ // ---------------------------------------------------------------------------------------------
735
+
736
+ /** The flows' minor units at one common scale, checked to share a currency. */
737
+ function flowMinors<C extends string>(
738
+ flows: readonly Money<C>[],
739
+ ): { minors: bigint[]; scale: number } {
740
+ if (flows.length === 0) {
741
+ throw new RangeError('At least one cash flow is needed');
742
+ }
743
+ const first = flows[0]!;
744
+ let scale = 0;
745
+ for (const flow of flows) {
746
+ assertSameCurrency(first, flow);
747
+ if (flow.scale > scale) {
748
+ scale = flow.scale;
749
+ }
750
+ }
751
+ const minors = flows.map((flow) => BigInt(flow.minor) * pow10n(scale - flow.scale));
752
+ return { minors, scale };
753
+ }
754
+
755
+ /**
756
+ * Σ flowₜ · bᵗ · q^(n−t) for a rate of (q − b)/b: the NPV times q^n, by Horner's rule. q^n is
757
+ * positive for a rate above −1, so this has the NPV's sign.
758
+ */
759
+ function scaledPresentValue(
760
+ minors: readonly bigint[],
761
+ growthNumerator: bigint,
762
+ base: bigint,
763
+ ): bigint {
764
+ let accumulator = minors[0]!;
765
+ let basePower = 1n;
766
+ for (let i = 1; i < minors.length; i++) {
767
+ basePower *= base;
768
+ accumulator = accumulator * growthNumerator + minors[i]! * basePower;
769
+ }
770
+ return accumulator;
771
+ }
772
+
773
+ /**
774
+ * The discounted sum of flows at periods 0, 1, 2…, `Σ flowₜ / (1 + rate)ᵗ`, exactly: the textbook
775
+ * NPV, with the first flow (an initial outlay, say) not discounted. `npvExact` is Excel's form. (Not
776
+ * Excel's PV, which is an annuity's present value.)
777
+ */
778
+ export function discountedSumExact<C extends string>(
779
+ rate: Factor,
780
+ flows: readonly Money<C>[],
781
+ ): ExactMoney<C> {
782
+ const [numerator, denominator] = discountedValue(rate, flows, false);
783
+ return new ExactMoney(flows[0]!.currency, numerator, denominator);
784
+ }
785
+
786
+ /**
787
+ * The discounted sum of flows at periods 0, 1, 2…, exact and rounded once (to the currency's
788
+ * exponent with a mode, or to a policy's scale; default 'halfExpand'). The first flow is not
789
+ * discounted; this is `flows[0] + npv(rate, flows.slice(1))`.
790
+ *
791
+ * discountedSum('0.08', [money('-1000', 'EUR'), money('300', 'EUR'), money('400', 'EUR'),
792
+ * money('500', 'EUR')], 'halfEven') // 17.63 EUR
793
+ */
794
+ export function discountedSum<C extends string>(
795
+ rate: Factor,
796
+ flows: readonly Money<C>[],
797
+ rounding: RoundingInput = DEFAULT_ROUNDING,
798
+ ): Money<C> {
799
+ const [numerator, denominator] = discountedValue(rate, flows, false);
800
+ return roundQuotient(flows[0]!.currency, numerator, denominator, rounding);
801
+ }
802
+
803
+ /**
804
+ * Excel's NPV, exactly: `Σ flowᵢ / (1 + rate)ⁱ` for i = 1, 2…, so the first flow is at the end of
805
+ * period 1 and is discounted once. Like Excel, an initial outlay at period 0 goes outside:
806
+ * `flows[0] + npv(rate, rest)`, or use `discountedSumExact`.
807
+ */
808
+ export function npvExact<C extends string>(
809
+ rate: Factor,
810
+ flows: readonly Money<C>[],
811
+ ): ExactMoney<C> {
812
+ const [numerator, denominator] = discountedValue(rate, flows, true);
813
+ return new ExactMoney(flows[0]!.currency, numerator, denominator);
814
+ }
815
+
816
+ /**
817
+ * Excel's NPV: flows at the ends of periods 1, 2…, exact and rounded once (to the currency's
818
+ * exponent with a mode, or to a policy's scale; default 'halfExpand'), so it matches Excel to the
819
+ * cent. Like Excel, an initial outlay at period 0 goes outside: `flows[0] + npv(rate, rest)`, or use
820
+ * `discountedSum`, which takes flows from period 0.
821
+ *
822
+ * npv('0.1', [money('-10000', 'USD'), money('3000', 'USD'), money('4200', 'USD'),
823
+ * money('6800', 'USD')]) // 1188.44 USD, as Excel's NPV(10%, -10000, 3000, 4200, 6800)
824
+ */
825
+ export function npv<C extends string>(
826
+ rate: Factor,
827
+ flows: readonly Money<C>[],
828
+ rounding: RoundingInput = DEFAULT_ROUNDING,
829
+ ): Money<C> {
830
+ const [numerator, denominator] = discountedValue(rate, flows, true);
831
+ return roundQuotient(flows[0]!.currency, numerator, denominator, rounding);
832
+ }
833
+
834
+ /**
835
+ * The flows' discounted value in major units as an unreduced fraction (denominator positive), the
836
+ * first flow at period 0, or at period 1 when `fromPeriodOne`.
837
+ */
838
+ function discountedValue(
839
+ rate: Factor,
840
+ flows: readonly Money[],
841
+ fromPeriodOne: boolean,
842
+ ): [bigint, bigint] {
843
+ const { minors, scale } = flowMinors(flows);
844
+ const rateRatio = ratio(rate);
845
+ const growthNumerator = rateRatio.num + rateRatio.den;
846
+ if (growthNumerator <= 0n) {
847
+ throw new RangeError(`The rate must be above -1; got ${rate}`);
848
+ }
849
+ let numerator = scaledPresentValue(minors, growthNumerator, rateRatio.den);
850
+ let denominator = growthNumerator ** BigInt(minors.length - 1) * pow10n(scale);
851
+ if (fromPeriodOne) {
852
+ // one more period: divide by 1 + rate = growthNumerator / den
853
+ numerator *= rateRatio.den;
854
+ denominator *= growthNumerator;
855
+ }
856
+ return [numerator, denominator];
857
+ }
858
+
859
+ /** Options for `irr`. */
860
+ export interface IrrOptions {
861
+ /** Decimal places of the result (default 10). */
862
+ readonly digits?: number;
863
+ /**
864
+ * Rates the IRR lies between (inclusive), with NPVs of opposite signs at the two ends, taken at
865
+ * the exact rates given. Needed when the flows change sign more than once, since they can then
866
+ * have several IRRs; it replaces Excel's `guess`.
867
+ */
868
+ readonly bracket?: readonly [Factor, Factor];
869
+ }
870
+
871
+ /** The result of `irr`: decimal strings with `digits` places. */
872
+ export interface IrrResult {
873
+ /** The IRR floored to `digits` places: the same as `lower`. */
874
+ readonly rate: string;
875
+ /**
876
+ * The IRR rounded down to `digits` places. Without a bracket, the NPV at `lower` has the
877
+ * opposite sign to the NPV at `upper`, or is zero.
878
+ */
879
+ readonly lower: string;
880
+ /** `lower` plus 10^−digits. */
881
+ readonly upper: string;
882
+ }
883
+
884
+ function signOf(value: bigint): -1 | 0 | 1 {
885
+ if (value > 0n) {
886
+ return 1;
887
+ }
888
+ if (value < 0n) {
889
+ return -1;
890
+ }
891
+ return 0;
892
+ }
893
+
894
+ /** Sign changes in the flows, zeros skipped, and the sign of the first non-zero flow. */
895
+ function signChanges(minors: readonly bigint[]): { changes: number; firstSign: -1 | 0 | 1 } {
896
+ let changes = 0;
897
+ let firstSign: -1 | 0 | 1 = 0;
898
+ let previous: -1 | 0 | 1 = 0;
899
+ for (const minor of minors) {
900
+ const sign = signOf(minor);
901
+ if (sign === 0) {
902
+ continue;
903
+ }
904
+ if (firstSign === 0) {
905
+ firstSign = sign;
906
+ }
907
+ if (previous !== 0 && sign !== previous) {
908
+ changes++;
909
+ }
910
+ previous = sign;
911
+ }
912
+ return { changes, firstSign };
913
+ }
914
+
915
+ /**
916
+ * Excel's IRR, exactly: the rate at which the NPV of flows at periods 0, 1, 2… (the first value
917
+ * undiscounted, as in Excel's IRR) is zero. The rate is exact to `digits` decimal places (default
918
+ * 10), floored: `rate` is `lower`, the IRR rounded down, and the IRR lies between `lower` and
919
+ * `upper`, 10^−digits apart. It is a polynomial root, irrational in general, so it is found by
920
+ * bisection in exact integer arithmetic on the grid of `digits`-place decimals, with no floats and
921
+ * no Newton steps; each step checks the NPV's sign alone, by Horner's rule on integers.
922
+ *
923
+ * Where Excel guesses, this throws a RangeError. The flows never change sign: there is no IRR
924
+ * (Excel returns #NUM!). They change sign more than once: there can be several IRRs, and Excel
925
+ * returns whichever its Newton iteration from `guess` finds; here a `bracket`, which replaces
926
+ * `guess`, must select one, and the IRR returned is one inside it. The IRR is within 10^−digits of
927
+ * −1, where the NPV is undefined: ask for more digits.
928
+ *
929
+ * irr([money('-1000', 'EUR'), money('300', 'EUR'), money('400', 'EUR'), money('500', 'EUR')],
930
+ * { digits: 8 }) // { rate: '0.08896339', lower: '0.08896339', upper: '0.08896340' }
931
+ */
932
+ export function irr(flows: readonly Money[], options?: IrrOptions): IrrResult {
933
+ const digits = options?.digits ?? 10;
934
+ if (!(Number.isInteger(digits) && digits >= 0 && digits <= 100)) {
935
+ invalid('digits', digits);
936
+ }
937
+ const { minors } = flowMinors(flows);
938
+ const { changes, firstSign } = signChanges(minors);
939
+ const bracket = options?.bracket;
940
+ if (changes === 0) {
941
+ throw new RangeError('The cash flows never change sign, so they have no IRR');
942
+ }
943
+ if (changes > 1 && bracket === undefined) {
944
+ throw new RangeError(
945
+ `The cash flows change sign ${changes} times, so they can have several IRRs; pass a bracket`,
946
+ );
947
+ }
948
+
949
+ // A rate of m / 10^digits: its growth factor's numerator is 10^digits + m over 10^digits.
950
+ const unit = pow10n(digits);
951
+ const signAt = (grid: bigint): -1 | 0 | 1 =>
952
+ signOf(scaledPresentValue(minors, unit + grid, unit));
953
+ const result = (grid: bigint): IrrResult => {
954
+ // the NPV is undefined at -1, so a lower end there is no answer
955
+ if (grid <= -unit) {
956
+ throw new RangeError(`The IRR is within 10^-${digits} of -1; ask for more digits`);
957
+ }
958
+ const lower = formatScaled(grid, digits);
959
+ return { rate: lower, lower, upper: formatScaled(grid + 1n, digits) };
960
+ };
961
+
962
+ let low: bigint;
963
+ let high: bigint;
964
+ let lowSign: -1 | 0 | 1;
965
+ if (bracket !== undefined) {
966
+ const bracketed = bracketToGrid(bracket, minors, unit, signAt);
967
+ if (typeof bracketed === 'bigint') {
968
+ return result(bracketed);
969
+ }
970
+ [low, high, lowSign] = bracketed;
971
+ } else {
972
+ // One sign change: exactly one IRR above −1 (Descartes' rule in 1/(1 + rate)). The NPV has the
973
+ // first flow's sign for large rates and the last flow's sign near −1.
974
+ const zeroSign = signAt(0n);
975
+ if (zeroSign === 0) {
976
+ return result(0n);
977
+ }
978
+ if (zeroSign === firstSign) {
979
+ // the IRR is negative: between −1 (excluded, where the NPV has the last flow's sign) and 0
980
+ low = -unit;
981
+ high = 0n;
982
+ lowSign = -firstSign as -1 | 1;
983
+ } else {
984
+ // the IRR is positive: double the upper end until the NPV takes the first flow's sign
985
+ low = 0n;
986
+ high = unit;
987
+ lowSign = zeroSign;
988
+ for (;;) {
989
+ const highSign = signAt(high);
990
+ if (highSign === 0) {
991
+ return result(high);
992
+ }
993
+ if (highSign !== lowSign) {
994
+ break;
995
+ }
996
+ low = high;
997
+ high *= 2n;
998
+ }
999
+ }
1000
+ }
1001
+
1002
+ // Bisection on the grid: the bracket's ends stay `digits`-place decimals, so the integers stay
1003
+ // bounded by the digits asked for, and each step halves the bracket.
1004
+ while (high - low > 1n) {
1005
+ const middle = (low + high) / 2n;
1006
+ const middleSign = signAt(middle);
1007
+ if (middleSign === 0) {
1008
+ return result(middle);
1009
+ }
1010
+ if (middleSign === lowSign) {
1011
+ low = middle;
1012
+ } else {
1013
+ high = middle;
1014
+ }
1015
+ }
1016
+ return result(low);
1017
+ }
1018
+
1019
+ /**
1020
+ * The caller's bracket narrowed to the grid of `unit`ths: the NPV's signs are taken at the exact
1021
+ * bracket ends first, so the root found is one inside the bracket. Returns the grid point at or
1022
+ * below the root when the root is already pinned to one grid step, else the grid bracket to bisect
1023
+ * and the sign at its lower end.
1024
+ */
1025
+ function bracketToGrid(
1026
+ bracket: readonly [Factor, Factor],
1027
+ minors: readonly bigint[],
1028
+ unit: bigint,
1029
+ signAt: (grid: bigint) => -1 | 0 | 1,
1030
+ ): bigint | [bigint, bigint, -1 | 1] {
1031
+ const lowRate = ratio(bracket[0]);
1032
+ const highRate = ratio(bracket[1]);
1033
+ if (!(lowRate.num * highRate.den < highRate.num * lowRate.den)) {
1034
+ throw new RangeError('The bracket must be two increasing rates');
1035
+ }
1036
+ if (lowRate.num + lowRate.den <= 0n) {
1037
+ throw new RangeError('The bracket must be above -1');
1038
+ }
1039
+ const signAtRate = (rate: Ratio) =>
1040
+ signOf(scaledPresentValue(minors, rate.num + rate.den, rate.den));
1041
+ const lowSign = signAtRate(lowRate);
1042
+ const highSign = signAtRate(highRate);
1043
+ // an end that is itself a root: the grid point at or below it
1044
+ if (lowSign === 0) {
1045
+ return floorDivide(lowRate.num * unit, lowRate.den);
1046
+ }
1047
+ if (highSign === 0) {
1048
+ return floorDivide(highRate.num * unit, highRate.den);
1049
+ }
1050
+ if (lowSign === highSign) {
1051
+ throw new RangeError('The NPV has the same sign at both ends of the bracket');
1052
+ }
1053
+
1054
+ // the grid points inside the bracket
1055
+ const gridLow = -floorDivide(-lowRate.num * unit, lowRate.den);
1056
+ const gridHigh = floorDivide(highRate.num * unit, highRate.den);
1057
+ if (gridLow > gridHigh) {
1058
+ // no grid point inside: the root is between the two around the bracket
1059
+ return gridHigh;
1060
+ }
1061
+ const gridLowSign = signAt(gridLow);
1062
+ if (gridLowSign === 0) {
1063
+ return gridLow;
1064
+ }
1065
+ if (gridLowSign !== lowSign) {
1066
+ // the sign changes between the bracket's low end and the first grid point
1067
+ return gridLow - 1n;
1068
+ }
1069
+ const gridHighSign = gridHigh === gridLow ? gridLowSign : signAt(gridHigh);
1070
+ if (gridHighSign === 0) {
1071
+ return gridHigh;
1072
+ }
1073
+ if (gridHighSign === lowSign) {
1074
+ // the sign changes between the last grid point and the bracket's high end
1075
+ return gridHigh;
1076
+ }
1077
+ return [gridLow, gridHigh, lowSign];
1078
+ }
1079
+
1080
+ function floorDivide(dividend: bigint, divisor: bigint): bigint {
1081
+ const quotient = dividend / divisor;
1082
+ // bigint division truncates; step down when a negative quotient left a remainder
1083
+ return dividend % divisor !== 0n && dividend < 0n !== divisor < 0n ? quotient - 1n : quotient;
1084
+ }
1085
+
1086
+ // ---------------------------------------------------------------------------------------------
1087
+ // Proration
1088
+ // ---------------------------------------------------------------------------------------------
1089
+
1090
+ /**
1091
+ * A point in time for proration: a calendar date (midnight UTC), or with `unit: 'second'`, an ISO
1092
+ * date-time in UTC ('2026-03-11T09:30:00Z') or a Unix time in whole seconds.
1093
+ */
1094
+ export type ProrationInstant = CalendarDate | number;
1095
+
1096
+ /** A span of time, `end` exclusive. */
1097
+ export interface ProrationPeriod {
1098
+ readonly start: ProrationInstant;
1099
+ readonly end: ProrationInstant;
1100
+ }
1101
+
1102
+ /** What proration counts: whole days (the default) or seconds. */
1103
+ export type ProrationUnit = 'day' | 'second';
1104
+
1105
+ /** Options for `prorate`. */
1106
+ export interface ProrateOptions {
1107
+ /** The billing period the price is for. */
1108
+ readonly period: ProrationPeriod;
1109
+ /** The part of it being charged or credited; inside `period`. */
1110
+ readonly used: ProrationPeriod;
1111
+ /** Count days (the default) or seconds. */
1112
+ readonly unit?: ProrationUnit;
1113
+ }
1114
+
1115
+ /** Options for `splitPeriod`. */
1116
+ export interface SplitPeriodOptions {
1117
+ /** The billing period the price is for. */
1118
+ readonly period: ProrationPeriod;
1119
+ /** The change points, in increasing order, strictly inside the period. */
1120
+ readonly at: readonly ProrationInstant[];
1121
+ /** Count days (the default) or seconds. */
1122
+ readonly unit?: ProrationUnit;
1123
+ /** Where indivisible minor units go (default 'largest', as in `allocate`). */
1124
+ readonly remainder?: Remainder;
1125
+ }
1126
+
1127
+ const DATE_TIME_RE = /^(\d{4}-\d{2}-\d{2})T(\d{2}):(\d{2}):(\d{2})Z$/;
1128
+
1129
+ /** The instant as a count of `unit`s since 1970-01-01T00:00:00Z. */
1130
+ function instantCount(instant: ProrationInstant, unit: ProrationUnit): number {
1131
+ if (unit !== 'day' && unit !== 'second') {
1132
+ invalid('unit', unit);
1133
+ }
1134
+ if (typeof instant === 'number') {
1135
+ if (unit !== 'second' || !Number.isSafeInteger(instant)) {
1136
+ throw new RangeError(`Unix time ${instant} needs whole seconds and unit 'second'`);
1137
+ }
1138
+ return instant;
1139
+ }
1140
+ if (typeof instant === 'string' && instant.length > 10) {
1141
+ const match = DATE_TIME_RE.exec(instant);
1142
+ if (unit !== 'second' || match === null) {
1143
+ throw new RangeError(`Invalid instant "${instant}" (YYYY-MM-DDTHH:MM:SSZ, unit 'second')`);
1144
+ }
1145
+ const hours = Number(match[2]);
1146
+ const minutes = Number(match[3]);
1147
+ const seconds = Number(match[4]);
1148
+ if (hours > 23 || minutes > 59 || seconds > 59) {
1149
+ throw new RangeError(`Invalid instant "${instant}"`);
1150
+ }
1151
+ return dayNumber(dateFields(match[1]!)) * 86_400 + hours * 3600 + minutes * 60 + seconds;
1152
+ }
1153
+ const days = dayNumber(dateFields(instant));
1154
+ return unit === 'day' ? days : days * 86_400;
1155
+ }
1156
+
1157
+ function spanOf(period: ProrationPeriod, unit: ProrationUnit): { start: number; end: number } {
1158
+ const start = instantCount(period.start, unit);
1159
+ const end = instantCount(period.end, unit);
1160
+ if (!(end > start)) {
1161
+ throw new RangeError('A period must end after it starts');
1162
+ }
1163
+ return { start, end };
1164
+ }
1165
+
1166
+ /**
1167
+ * The part of `price` for the `used` part of a billing `period`: `price × used / period`, counted in
1168
+ * days (or seconds), exact and rounded once (to the currency's exponent with a mode, or to a
1169
+ * policy's scale; default 'halfExpand'). Periods are end-exclusive.
1170
+ *
1171
+ * prorate(money('30', 'EUR'), {
1172
+ * period: { start: '2026-03-01', end: '2026-04-01' },
1173
+ * used: { start: '2026-03-11', end: '2026-04-01' },
1174
+ * }, 'halfEven') // 20.32 EUR (21 of 31 days)
1175
+ */
1176
+ export function prorate<C extends string>(
1177
+ price: Money<C>,
1178
+ options: ProrateOptions,
1179
+ rounding: RoundingInput = DEFAULT_ROUNDING,
1180
+ ): Money<C> {
1181
+ const unit = options.unit ?? 'day';
1182
+ const period = spanOf(options.period, unit);
1183
+ const usedStart = instantCount(options.used.start, unit);
1184
+ const usedEnd = instantCount(options.used.end, unit);
1185
+ if (!(usedStart >= period.start && usedEnd <= period.end && usedEnd >= usedStart)) {
1186
+ throw new RangeError('The used part must lie inside the period');
1187
+ }
1188
+ const fraction = ratio(BigInt(usedEnd - usedStart), BigInt(period.end - period.start));
1189
+ return multiplyAndRound(price, fraction, rounding);
1190
+ }
1191
+
1192
+ /**
1193
+ * Splits one period's price at change points (plan changes), in proportion to the days (or seconds)
1194
+ * in each piece, through `allocate`, so the pieces always sum exactly to the price.
1195
+ *
1196
+ * splitPeriod(money('30', 'EUR'), {
1197
+ * period: { start: '2026-03-01', end: '2026-04-01' },
1198
+ * at: ['2026-03-11', '2026-03-20'],
1199
+ * }) // [9.68 EUR, 8.71 EUR, 11.61 EUR]
1200
+ */
1201
+ export function splitPeriod<C extends string>(
1202
+ price: Money<C>,
1203
+ options: SplitPeriodOptions,
1204
+ ): Money<C>[] {
1205
+ const unit = options.unit ?? 'day';
1206
+ const period = spanOf(options.period, unit);
1207
+ const weights: number[] = [];
1208
+ let previous = period.start;
1209
+ for (const point of options.at) {
1210
+ const count = instantCount(point, unit);
1211
+ if (!(count > previous && count < period.end)) {
1212
+ throw new RangeError('Change points must increase and lie strictly inside the period');
1213
+ }
1214
+ weights.push(count - previous);
1215
+ previous = count;
1216
+ }
1217
+ weights.push(period.end - previous);
1218
+ return allocate(price, weights, { remainder: options.remainder ?? 'largest' });
1219
+ }