calcsuite-react 1.1.2 → 1.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/dist/calcsuite.js +621 -617
- package/dist/ui/icons.d.ts +1 -0
- package/package.json +1 -1
- package/src/theme.css +11 -10
package/dist/calcsuite.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var ge = (e, t, n) =>
|
|
1
|
+
var fa = Object.defineProperty;
|
|
2
|
+
var ya = (e, t, n) => t in e ? fa(e, t, { enumerable: !0, configurable: !0, writable: !0, value: n }) : e[t] = n;
|
|
3
|
+
var ge = (e, t, n) => ya(e, typeof t != "symbol" ? t + "" : t, n);
|
|
4
4
|
import { jsx as o, jsxs as b, Fragment as re } from "react/jsx-runtime";
|
|
5
|
-
import { useState as M, useCallback as ke, useMemo as X, useContext as
|
|
5
|
+
import { useState as M, useCallback as ke, useMemo as X, useContext as ba, createContext as ga, useRef as de, useEffect as Q, Fragment as xn, useSyncExternalStore as va } from "react";
|
|
6
6
|
import mt from "decimal.js";
|
|
7
|
-
const
|
|
7
|
+
const ka = {
|
|
8
8
|
money: 2,
|
|
9
9
|
rate: 6,
|
|
10
10
|
period: 4,
|
|
@@ -13,7 +13,7 @@ const ga = {
|
|
|
13
13
|
instalment: "none",
|
|
14
14
|
residualAbsorption: "last"
|
|
15
15
|
}, qt = {
|
|
16
|
-
rounding:
|
|
16
|
+
rounding: ka,
|
|
17
17
|
ui: {
|
|
18
18
|
theme: "system",
|
|
19
19
|
accent: "#078DEE",
|
|
@@ -68,13 +68,13 @@ function xt(e) {
|
|
|
68
68
|
defaults: { tenureUnit: "both", rateType: "floating", maxRatePercent: 50, sipReturnPercent: "12", inflationPercent: "6" }
|
|
69
69
|
};
|
|
70
70
|
}
|
|
71
|
-
const
|
|
71
|
+
const Qe = xt("IN"), H = mt.clone({
|
|
72
72
|
precision: 40,
|
|
73
73
|
rounding: mt.ROUND_HALF_UP,
|
|
74
74
|
toExpPos: 60,
|
|
75
75
|
toExpNeg: -60,
|
|
76
76
|
modulo: mt.ROUND_DOWN
|
|
77
|
-
}), g = (e) => new H(e),
|
|
77
|
+
}), g = (e) => new H(e), ms = (e, t) => g(e).eq(t), ps = (e, t) => g(e).gt(t), hs = (e, t) => g(e).lt(t), ce = (e, t = "1e-9") => e.abs().lt(t), wa = {
|
|
78
78
|
HALF_UP: H.ROUND_HALF_UP,
|
|
79
79
|
HALF_EVEN: H.ROUND_HALF_EVEN,
|
|
80
80
|
HALF_DOWN: H.ROUND_HALF_DOWN,
|
|
@@ -83,7 +83,7 @@ const Xe = xt("IN"), H = mt.clone({
|
|
|
83
83
|
CEIL: H.ROUND_CEIL,
|
|
84
84
|
FLOOR: H.ROUND_FLOOR
|
|
85
85
|
};
|
|
86
|
-
function
|
|
86
|
+
function Na(e) {
|
|
87
87
|
switch (e.numberFormat.grouping) {
|
|
88
88
|
case "indian":
|
|
89
89
|
return "en-IN";
|
|
@@ -98,7 +98,7 @@ function ka(e) {
|
|
|
98
98
|
}
|
|
99
99
|
}
|
|
100
100
|
function Sn(e) {
|
|
101
|
-
const t =
|
|
101
|
+
const t = wa[e.rounding.mode], n = (l, p = e.numberFormat.decimalPlaces) => g(l).toDecimalPlaces(p, t), a = (l, p) => e.numberFormat.grouping === "plain" ? l.toFixed(p) : new Intl.NumberFormat(Na(e), {
|
|
102
102
|
minimumFractionDigits: e.numberFormat.trimTrailingZeros ? 0 : p,
|
|
103
103
|
maximumFractionDigits: p
|
|
104
104
|
}).format(l), r = (l, p) => l ? e.numberFormat.negativeFormat === "parentheses" ? `(${p})` : `-${p}` : p, s = (l) => {
|
|
@@ -126,54 +126,54 @@ function pt(e) {
|
|
|
126
126
|
const t = Math.floor(e / 12), n = e % 12, a = [];
|
|
127
127
|
return t && a.push(`${t} yr`), n && a.push(`${n} mo`), a.join(" ") || "0 mo";
|
|
128
128
|
}
|
|
129
|
-
const
|
|
129
|
+
const Cn = [
|
|
130
130
|
{ id: "default", label: "Green", main: "#00A76F", light: "#2CCF8E", dark: "#087055", ink: "#06251A" },
|
|
131
131
|
{ id: "cyan", label: "Cyan", main: "#078DEE", light: "#68CDF9", dark: "#0351AB", ink: "#FFFFFF" },
|
|
132
132
|
{ id: "purple", label: "Purple", main: "#7635DC", light: "#B985F4", dark: "#431A9E", ink: "#FFFFFF" },
|
|
133
133
|
{ id: "blue", label: "Blue", main: "#2065D1", light: "#76B0F1", dark: "#103996", ink: "#FFFFFF" },
|
|
134
134
|
{ id: "orange", label: "Orange", main: "#FDA92D", light: "#FED680", dark: "#B66816", ink: "#212B36" },
|
|
135
135
|
{ id: "gray", label: "Gray", main: "#A4AAB3", light: "#CED1D7", dark: "#63686C", ink: "#FFFFFF" }
|
|
136
|
-
],
|
|
137
|
-
{ id: "Inter Tight", label: "Inter Tight", stack: `'Inter Tight', ${
|
|
138
|
-
{ id: "Public Sans", label: "Public Sans", stack: `'Public Sans', ${
|
|
139
|
-
{ id: "system-ui", label: "System UI", stack: `system-ui, ${
|
|
136
|
+
], xa = (e) => Cn.find((t) => t.main.toLowerCase() === e.toLowerCase()), Je = "-apple-system, 'Segoe UI', system-ui, sans-serif", Pn = [
|
|
137
|
+
{ id: "Inter Tight", label: "Inter Tight", stack: `'Inter Tight', ${Je}` },
|
|
138
|
+
{ id: "Public Sans", label: "Public Sans", stack: `'Public Sans', ${Je}` },
|
|
139
|
+
{ id: "system-ui", label: "System UI", stack: `system-ui, ${Je}` },
|
|
140
140
|
{ id: "Georgia", label: "Georgia (serif)", stack: "Georgia, 'Times New Roman', serif" }
|
|
141
|
-
],
|
|
141
|
+
], Sa = (e) => {
|
|
142
142
|
var t;
|
|
143
|
-
return ((t =
|
|
144
|
-
},
|
|
145
|
-
function
|
|
143
|
+
return ((t = Pn.find((n) => n.id === e)) == null ? void 0 : t.stack) ?? `'${e}', ${Je}`;
|
|
144
|
+
}, Tn = ga(null), Fn = "calcsuite:settings";
|
|
145
|
+
function et(e, t) {
|
|
146
146
|
if (t == null) return e;
|
|
147
147
|
const n = Array.isArray(e) ? [...e] : { ...e };
|
|
148
148
|
for (const a of Object.keys(t)) {
|
|
149
149
|
const r = t[a], s = e[a];
|
|
150
|
-
n[a] = r && typeof r == "object" && !Array.isArray(r) && s && typeof s == "object" ?
|
|
150
|
+
n[a] = r && typeof r == "object" && !Array.isArray(r) && s && typeof s == "object" ? et(s, r) : r;
|
|
151
151
|
}
|
|
152
152
|
return n;
|
|
153
153
|
}
|
|
154
|
-
function
|
|
155
|
-
const t = e ? Qe
|
|
154
|
+
function Ca(e) {
|
|
155
|
+
const t = e ? et(Qe, e) : Qe;
|
|
156
156
|
try {
|
|
157
|
-
const n = localStorage.getItem(
|
|
158
|
-
if (n) return
|
|
157
|
+
const n = localStorage.getItem(Fn);
|
|
158
|
+
if (n) return et(t, JSON.parse(n));
|
|
159
159
|
} catch {
|
|
160
160
|
}
|
|
161
161
|
return t;
|
|
162
162
|
}
|
|
163
163
|
function ht(e) {
|
|
164
164
|
try {
|
|
165
|
-
e.persistence.driver === "localStorage" && localStorage.setItem(
|
|
165
|
+
e.persistence.driver === "localStorage" && localStorage.setItem(Fn, JSON.stringify(e));
|
|
166
166
|
} catch {
|
|
167
167
|
}
|
|
168
168
|
}
|
|
169
|
-
function
|
|
169
|
+
function fs({
|
|
170
170
|
children: e,
|
|
171
171
|
settings: t
|
|
172
172
|
}) {
|
|
173
|
-
const [n, a] = M(() =>
|
|
173
|
+
const [n, a] = M(() => Ca(t)), r = ke((h) => {
|
|
174
174
|
a(h), ht(h);
|
|
175
175
|
}, []), s = ke((h) => a((f) => {
|
|
176
|
-
const y =
|
|
176
|
+
const y = et(f, h);
|
|
177
177
|
return ht(y), y;
|
|
178
178
|
}), []), u = ke((h) => {
|
|
179
179
|
a((f) => {
|
|
@@ -188,10 +188,20 @@ function ps({
|
|
|
188
188
|
() => ({ settings: n, fmt: i, update: s, setRegion: u, reset: m, replace: d, resolvedTheme: c }),
|
|
189
189
|
[n, i, s, u, m, d, c]
|
|
190
190
|
), p = X(
|
|
191
|
-
() =>
|
|
191
|
+
() => {
|
|
192
|
+
var h;
|
|
193
|
+
return {
|
|
194
|
+
display: "contents",
|
|
195
|
+
"--fc-accent": n.ui.accent,
|
|
196
|
+
// Each preset ships its own readable text colour for on-accent surfaces (buttons, active nav,
|
|
197
|
+
// FAB). Without this, on-accent text falls back to white and low-contrasts on light accents.
|
|
198
|
+
"--fc-accent-ink": ((h = xa(n.ui.accent)) == null ? void 0 : h.ink) ?? "#ffffff",
|
|
199
|
+
"--fc-font-ui": Sa(n.ui.fontFamily)
|
|
200
|
+
};
|
|
201
|
+
},
|
|
192
202
|
[n.ui.accent, n.ui.fontFamily]
|
|
193
203
|
);
|
|
194
|
-
return /* @__PURE__ */ o(
|
|
204
|
+
return /* @__PURE__ */ o(Tn.Provider, { value: l, children: /* @__PURE__ */ o(
|
|
195
205
|
"div",
|
|
196
206
|
{
|
|
197
207
|
"data-fincalc-root": "",
|
|
@@ -203,17 +213,17 @@ function ps({
|
|
|
203
213
|
) });
|
|
204
214
|
}
|
|
205
215
|
function ue() {
|
|
206
|
-
const e =
|
|
216
|
+
const e = ba(Tn);
|
|
207
217
|
if (!e) throw new Error("useSettings must be used within SettingsProvider");
|
|
208
218
|
return e;
|
|
209
219
|
}
|
|
210
|
-
let
|
|
211
|
-
const
|
|
212
|
-
|
|
213
|
-
},
|
|
214
|
-
|
|
215
|
-
},
|
|
216
|
-
function
|
|
220
|
+
let tt = 0;
|
|
221
|
+
const Pa = () => {
|
|
222
|
+
tt += 1;
|
|
223
|
+
}, Ta = () => {
|
|
224
|
+
tt = Math.max(0, tt - 1);
|
|
225
|
+
}, Fa = () => tt > 0, Ia = 'a[href],button:not([disabled]),textarea:not([disabled]),input:not([disabled]),select:not([disabled]),[tabindex]:not([tabindex="-1"])';
|
|
226
|
+
function Ra({
|
|
217
227
|
open: e,
|
|
218
228
|
onClose: t,
|
|
219
229
|
children: n,
|
|
@@ -222,7 +232,7 @@ function Fa({
|
|
|
222
232
|
}) {
|
|
223
233
|
const s = de(null), u = de(null), m = ke(() => {
|
|
224
234
|
const h = s.current;
|
|
225
|
-
return h ? Array.from(h.querySelectorAll(
|
|
235
|
+
return h ? Array.from(h.querySelectorAll(Ia)).filter(
|
|
226
236
|
(f) => !f.hasAttribute("disabled") && f.getAttribute("aria-hidden") !== "true"
|
|
227
237
|
) : [];
|
|
228
238
|
}, []), [d, i] = M(e), [c, l] = M(!1);
|
|
@@ -246,7 +256,7 @@ function Fa({
|
|
|
246
256
|
document.body.style.overflow = "hidden";
|
|
247
257
|
const w = (k) => {
|
|
248
258
|
if (k.key === "Escape") {
|
|
249
|
-
if (
|
|
259
|
+
if (Fa()) return;
|
|
250
260
|
k.preventDefault(), k.stopImmediatePropagation(), t();
|
|
251
261
|
return;
|
|
252
262
|
}
|
|
@@ -292,17 +302,17 @@ function be(e, t, n, a = !1) {
|
|
|
292
302
|
let m = s.times(u.minus(1)).div(r);
|
|
293
303
|
return a && (m = m.times(r.plus(1))), m;
|
|
294
304
|
}
|
|
295
|
-
function
|
|
305
|
+
function nt(e, t, n) {
|
|
296
306
|
return g(e).times(g(t).plus(1).pow(n));
|
|
297
307
|
}
|
|
298
|
-
function
|
|
308
|
+
function In(e, t, n, a = !1) {
|
|
299
309
|
const r = g(t), s = g(e);
|
|
300
310
|
if (ce(r)) return s.times(n);
|
|
301
311
|
const u = r.plus(1).pow(n);
|
|
302
312
|
let m = s.times(g(1).minus(u.pow(-1))).div(r);
|
|
303
313
|
return a && (m = m.times(r.plus(1))), m;
|
|
304
314
|
}
|
|
305
|
-
function
|
|
315
|
+
function Ea(e, t, n) {
|
|
306
316
|
return g(e).div(g(t).plus(1).pow(n));
|
|
307
317
|
}
|
|
308
318
|
function we(e, t, n, a = 0, r = !1) {
|
|
@@ -312,11 +322,11 @@ function we(e, t, n, a = 0, r = !1) {
|
|
|
312
322
|
let m = g(e).times(u).plus(a).times(s).div(u.minus(1));
|
|
313
323
|
return r && (m = m.div(s.plus(1))), m;
|
|
314
324
|
}
|
|
315
|
-
function
|
|
325
|
+
function Ma(e, t, n) {
|
|
316
326
|
const a = g(n), r = g(e), s = g(t);
|
|
317
327
|
return ce(a) ? r.div(s) : H.ln(s.div(s.minus(r.times(a)))).div(H.ln(a.plus(1)));
|
|
318
328
|
}
|
|
319
|
-
function
|
|
329
|
+
function it(e, t = -0.9999, n = 100, a = 200) {
|
|
320
330
|
let r = g(t), s = g(n), u = e(r), m = e(s);
|
|
321
331
|
if (u.times(m).gt(0)) return null;
|
|
322
332
|
for (let d = 0; d < a; d++) {
|
|
@@ -333,42 +343,42 @@ function At(e, t) {
|
|
|
333
343
|
a = a.plus(g(t[r]).div(n.plus(1).pow(r)));
|
|
334
344
|
return a;
|
|
335
345
|
}
|
|
336
|
-
function
|
|
337
|
-
return
|
|
346
|
+
function Rn(e) {
|
|
347
|
+
return it((t) => At(t, e));
|
|
338
348
|
}
|
|
339
|
-
const
|
|
340
|
-
function
|
|
349
|
+
const $a = (e, t) => (Date.parse(t) - Date.parse(e)) / 864e5;
|
|
350
|
+
function En(e, t) {
|
|
341
351
|
const n = g(e), a = t[0].date;
|
|
342
352
|
let r = g(0);
|
|
343
353
|
for (const s of t) {
|
|
344
|
-
const u = g(
|
|
354
|
+
const u = g($a(a, s.date)).div(365);
|
|
345
355
|
r = r.plus(g(s.amount).div(n.plus(1).pow(u)));
|
|
346
356
|
}
|
|
347
357
|
return r;
|
|
348
358
|
}
|
|
349
|
-
function
|
|
359
|
+
function Mn(e) {
|
|
350
360
|
if (e.length < 2) return null;
|
|
351
361
|
const t = [...e].sort((n, a) => Date.parse(n.date) - Date.parse(a.date));
|
|
352
|
-
return
|
|
362
|
+
return it((n) => En(n, t), -0.9999, 100);
|
|
353
363
|
}
|
|
354
|
-
function
|
|
364
|
+
function st(e, t, n) {
|
|
355
365
|
return g(t).div(e).pow(g(1).div(n)).minus(1);
|
|
356
366
|
}
|
|
357
|
-
const
|
|
367
|
+
const ys = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
358
368
|
__proto__: null,
|
|
359
|
-
bisectRate:
|
|
360
|
-
cagr:
|
|
369
|
+
bisectRate: it,
|
|
370
|
+
cagr: st,
|
|
361
371
|
fvAnnuity: be,
|
|
362
|
-
fvLump:
|
|
363
|
-
irr:
|
|
364
|
-
nper:
|
|
372
|
+
fvLump: nt,
|
|
373
|
+
irr: Rn,
|
|
374
|
+
nper: Ma,
|
|
365
375
|
npv: At,
|
|
366
376
|
periodic: J,
|
|
367
377
|
pmt: we,
|
|
368
|
-
pvAnnuity:
|
|
369
|
-
pvLump:
|
|
370
|
-
xirr:
|
|
371
|
-
xnpv:
|
|
378
|
+
pvAnnuity: In,
|
|
379
|
+
pvLump: Ea,
|
|
380
|
+
xirr: Mn,
|
|
381
|
+
xnpv: En
|
|
372
382
|
}, Symbol.toStringTag, { value: "Module" })), me = {
|
|
373
383
|
IN: {
|
|
374
384
|
region: "IN",
|
|
@@ -405,18 +415,18 @@ class se extends Error {
|
|
|
405
415
|
this.name = "FinCalcError", this.code = n, this.field = r;
|
|
406
416
|
}
|
|
407
417
|
}
|
|
408
|
-
const
|
|
418
|
+
const Aa = 2, te = (e) => e.toDecimalPlaces(Aa, H.ROUND_HALF_UP), St = (e) => e.div(100).div(12);
|
|
409
419
|
function Ct(e, t, n) {
|
|
410
420
|
if (ce(t)) return e.div(n);
|
|
411
421
|
const a = t.plus(1).pow(n);
|
|
412
422
|
return e.times(t).times(a).div(a.minus(1));
|
|
413
423
|
}
|
|
414
|
-
function
|
|
424
|
+
function Da(e, t, n) {
|
|
415
425
|
if (ce(t)) return e.times(n);
|
|
416
426
|
const a = t.plus(1).pow(n);
|
|
417
427
|
return e.times(a.minus(1)).div(t.times(a));
|
|
418
428
|
}
|
|
419
|
-
function
|
|
429
|
+
function La(e, t, n) {
|
|
420
430
|
if (ce(t)) return Math.ceil(e.div(n).toNumber());
|
|
421
431
|
const a = e.times(t);
|
|
422
432
|
if (n.lte(a))
|
|
@@ -442,7 +452,7 @@ function Gt(e, t, n, a) {
|
|
|
442
452
|
throw new se("SOLVER_DID_NOT_CONVERGE", "Could not find a rate within the allowed range.", "rate");
|
|
443
453
|
return u;
|
|
444
454
|
}
|
|
445
|
-
function
|
|
455
|
+
function Ua(e, t, n, a) {
|
|
446
456
|
const r = [];
|
|
447
457
|
let s = e, u = g(0);
|
|
448
458
|
for (let m = 1; m <= n; m++) {
|
|
@@ -460,7 +470,7 @@ function Da(e, t, n, a) {
|
|
|
460
470
|
}
|
|
461
471
|
return r;
|
|
462
472
|
}
|
|
463
|
-
function
|
|
473
|
+
function Oa(e) {
|
|
464
474
|
const t = [];
|
|
465
475
|
for (const n of e) {
|
|
466
476
|
const a = Math.ceil(n.month / 12);
|
|
@@ -503,17 +513,17 @@ function Ie(e) {
|
|
|
503
513
|
i = te(Ct(u, k(), d)), l = "PMT = P·r·(1+r)^n / ((1+r)^n − 1)";
|
|
504
514
|
break;
|
|
505
515
|
case "principal":
|
|
506
|
-
u =
|
|
516
|
+
u = Da(i, k(), d), l = "P = PMT·((1+r)^n − 1) / (r·(1+r)^n)";
|
|
507
517
|
break;
|
|
508
518
|
case "tenure":
|
|
509
|
-
d =
|
|
519
|
+
d = La(u, k(), i), l = "n = ln(PMT / (PMT − P·r)) / ln(1 + r)";
|
|
510
520
|
break;
|
|
511
521
|
case "rate":
|
|
512
522
|
m = Gt(u, d, i, t.maxRatePct), l = "solve r: PMT = P·r·(1+r)^n / ((1+r)^n − 1)";
|
|
513
523
|
break;
|
|
514
524
|
}
|
|
515
525
|
}
|
|
516
|
-
const p = St(m), h = n === "flat" ? i : te(Ct(u, p, d)), f =
|
|
526
|
+
const p = St(m), h = n === "flat" ? i : te(Ct(u, p, d)), f = Ua(u, p, d, h);
|
|
517
527
|
d = f.length;
|
|
518
528
|
const y = f.reduce((k, S) => k.plus(S.interest), g(0)), w = f.reduce((k, S) => k.plus(S.payment), g(0));
|
|
519
529
|
return {
|
|
@@ -527,7 +537,7 @@ function Ie(e) {
|
|
|
527
537
|
totalInterest: te(y),
|
|
528
538
|
totalPayment: te(w),
|
|
529
539
|
schedule: f,
|
|
530
|
-
byYear:
|
|
540
|
+
byYear: Oa(f),
|
|
531
541
|
chart: {
|
|
532
542
|
balance: f.map((k) => k.closingBalance),
|
|
533
543
|
cumulativeInterest: f.map((k) => k.cumulativeInterest)
|
|
@@ -549,7 +559,7 @@ const C = (e, t = 0) => {
|
|
|
549
559
|
tone: n,
|
|
550
560
|
sub: a
|
|
551
561
|
}), U = (e) => e.toDecimalPlaces(2, H.ROUND_HALF_UP);
|
|
552
|
-
function
|
|
562
|
+
function $n(e, t) {
|
|
553
563
|
const n = /* @__PURE__ */ new Map();
|
|
554
564
|
for (const r of e) {
|
|
555
565
|
const s = Math.ceil(r.month / 12), u = n.get(s);
|
|
@@ -567,7 +577,7 @@ function Mn(e, t) {
|
|
|
567
577
|
}
|
|
568
578
|
return a;
|
|
569
579
|
}
|
|
570
|
-
const
|
|
580
|
+
const An = [
|
|
571
581
|
{
|
|
572
582
|
key: "count",
|
|
573
583
|
label: "How many loans",
|
|
@@ -578,19 +588,19 @@ const $n = [
|
|
|
578
588
|
];
|
|
579
589
|
for (let e = 1; e <= 5; e++) {
|
|
580
590
|
const t = e <= 2, n = t ? void 0 : (a) => C(a.count, 2) >= e;
|
|
581
|
-
|
|
591
|
+
An.push(
|
|
582
592
|
{ key: `p${e}`, label: `Loan ${e} amount`, kind: "money", prefix: "currency", default: e <= 2 ? "2500000" : "", optional: !t, showIf: n },
|
|
583
593
|
{ key: `r${e}`, label: `Loan ${e} rate`, kind: "percent", suffix: "%", default: e === 1 ? 9 : e === 2 ? 8.65 : "", optional: !t, showIf: n, labelByRegion: {} },
|
|
584
594
|
{ key: `t${e}`, label: `Loan ${e} tenure`, kind: "tenure", default: 240, optional: !t, showIf: n, labelByRegion: { US: `Loan ${e} term` } }
|
|
585
595
|
);
|
|
586
596
|
}
|
|
587
|
-
const
|
|
597
|
+
const Ba = {
|
|
588
598
|
id: "loan.compare",
|
|
589
599
|
group: "loans",
|
|
590
600
|
title: "Compare loans",
|
|
591
601
|
blurb: "Line up 2–5 loans and see which costs least over its full life.",
|
|
592
602
|
keywords: ["compare", "loan", "cheapest", "emi", "best offer"],
|
|
593
|
-
inputs:
|
|
603
|
+
inputs: An,
|
|
594
604
|
compute(e, t) {
|
|
595
605
|
const n = me[t.region], a = Math.max(2, Math.min(5, C(e.count, 2))), r = [];
|
|
596
606
|
for (let l = 1; l <= a; l++) {
|
|
@@ -628,7 +638,7 @@ const Ua = {
|
|
|
628
638
|
raw: i
|
|
629
639
|
};
|
|
630
640
|
}
|
|
631
|
-
},
|
|
641
|
+
}, _a = {
|
|
632
642
|
id: "loan.prepay",
|
|
633
643
|
group: "loans",
|
|
634
644
|
title: "Prepayment impact",
|
|
@@ -697,7 +707,7 @@ const Ua = {
|
|
|
697
707
|
schedule: {
|
|
698
708
|
title: "New amortisation",
|
|
699
709
|
columns: ["Month", "Principal", "Interest", "Prepay", "Balance"],
|
|
700
|
-
groups:
|
|
710
|
+
groups: $n(w, t),
|
|
701
711
|
toneCols: { 1: "principal", 2: "interest" }
|
|
702
712
|
},
|
|
703
713
|
notes: B,
|
|
@@ -712,7 +722,7 @@ const Ua = {
|
|
|
712
722
|
}
|
|
713
723
|
};
|
|
714
724
|
}
|
|
715
|
-
},
|
|
725
|
+
}, Ha = {
|
|
716
726
|
id: "loan.transfer",
|
|
717
727
|
group: "loans",
|
|
718
728
|
title: "Balance transfer",
|
|
@@ -756,7 +766,7 @@ const Ua = {
|
|
|
756
766
|
}
|
|
757
767
|
};
|
|
758
768
|
}
|
|
759
|
-
},
|
|
769
|
+
}, qa = {
|
|
760
770
|
id: "loan.eligibility",
|
|
761
771
|
group: "loans",
|
|
762
772
|
title: "Loan eligibility",
|
|
@@ -797,7 +807,7 @@ const Ua = {
|
|
|
797
807
|
}
|
|
798
808
|
const d = [];
|
|
799
809
|
let i = g(0);
|
|
800
|
-
return u.gt(0) ? i = U(
|
|
810
|
+
return u.gt(0) ? i = U(In(u, s, r)) : d.push("Existing obligations already use up the allowed share of income — no additional loan capacity."), {
|
|
801
811
|
primary: v("Eligible loan amount", t.fmt.money(i), "positive"),
|
|
802
812
|
secondary: m,
|
|
803
813
|
formula: t.region === "US" ? "EMI = min(income·frontDTI, income·backDTI − debts); P = PV of that annuity" : "EMI = income·FOIR − existingEMI; P = PV of that annuity",
|
|
@@ -808,7 +818,7 @@ const Ua = {
|
|
|
808
818
|
}
|
|
809
819
|
};
|
|
810
820
|
}
|
|
811
|
-
},
|
|
821
|
+
}, Ga = {
|
|
812
822
|
id: "loan.stepEmi",
|
|
813
823
|
group: "loans",
|
|
814
824
|
title: "Step-up / step-down EMI",
|
|
@@ -825,7 +835,7 @@ const Ua = {
|
|
|
825
835
|
let S = a;
|
|
826
836
|
for (let F = 1; F <= s; F++) S = S.plus(S.times(m)).minus(k.times(d(F)));
|
|
827
837
|
return S;
|
|
828
|
-
}, c = U(
|
|
838
|
+
}, c = U(it((k) => i(k), 0, a.toNumber(), 200) ?? we(a, m, s)), l = [];
|
|
829
839
|
let p = a, h = g(0), f = c;
|
|
830
840
|
for (let k = 1; k <= s && p.gt("0.005"); k++) {
|
|
831
841
|
const S = U(p.times(m));
|
|
@@ -845,7 +855,7 @@ const Ua = {
|
|
|
845
855
|
schedule: {
|
|
846
856
|
title: "Amortisation",
|
|
847
857
|
columns: ["Month", "Principal", "Interest", n.paymentLabel, "Balance"],
|
|
848
|
-
groups:
|
|
858
|
+
groups: $n(l, t),
|
|
849
859
|
toneCols: { 1: "principal", 2: "interest" }
|
|
850
860
|
},
|
|
851
861
|
notes: [`EMI changes by ${t.fmt.pct(g(C(e.annualStepPct)))} every 12 months. A step-up starts lower and pays a little more interest than a flat EMI; a step-down does the reverse.`],
|
|
@@ -859,7 +869,7 @@ const Ua = {
|
|
|
859
869
|
}
|
|
860
870
|
};
|
|
861
871
|
}
|
|
862
|
-
},
|
|
872
|
+
}, ja = {
|
|
863
873
|
id: "loan.moratorium",
|
|
864
874
|
group: "loans",
|
|
865
875
|
title: "Moratorium / EMI holiday",
|
|
@@ -914,7 +924,7 @@ const Ua = {
|
|
|
914
924
|
}
|
|
915
925
|
};
|
|
916
926
|
}
|
|
917
|
-
},
|
|
927
|
+
}, Va = {
|
|
918
928
|
id: "loan.overdraft",
|
|
919
929
|
group: "loans",
|
|
920
930
|
title: "Overdraft / flexi loan",
|
|
@@ -944,7 +954,7 @@ const Ua = {
|
|
|
944
954
|
}
|
|
945
955
|
};
|
|
946
956
|
}
|
|
947
|
-
},
|
|
957
|
+
}, Ya = {
|
|
948
958
|
id: "loan.refinance",
|
|
949
959
|
group: "loans",
|
|
950
960
|
title: "Refinance",
|
|
@@ -991,16 +1001,16 @@ const Ua = {
|
|
|
991
1001
|
}
|
|
992
1002
|
};
|
|
993
1003
|
}
|
|
994
|
-
},
|
|
995
|
-
Ua,
|
|
996
|
-
Oa,
|
|
1004
|
+
}, Ka = [
|
|
997
1005
|
Ba,
|
|
998
1006
|
_a,
|
|
999
1007
|
Ha,
|
|
1000
1008
|
qa,
|
|
1001
1009
|
Ga,
|
|
1002
|
-
ja
|
|
1003
|
-
|
|
1010
|
+
ja,
|
|
1011
|
+
Va,
|
|
1012
|
+
Ya
|
|
1013
|
+
], lt = Qe.defaults.sipReturnPercent, Wa = Qe.defaults.inflationPercent, ct = (e, t) => ({
|
|
1004
1014
|
labels: e,
|
|
1005
1015
|
series: [{ name: "Value", tone: "accent", points: t, area: !0 }]
|
|
1006
1016
|
}), Dt = (e) => ({
|
|
@@ -1010,7 +1020,7 @@ const Ua = {
|
|
|
1010
1020
|
}), Lt = (e, t) => [
|
|
1011
1021
|
{ label: "Invested", value: Number(e), tone: "principal" },
|
|
1012
1022
|
{ label: "Gains", value: Number(t), tone: "interest" }
|
|
1013
|
-
],
|
|
1023
|
+
], za = {
|
|
1014
1024
|
id: "invest.sip",
|
|
1015
1025
|
group: "invest",
|
|
1016
1026
|
title: "SIP Calculator",
|
|
@@ -1018,7 +1028,7 @@ const Ua = {
|
|
|
1018
1028
|
keywords: ["sip", "systematic investment plan", "mutual fund", "monthly investment", "future value"],
|
|
1019
1029
|
inputs: [
|
|
1020
1030
|
{ key: "monthlyAmount", label: "Monthly investment", kind: "money", prefix: "currency", default: "10000" },
|
|
1021
|
-
{ key: "expectedReturnPct", label: "Expected return", kind: "percent", suffix: "% p.a.", default:
|
|
1031
|
+
{ key: "expectedReturnPct", label: "Expected return", kind: "percent", suffix: "% p.a.", default: lt },
|
|
1022
1032
|
{ key: "tenure", label: "Investment period", kind: "tenure", default: 120 }
|
|
1023
1033
|
],
|
|
1024
1034
|
compute(e, t) {
|
|
@@ -1036,7 +1046,7 @@ const Ua = {
|
|
|
1036
1046
|
],
|
|
1037
1047
|
split: Lt(i.toFixed(2), c.toFixed(2)),
|
|
1038
1048
|
schedule: Dt(p),
|
|
1039
|
-
chart:
|
|
1049
|
+
chart: ct(p.map((f) => f.label), h),
|
|
1040
1050
|
formula: "FV = P·[((1+i)^n − 1) / i]·(1+i), i = r/12 (invested at the start of each month)",
|
|
1041
1051
|
notes: ["Returns are assumed constant; actual market returns vary year to year."],
|
|
1042
1052
|
raw: {
|
|
@@ -1047,7 +1057,7 @@ const Ua = {
|
|
|
1047
1057
|
}
|
|
1048
1058
|
};
|
|
1049
1059
|
}
|
|
1050
|
-
},
|
|
1060
|
+
}, Ja = {
|
|
1051
1061
|
id: "invest.stepupSip",
|
|
1052
1062
|
group: "invest",
|
|
1053
1063
|
title: "Step-up SIP Calculator",
|
|
@@ -1056,7 +1066,7 @@ const Ua = {
|
|
|
1056
1066
|
inputs: [
|
|
1057
1067
|
{ key: "monthlyAmount", label: "Initial monthly investment", kind: "money", prefix: "currency", default: "10000" },
|
|
1058
1068
|
{ key: "annualStepPct", label: "Annual step-up", kind: "percent", suffix: "%", default: "10" },
|
|
1059
|
-
{ key: "returnPct", label: "Expected return", kind: "percent", suffix: "% p.a.", default:
|
|
1069
|
+
{ key: "returnPct", label: "Expected return", kind: "percent", suffix: "% p.a.", default: lt },
|
|
1060
1070
|
{ key: "tenure", label: "Investment period", kind: "tenure", default: 120 }
|
|
1061
1071
|
],
|
|
1062
1072
|
compute(e, t) {
|
|
@@ -1075,13 +1085,13 @@ const Ua = {
|
|
|
1075
1085
|
],
|
|
1076
1086
|
split: Lt(c.toFixed(2), f.toFixed(2)),
|
|
1077
1087
|
schedule: Dt(p),
|
|
1078
|
-
chart:
|
|
1088
|
+
chart: ct(p.map((y) => y.label), h),
|
|
1079
1089
|
formula: "Monthly simulation; the SIP amount is increased by the step-up % every 12 months",
|
|
1080
1090
|
notes: ["The monthly amount steps up on each yearly anniversary; returns are assumed constant."],
|
|
1081
1091
|
raw: { maturity: i.toFixed(2), invested: c.toFixed(2), gains: f.toFixed(2), finalMonthly: l.toFixed(2) }
|
|
1082
1092
|
};
|
|
1083
1093
|
}
|
|
1084
|
-
},
|
|
1094
|
+
}, Za = { annual: 1, semiannual: 2, quarterly: 4, monthly: 12 }, Xa = {
|
|
1085
1095
|
id: "invest.lumpsum",
|
|
1086
1096
|
group: "invest",
|
|
1087
1097
|
title: "Lump Sum Calculator",
|
|
@@ -1089,7 +1099,7 @@ const Ua = {
|
|
|
1089
1099
|
keywords: ["lump sum", "lumpsum", "one time investment", "compound interest", "maturity"],
|
|
1090
1100
|
inputs: [
|
|
1091
1101
|
{ key: "principal", label: "Investment amount", kind: "money", prefix: "currency", default: "100000" },
|
|
1092
|
-
{ key: "ratePct", label: "Expected return", kind: "percent", suffix: "% p.a.", default:
|
|
1102
|
+
{ key: "ratePct", label: "Expected return", kind: "percent", suffix: "% p.a.", default: lt },
|
|
1093
1103
|
{ key: "years", label: "Investment period", kind: "years", suffix: "years", default: 10 },
|
|
1094
1104
|
{
|
|
1095
1105
|
key: "compounding",
|
|
@@ -1105,7 +1115,7 @@ const Ua = {
|
|
|
1105
1115
|
}
|
|
1106
1116
|
],
|
|
1107
1117
|
compute(e, t) {
|
|
1108
|
-
const { D: n, fmt: a } = t, r = D(e.principal, "100000"), s = n(C(e.ratePct, Number(t.settings.defaults.sipReturnPercent))), u = Math.max(1, Math.round(C(e.years, 10))), m =
|
|
1118
|
+
const { D: n, fmt: a } = t, r = D(e.principal, "100000"), s = n(C(e.ratePct, Number(t.settings.defaults.sipReturnPercent))), u = Math.max(1, Math.round(C(e.years, 10))), m = Za[_(e.compounding, "annual")] ?? 1, d = s.div(100).div(m), i = r.times(d.plus(1).pow(m * u)), c = i.minus(r), l = r.isZero() ? n(0) : st(r, i, u), p = [], h = [];
|
|
1109
1119
|
for (let f = 1; f <= u; f++) {
|
|
1110
1120
|
const y = r.times(d.plus(1).pow(m * f));
|
|
1111
1121
|
p.push({ label: String(f), cells: [a.money(r), a.money(y.minus(r)), a.money(y)] }), h.push(Number(y.toFixed(2)));
|
|
@@ -1119,13 +1129,13 @@ const Ua = {
|
|
|
1119
1129
|
],
|
|
1120
1130
|
split: Lt(r.toFixed(2), c.toFixed(2)),
|
|
1121
1131
|
schedule: Dt(p),
|
|
1122
|
-
chart:
|
|
1132
|
+
chart: ct(p.map((f) => f.label), h),
|
|
1123
1133
|
formula: "A = P·(1 + r/f)^(f·t)",
|
|
1124
1134
|
notes: ["Returns are assumed constant across the whole period."],
|
|
1125
1135
|
raw: { maturity: i.toFixed(2), invested: r.toFixed(2), gains: c.toFixed(2), cagr: l.times(100).toFixed(4) }
|
|
1126
1136
|
};
|
|
1127
1137
|
}
|
|
1128
|
-
},
|
|
1138
|
+
}, Qa = 1200, er = {
|
|
1129
1139
|
id: "invest.swp",
|
|
1130
1140
|
group: "invest",
|
|
1131
1141
|
title: "SWP Calculator",
|
|
@@ -1138,7 +1148,7 @@ const Ua = {
|
|
|
1138
1148
|
{ key: "tenureMonths", label: "Withdrawal period", kind: "tenure", default: 120, optional: !0 }
|
|
1139
1149
|
],
|
|
1140
1150
|
compute(e, t) {
|
|
1141
|
-
const { D: n, fmt: a } = t, r = D(e.corpus, "5000000"), s = D(e.withdrawalPerMonth, "30000"), u = C(e.expectedReturnPct, 8), m = J(u, 12), d = C(e.tenureMonths, 0), i = d > 0 ? Math.round(d) :
|
|
1151
|
+
const { D: n, fmt: a } = t, r = D(e.corpus, "5000000"), s = D(e.withdrawalPerMonth, "30000"), u = C(e.expectedReturnPct, 8), m = J(u, 12), d = C(e.tenureMonths, 0), i = d > 0 ? Math.round(d) : Qa;
|
|
1142
1152
|
let c = r, l = n(0), p = 0;
|
|
1143
1153
|
const h = [], f = [];
|
|
1144
1154
|
let y = r, w = n(0);
|
|
@@ -1164,7 +1174,7 @@ const Ua = {
|
|
|
1164
1174
|
rows: h,
|
|
1165
1175
|
toneCols: { 2: "interest", 3: "principal" }
|
|
1166
1176
|
},
|
|
1167
|
-
chart:
|
|
1177
|
+
chart: ct(h.map((N) => N.label), f),
|
|
1168
1178
|
formula: "Each month: balance = balance·(1 + r/12) − withdrawal",
|
|
1169
1179
|
notes: [
|
|
1170
1180
|
S ? `The corpus is exhausted in month ${p}; the final withdrawal may be partial.` : "The corpus survives the whole withdrawal period; the remaining balance is shown.",
|
|
@@ -1177,7 +1187,7 @@ const Ua = {
|
|
|
1177
1187
|
}
|
|
1178
1188
|
};
|
|
1179
1189
|
}
|
|
1180
|
-
},
|
|
1190
|
+
}, tr = {
|
|
1181
1191
|
id: "invest.goal",
|
|
1182
1192
|
group: "invest",
|
|
1183
1193
|
title: "Goal SIP Planner",
|
|
@@ -1186,12 +1196,12 @@ const Ua = {
|
|
|
1186
1196
|
inputs: [
|
|
1187
1197
|
{ key: "targetCorpus", label: "Today's cost of goal", kind: "money", prefix: "currency", default: "10000000" },
|
|
1188
1198
|
{ key: "years", label: "Years to goal", kind: "years", suffix: "years", default: 15 },
|
|
1189
|
-
{ key: "expectedReturnPct", label: "Expected return", kind: "percent", suffix: "% p.a.", default:
|
|
1190
|
-
{ key: "inflationPct", label: "Inflation", kind: "percent", suffix: "% p.a.", default:
|
|
1199
|
+
{ key: "expectedReturnPct", label: "Expected return", kind: "percent", suffix: "% p.a.", default: lt },
|
|
1200
|
+
{ key: "inflationPct", label: "Inflation", kind: "percent", suffix: "% p.a.", default: Wa },
|
|
1191
1201
|
{ key: "existingSavings", label: "Existing savings", kind: "money", prefix: "currency", default: "0", optional: !0 }
|
|
1192
1202
|
],
|
|
1193
1203
|
compute(e, t) {
|
|
1194
|
-
const { D: n, fmt: a } = t, r = D(e.targetCorpus, "10000000"), s = Math.max(1, Math.round(C(e.years, 15))), u = C(e.expectedReturnPct, Number(t.settings.defaults.sipReturnPercent)), m = n(C(e.inflationPct, Number(t.settings.defaults.inflationPercent))).div(100), d = D(e.existingSavings, "0"), i = s * 12, c = J(u, 12), l = r.times(m.plus(1).pow(s)), p =
|
|
1204
|
+
const { D: n, fmt: a } = t, r = D(e.targetCorpus, "10000000"), s = Math.max(1, Math.round(C(e.years, 15))), u = C(e.expectedReturnPct, Number(t.settings.defaults.sipReturnPercent)), m = n(C(e.inflationPct, Number(t.settings.defaults.inflationPercent))).div(100), d = D(e.existingSavings, "0"), i = s * 12, c = J(u, 12), l = r.times(m.plus(1).pow(s)), p = nt(d, c, i), h = l.minus(p), f = be(1, c, i, !0), y = h.gt(0) ? h.div(f) : n(0), w = y.times(i), k = h.gt(0) ? h.minus(w) : n(0), S = [
|
|
1195
1205
|
`Target grows with ${a.pct(m.times(100))} inflation to ${a.money(l)} in ${s} years.`
|
|
1196
1206
|
];
|
|
1197
1207
|
d.gt(0) && S.push(`Existing savings grow to ${a.money(p)}, reducing what the SIP must fund.`);
|
|
@@ -1215,14 +1225,14 @@ const Ua = {
|
|
|
1215
1225
|
}
|
|
1216
1226
|
};
|
|
1217
1227
|
}
|
|
1218
|
-
},
|
|
1228
|
+
}, nr = [za, Ja, Xa, er, tr], Dn = "10% TDS applies on interest above ₹40,000/yr (₹50,000 for senior citizens). Submit Form 15G/15H to waive if income is below the taxable limit.", Oe = (e, t, n) => ({
|
|
1219
1229
|
labels: e,
|
|
1220
1230
|
series: [{ name: n, tone: "accent", points: t, area: !0 }]
|
|
1221
1231
|
}), Be = (e, t, n) => ({
|
|
1222
1232
|
columns: e,
|
|
1223
1233
|
rows: t,
|
|
1224
1234
|
toneCols: { [n]: "interest" }
|
|
1225
|
-
}),
|
|
1235
|
+
}), ar = {
|
|
1226
1236
|
id: "invest.fd",
|
|
1227
1237
|
group: "invest",
|
|
1228
1238
|
title: "Fixed Deposit (FD)",
|
|
@@ -1283,7 +1293,7 @@ const Ua = {
|
|
|
1283
1293
|
formula: i ? "Interest/period = P·(r/f); principal returned at maturity" : "A = P·(1 + r/f)^(f·t)",
|
|
1284
1294
|
notes: [
|
|
1285
1295
|
i ? "Interest is paid out each period; the principal is returned at maturity." : "Interest is reinvested (compounded) and paid with the principal at maturity.",
|
|
1286
|
-
|
|
1296
|
+
Dn
|
|
1287
1297
|
],
|
|
1288
1298
|
raw: {
|
|
1289
1299
|
maturity: k.toFixed(2),
|
|
@@ -1294,7 +1304,7 @@ const Ua = {
|
|
|
1294
1304
|
}
|
|
1295
1305
|
};
|
|
1296
1306
|
}
|
|
1297
|
-
},
|
|
1307
|
+
}, rr = {
|
|
1298
1308
|
id: "invest.rd",
|
|
1299
1309
|
group: "invest",
|
|
1300
1310
|
title: "Recurring Deposit (RD)",
|
|
@@ -1335,12 +1345,12 @@ const Ua = {
|
|
|
1335
1345
|
schedule: Be(["Year", "Invested", "Interest", "Value"], p, 2),
|
|
1336
1346
|
chart: Oe(p.map((f) => f.label), h, "Value"),
|
|
1337
1347
|
formula: "M = Σ deposit·(1 + r/4)^(quarters remaining)",
|
|
1338
|
-
notes: ["Interest is compounded quarterly, the standard for bank recurring deposits.",
|
|
1348
|
+
notes: ["Interest is compounded quarterly, the standard for bank recurring deposits.", Dn],
|
|
1339
1349
|
warnings: d,
|
|
1340
1350
|
raw: { maturity: i.toFixed(2), invested: c.toFixed(2), interest: l.toFixed(2) }
|
|
1341
1351
|
};
|
|
1342
1352
|
}
|
|
1343
|
-
},
|
|
1353
|
+
}, or = {
|
|
1344
1354
|
id: "invest.ppf",
|
|
1345
1355
|
group: "invest",
|
|
1346
1356
|
title: "Public Provident Fund (PPF)",
|
|
@@ -1397,7 +1407,7 @@ const Ua = {
|
|
|
1397
1407
|
raw: { maturity: i.toFixed(2), invested: p.toFixed(2), interest: h.toFixed(2) }
|
|
1398
1408
|
};
|
|
1399
1409
|
}
|
|
1400
|
-
},
|
|
1410
|
+
}, ir = {
|
|
1401
1411
|
id: "invest.nps",
|
|
1402
1412
|
group: "invest",
|
|
1403
1413
|
title: "National Pension System (NPS)",
|
|
@@ -1441,7 +1451,7 @@ const Ua = {
|
|
|
1441
1451
|
}
|
|
1442
1452
|
};
|
|
1443
1453
|
}
|
|
1444
|
-
},
|
|
1454
|
+
}, sr = {
|
|
1445
1455
|
id: "invest.epf",
|
|
1446
1456
|
group: "invest",
|
|
1447
1457
|
title: "Employees’ Provident Fund (EPF)",
|
|
@@ -1490,7 +1500,7 @@ const Ua = {
|
|
|
1490
1500
|
raw: { corpus: h.toFixed(2), contributions: f.toFixed(2), interest: k.toFixed(2) }
|
|
1491
1501
|
};
|
|
1492
1502
|
}
|
|
1493
|
-
},
|
|
1503
|
+
}, lr = {
|
|
1494
1504
|
id: "invest.ssy",
|
|
1495
1505
|
group: "invest",
|
|
1496
1506
|
title: "Sukanya Samriddhi Yojana (SSY)",
|
|
@@ -1533,7 +1543,7 @@ const Ua = {
|
|
|
1533
1543
|
raw: { maturity: l.toFixed(2), invested: f.toFixed(2), interest: y.toFixed(2) }
|
|
1534
1544
|
};
|
|
1535
1545
|
}
|
|
1536
|
-
},
|
|
1546
|
+
}, cr = [ar, rr, or, ir, sr, lr], ur = {
|
|
1537
1547
|
id: "invest.401k",
|
|
1538
1548
|
group: "invest",
|
|
1539
1549
|
title: "401(k) with Employer Match",
|
|
@@ -1597,7 +1607,7 @@ const Ua = {
|
|
|
1597
1607
|
}
|
|
1598
1608
|
};
|
|
1599
1609
|
}
|
|
1600
|
-
},
|
|
1610
|
+
}, dr = {
|
|
1601
1611
|
id: "invest.iraCompare",
|
|
1602
1612
|
group: "invest",
|
|
1603
1613
|
title: "Roth vs Traditional IRA",
|
|
@@ -1651,7 +1661,7 @@ const Ua = {
|
|
|
1651
1661
|
}
|
|
1652
1662
|
};
|
|
1653
1663
|
}
|
|
1654
|
-
},
|
|
1664
|
+
}, mr = {
|
|
1655
1665
|
id: "invest.529",
|
|
1656
1666
|
group: "invest",
|
|
1657
1667
|
title: "529 College Savings",
|
|
@@ -1667,7 +1677,7 @@ const Ua = {
|
|
|
1667
1677
|
{ key: "collegeCostInflationPct", label: "College cost inflation", kind: "percent", suffix: "%", default: 5, advanced: !0 }
|
|
1668
1678
|
],
|
|
1669
1679
|
compute(e, t) {
|
|
1670
|
-
const { fmt: n } = t, a = g(C(e.currentSavings)), r = g(C(e.monthlyContribution)), s = Math.max(0, Math.round(C(e.yearsUntilCollege))), u = s * 12, m = J(C(e.expectedReturnPct), 12), d =
|
|
1680
|
+
const { fmt: n } = t, a = g(C(e.currentSavings)), r = g(C(e.monthlyContribution)), s = Math.max(0, Math.round(C(e.yearsUntilCollege))), u = s * 12, m = J(C(e.expectedReturnPct), 12), d = nt(a, m, u), i = be(r, m, u), c = d.plus(i), l = a.plus(r.times(u)), p = c.minus(l), h = [
|
|
1671
1681
|
v("Total invested", n.money(l), "principal"),
|
|
1672
1682
|
v("Investment growth", n.money(p), "interest")
|
|
1673
1683
|
], f = {
|
|
@@ -1681,7 +1691,7 @@ const Ua = {
|
|
|
1681
1691
|
const k = g(C(e.currentAnnualCost)), S = g(C(e.collegeCostInflationPct)).div(100);
|
|
1682
1692
|
let F = g(0);
|
|
1683
1693
|
for (let x = 0; x < 4; x++)
|
|
1684
|
-
F = F.plus(
|
|
1694
|
+
F = F.plus(nt(k, S, s + x));
|
|
1685
1695
|
const N = c.minus(F), P = N.gte(0);
|
|
1686
1696
|
h.push(v("4-year college cost", n.money(F), "default", "inflation-adjusted")), h.push(
|
|
1687
1697
|
v(
|
|
@@ -1706,7 +1716,7 @@ const Ua = {
|
|
|
1706
1716
|
raw: f
|
|
1707
1717
|
};
|
|
1708
1718
|
}
|
|
1709
|
-
},
|
|
1719
|
+
}, pr = [ur, dr, mr], hr = (e) => e === "annual" ? 1 : e === "semiannual" ? 2 : e === "quarterly" ? 4 : 12, ut = (e) => _(e).split(/[, ]+/).map((t) => t.trim()).filter(Boolean).map(Number).filter((t) => Number.isFinite(t)), fr = {
|
|
1710
1720
|
id: "returns.tvm",
|
|
1711
1721
|
group: "returns",
|
|
1712
1722
|
title: "Time value of money (TVM)",
|
|
@@ -1737,7 +1747,7 @@ const Ua = {
|
|
|
1737
1747
|
] }
|
|
1738
1748
|
],
|
|
1739
1749
|
compute(e) {
|
|
1740
|
-
const t = _(e.solveFor, "FV"), n =
|
|
1750
|
+
const t = _(e.solveFor, "FV"), n = hr(_(e.compounding, "monthly")), a = g(C(e.ratePct)).div(100).div(n), r = C(e.n), s = _(e.timing) === "begin", u = g(C(e.pv)), m = g(C(e.pmt)), d = g(C(e.fv)), i = (f, y) => ce(f) ? g(y) : f.plus(1).pow(y).minus(1).div(f).times(s ? f.plus(1) : 1), c = (f, y) => f.plus(1).pow(y);
|
|
1741
1751
|
let l = "Future value", p = g(0), h = "PV·(1+i)^n + PMT·[((1+i)^n − 1)/i]·timing + FV = 0";
|
|
1742
1752
|
if (t === "FV")
|
|
1743
1753
|
p = u.times(c(a, r)).plus(m.times(i(a, r))).neg(), l = "Future value";
|
|
@@ -1774,7 +1784,7 @@ const Ua = {
|
|
|
1774
1784
|
}
|
|
1775
1785
|
return { primary: v(l, p.toDecimalPlaces(2).toString(), "accent"), formula: h, raw: { value: p.toNumber() } };
|
|
1776
1786
|
}
|
|
1777
|
-
},
|
|
1787
|
+
}, yr = {
|
|
1778
1788
|
id: "returns.cagr",
|
|
1779
1789
|
group: "returns",
|
|
1780
1790
|
title: "CAGR",
|
|
@@ -1786,7 +1796,7 @@ const Ua = {
|
|
|
1786
1796
|
{ key: "years", label: "Period", kind: "years", default: "10" }
|
|
1787
1797
|
],
|
|
1788
1798
|
compute(e, t) {
|
|
1789
|
-
const n = t.D(C(e.begin)), a = t.D(C(e.end)), r = C(e.years) || 1, s =
|
|
1799
|
+
const n = t.D(C(e.begin)), a = t.D(C(e.end)), r = C(e.years) || 1, s = st(n, a, r).times(100), u = a.minus(n).div(n).times(100);
|
|
1790
1800
|
return {
|
|
1791
1801
|
primary: v("CAGR", `${t.fmt.num(s, 2)}%`, "accent"),
|
|
1792
1802
|
secondary: [
|
|
@@ -1797,7 +1807,7 @@ const Ua = {
|
|
|
1797
1807
|
raw: { cagr: s.toNumber(), absolute: u.toNumber() }
|
|
1798
1808
|
};
|
|
1799
1809
|
}
|
|
1800
|
-
},
|
|
1810
|
+
}, br = {
|
|
1801
1811
|
id: "returns.absolute",
|
|
1802
1812
|
group: "returns",
|
|
1803
1813
|
title: "Absolute return",
|
|
@@ -1810,14 +1820,14 @@ const Ua = {
|
|
|
1810
1820
|
],
|
|
1811
1821
|
compute(e, t) {
|
|
1812
1822
|
const n = t.D(C(e.invested)), a = t.D(C(e.current)), r = a.minus(n).div(n).times(100), s = C(e.years), u = [v("Total gain", t.fmt.money(a.minus(n)), a.gte(n) ? "positive" : "negative")];
|
|
1813
|
-
return s > 0 && u.push(v("Annualised (CAGR)", `${t.fmt.num(
|
|
1823
|
+
return s > 0 && u.push(v("Annualised (CAGR)", `${t.fmt.num(st(n, a, s).times(100), 2)}%`)), {
|
|
1814
1824
|
primary: v("Absolute return", `${t.fmt.num(r, 2)}%`, "accent"),
|
|
1815
1825
|
secondary: u,
|
|
1816
1826
|
formula: "Absolute return = (Current − Invested) / Invested",
|
|
1817
1827
|
raw: { absolute: r.toNumber() }
|
|
1818
1828
|
};
|
|
1819
1829
|
}
|
|
1820
|
-
},
|
|
1830
|
+
}, gr = {
|
|
1821
1831
|
id: "returns.xirr",
|
|
1822
1832
|
group: "returns",
|
|
1823
1833
|
title: "XIRR",
|
|
@@ -1833,7 +1843,7 @@ const Ua = {
|
|
|
1833
1843
|
compute(e, t) {
|
|
1834
1844
|
const a = (e.flows ?? []).filter((u) => u.date && u.amount !== "").map((u) => ({ date: u.date, amount: u.amount }));
|
|
1835
1845
|
if (a.length < 2) return { primary: v("XIRR", "—"), warnings: ["Enter at least two dated cashflows."] };
|
|
1836
|
-
const r =
|
|
1846
|
+
const r = Mn(a);
|
|
1837
1847
|
if (!r) return { primary: v("XIRR", "—"), warnings: ["Need at least one negative and one positive cashflow."] };
|
|
1838
1848
|
const s = r.times(100);
|
|
1839
1849
|
return {
|
|
@@ -1842,7 +1852,7 @@ const Ua = {
|
|
|
1842
1852
|
raw: { xirr: s.toNumber() }
|
|
1843
1853
|
};
|
|
1844
1854
|
}
|
|
1845
|
-
},
|
|
1855
|
+
}, vr = {
|
|
1846
1856
|
id: "returns.irr",
|
|
1847
1857
|
group: "returns",
|
|
1848
1858
|
title: "IRR",
|
|
@@ -1850,12 +1860,12 @@ const Ua = {
|
|
|
1850
1860
|
keywords: ["irr", "internal rate of return"],
|
|
1851
1861
|
inputs: [{ key: "series", label: "Cashflows (comma-separated, period 0 first)", kind: "text", default: "-100000, 30000, 40000, 50000, 40000", help: "-100000, 30000, ..." }],
|
|
1852
1862
|
compute(e, t) {
|
|
1853
|
-
const n =
|
|
1863
|
+
const n = ut(_(e.series));
|
|
1854
1864
|
if (n.length < 2) return { primary: v("IRR", "—"), warnings: ["Enter at least two cashflows."] };
|
|
1855
|
-
const a =
|
|
1865
|
+
const a = Rn(n);
|
|
1856
1866
|
return a ? { primary: v("IRR", `${t.fmt.num(a.times(100), 2)}%`, "accent"), formula: "IRR: rate where NPV = 0", raw: { irr: a.times(100).toNumber() } } : { primary: v("IRR", "—"), warnings: ["No sign change — IRR is undefined for these flows."] };
|
|
1857
1867
|
}
|
|
1858
|
-
},
|
|
1868
|
+
}, kr = {
|
|
1859
1869
|
id: "returns.npv",
|
|
1860
1870
|
group: "returns",
|
|
1861
1871
|
title: "NPV",
|
|
@@ -1866,7 +1876,7 @@ const Ua = {
|
|
|
1866
1876
|
{ key: "series", label: "Cashflows (comma-separated, period 0 first)", kind: "text", default: "-100000, 30000, 40000, 50000, 40000" }
|
|
1867
1877
|
],
|
|
1868
1878
|
compute(e, t) {
|
|
1869
|
-
const n =
|
|
1879
|
+
const n = ut(_(e.series)), a = At(g(C(e.ratePct)).div(100), n);
|
|
1870
1880
|
return {
|
|
1871
1881
|
primary: v("NPV", t.fmt.money(a), a.gte(0) ? "positive" : "negative"),
|
|
1872
1882
|
secondary: [v(a.gte(0) ? "Value-creating" : "Value-destroying", a.gte(0) ? "NPV ≥ 0" : "NPV < 0")],
|
|
@@ -1874,7 +1884,7 @@ const Ua = {
|
|
|
1874
1884
|
raw: { npv: a.toNumber() }
|
|
1875
1885
|
};
|
|
1876
1886
|
}
|
|
1877
|
-
},
|
|
1887
|
+
}, wr = {
|
|
1878
1888
|
id: "returns.mirr",
|
|
1879
1889
|
group: "returns",
|
|
1880
1890
|
title: "MIRR",
|
|
@@ -1886,7 +1896,7 @@ const Ua = {
|
|
|
1886
1896
|
{ key: "reinvestPct", label: "Reinvestment rate", kind: "percent", default: "12" }
|
|
1887
1897
|
],
|
|
1888
1898
|
compute(e, t) {
|
|
1889
|
-
const n =
|
|
1899
|
+
const n = ut(_(e.series)), a = n.length - 1;
|
|
1890
1900
|
if (a < 1) return { primary: v("MIRR", "—"), warnings: ["Enter at least two cashflows."] };
|
|
1891
1901
|
const r = g(C(e.financePct)).div(100), s = g(C(e.reinvestPct)).div(100);
|
|
1892
1902
|
let u = g(0), m = g(0);
|
|
@@ -1896,7 +1906,7 @@ const Ua = {
|
|
|
1896
1906
|
const d = u.div(m.neg()).pow(g(1).div(a)).minus(1).times(100);
|
|
1897
1907
|
return { primary: v("MIRR", `${t.fmt.num(d, 2)}%`, "accent"), formula: "MIRR = (FV(inflows@reinvest) / −PV(outflows@finance))^(1/n) − 1", raw: { mirr: d.toNumber() } };
|
|
1898
1908
|
}
|
|
1899
|
-
},
|
|
1909
|
+
}, Nr = {
|
|
1900
1910
|
id: "returns.payback",
|
|
1901
1911
|
group: "returns",
|
|
1902
1912
|
title: "Payback period",
|
|
@@ -1908,7 +1918,7 @@ const Ua = {
|
|
|
1908
1918
|
{ key: "discountPct", label: "Discount rate (for discounted payback)", kind: "percent", default: "0", optional: !0, advanced: !0 }
|
|
1909
1919
|
],
|
|
1910
1920
|
compute(e, t) {
|
|
1911
|
-
const n = t.D(C(e.investment)), a =
|
|
1921
|
+
const n = t.D(C(e.investment)), a = ut(_(e.series)), r = g(C(e.discountPct)).div(100), s = r.gt(0);
|
|
1912
1922
|
let u = g(0), m = 0, d = null;
|
|
1913
1923
|
for (let i = 0; i < a.length; i++) {
|
|
1914
1924
|
const c = s ? g(a[i]).div(r.plus(1).pow(i + 1)) : g(a[i]), l = u;
|
|
@@ -1925,7 +1935,7 @@ const Ua = {
|
|
|
1925
1935
|
raw: { payback: d }
|
|
1926
1936
|
};
|
|
1927
1937
|
}
|
|
1928
|
-
},
|
|
1938
|
+
}, xr = {
|
|
1929
1939
|
id: "returns.realReturn",
|
|
1930
1940
|
group: "returns",
|
|
1931
1941
|
title: "Real (inflation-adjusted) return",
|
|
@@ -1944,7 +1954,7 @@ const Ua = {
|
|
|
1944
1954
|
raw: { real: r.toNumber() }
|
|
1945
1955
|
};
|
|
1946
1956
|
}
|
|
1947
|
-
},
|
|
1957
|
+
}, Sr = {
|
|
1948
1958
|
id: "returns.rule72",
|
|
1949
1959
|
group: "returns",
|
|
1950
1960
|
title: "Rule of 72",
|
|
@@ -1965,9 +1975,7 @@ const Ua = {
|
|
|
1965
1975
|
raw: { approx: a.toNumber(), exact: r.toNumber() }
|
|
1966
1976
|
};
|
|
1967
1977
|
}
|
|
1968
|
-
},
|
|
1969
|
-
pr,
|
|
1970
|
-
hr,
|
|
1978
|
+
}, Cr = [
|
|
1971
1979
|
fr,
|
|
1972
1980
|
yr,
|
|
1973
1981
|
br,
|
|
@@ -1975,7 +1983,9 @@ const Ua = {
|
|
|
1975
1983
|
vr,
|
|
1976
1984
|
kr,
|
|
1977
1985
|
wr,
|
|
1978
|
-
Nr
|
|
1986
|
+
Nr,
|
|
1987
|
+
xr,
|
|
1988
|
+
Sr
|
|
1979
1989
|
], Ne = "Estimate for planning only — not tax advice. Verify against current law and your own situation.";
|
|
1980
1990
|
function Ut(e, t, n) {
|
|
1981
1991
|
let a = g(0), r = 0;
|
|
@@ -1993,7 +2003,7 @@ function Ut(e, t, n) {
|
|
|
1993
2003
|
}
|
|
1994
2004
|
return { tax: a, rows: s };
|
|
1995
2005
|
}
|
|
1996
|
-
const
|
|
2006
|
+
const Pr = (e, t) => Ut(e, t, Tr).tax, Tr = { money: (e) => String(e) }, jt = (e, t) => e.gt(t) ? g(t) : e, dt = (e, t) => v(e, t, "positive"), Fr = {
|
|
1997
2007
|
id: "tax.gst",
|
|
1998
2008
|
group: "tax",
|
|
1999
2009
|
title: "GST Calculator",
|
|
@@ -2074,7 +2084,7 @@ const Sr = (e, t) => Ut(e, t, Cr).tax, Cr = { money: (e) => String(e) }, jt = (e
|
|
|
2074
2084
|
}
|
|
2075
2085
|
};
|
|
2076
2086
|
}
|
|
2077
|
-
},
|
|
2087
|
+
}, Ir = {
|
|
2078
2088
|
id: "tax.tds",
|
|
2079
2089
|
group: "tax",
|
|
2080
2090
|
title: "TDS on Interest",
|
|
@@ -2108,7 +2118,7 @@ const Sr = (e, t) => Ut(e, t, Cr).tax, Cr = { money: (e) => String(e) }, jt = (e
|
|
|
2108
2118
|
), {
|
|
2109
2119
|
primary: v("TDS deducted", n.money(p), p.gt(0) ? "negative" : "positive"),
|
|
2110
2120
|
secondary: [
|
|
2111
|
-
|
|
2121
|
+
dt("Net interest received", n.money(h)),
|
|
2112
2122
|
v("Effective TDS rate", n.pct(f), "accent"),
|
|
2113
2123
|
v("Applicable threshold", n.money(d), "default")
|
|
2114
2124
|
],
|
|
@@ -2121,7 +2131,7 @@ const Sr = (e, t) => Ut(e, t, Cr).tax, Cr = { money: (e) => String(e) }, jt = (e
|
|
|
2121
2131
|
"<60": [{ to: 25e4, rate: 0 }, { to: 5e5, rate: 5 }, { to: 1e6, rate: 20 }, { to: 1 / 0, rate: 30 }],
|
|
2122
2132
|
"60-80": [{ to: 3e5, rate: 0 }, { to: 5e5, rate: 5 }, { to: 1e6, rate: 20 }, { to: 1 / 0, rate: 30 }],
|
|
2123
2133
|
"80+": [{ to: 5e5, rate: 0 }, { to: 1e6, rate: 20 }, { to: 1 / 0, rate: 30 }]
|
|
2124
|
-
},
|
|
2134
|
+
}, Rr = [
|
|
2125
2135
|
{ to: 3e5, rate: 0 },
|
|
2126
2136
|
{ to: 7e5, rate: 5 },
|
|
2127
2137
|
{ to: 1e6, rate: 10 },
|
|
@@ -2129,7 +2139,7 @@ const Sr = (e, t) => Ut(e, t, Cr).tax, Cr = { money: (e) => String(e) }, jt = (e
|
|
|
2129
2139
|
{ to: 15e5, rate: 20 },
|
|
2130
2140
|
{ to: 1 / 0, rate: 30 }
|
|
2131
2141
|
];
|
|
2132
|
-
function
|
|
2142
|
+
function Er(e, t, n) {
|
|
2133
2143
|
const r = [
|
|
2134
2144
|
{ threshold: 5e7, rate: 25, prev: 20 },
|
|
2135
2145
|
{ threshold: 2e7, rate: 20, prev: 15 },
|
|
@@ -2141,10 +2151,10 @@ function Ir(e, t, n) {
|
|
|
2141
2151
|
return i.gt(0) ? s.minus(i) : s;
|
|
2142
2152
|
}
|
|
2143
2153
|
function Yt(e, t, n, a, r) {
|
|
2144
|
-
const { tax: s, rows: u } = Ut(e, t, r), m = e.gt(n) ? g(0) : s.lt(a) ? s : g(a), d = s.minus(m), i =
|
|
2154
|
+
const { tax: s, rows: u } = Ut(e, t, r), m = e.gt(n) ? g(0) : s.lt(a) ? s : g(a), d = s.minus(m), i = Er(e, d, (p) => Pr(g(p), t)), c = d.plus(i).times("0.04"), l = d.plus(i).plus(c);
|
|
2145
2155
|
return { taxable: e, base: s, rebate: m, surcharge: i, cess: c, total: l, rows: u };
|
|
2146
2156
|
}
|
|
2147
|
-
const
|
|
2157
|
+
const Mr = {
|
|
2148
2158
|
id: "tax.incomeIN",
|
|
2149
2159
|
group: "tax",
|
|
2150
2160
|
title: "Income Tax (Old vs New)",
|
|
@@ -2170,7 +2180,7 @@ const Rr = {
|
|
|
2170
2180
|
{ key: "homeLoanInterest", label: "Home loan interest (24b)", kind: "money", prefix: "currency", default: "0", help: "max ₹2L", optional: !0 }
|
|
2171
2181
|
],
|
|
2172
2182
|
compute(e, t) {
|
|
2173
|
-
const { fmt: n } = t, a = D(e.grossIncome, "1200000"), r = _(e.age, "<60"), s = jt(D(e.ded80C, "0"), 15e4), u = D(e.ded80D, "0"), m = D(e.hraExemption, "0"), d = jt(D(e.homeLoanInterest, "0"), 2e5), i = g(5e4).plus(s).plus(u).plus(m).plus(d), c = a.minus(i), l = c.gt(0) ? c : g(0), p = Yt(l, Vt[r] ?? Vt["<60"], 5e5, 12500, n), h = a.minus(75e3), f = h.gt(0) ? h : g(0), y = Yt(f,
|
|
2183
|
+
const { fmt: n } = t, a = D(e.grossIncome, "1200000"), r = _(e.age, "<60"), s = jt(D(e.ded80C, "0"), 15e4), u = D(e.ded80D, "0"), m = D(e.hraExemption, "0"), d = jt(D(e.homeLoanInterest, "0"), 2e5), i = g(5e4).plus(s).plus(u).plus(m).plus(d), c = a.minus(i), l = c.gt(0) ? c : g(0), p = Yt(l, Vt[r] ?? Vt["<60"], 5e5, 12500, n), h = a.minus(75e3), f = h.gt(0) ? h : g(0), y = Yt(f, Rr, 7e5, 25e3, n), w = !y.total.gt(p.total), k = w ? y : p, S = p.total.minus(y.total).abs();
|
|
2174
2184
|
return {
|
|
2175
2185
|
primary: v(
|
|
2176
2186
|
`${w ? "New" : "Old"} regime is cheaper`,
|
|
@@ -2206,7 +2216,7 @@ const Rr = {
|
|
|
2206
2216
|
}
|
|
2207
2217
|
};
|
|
2208
2218
|
}
|
|
2209
|
-
},
|
|
2219
|
+
}, $r = {
|
|
2210
2220
|
id: "tax.capitalGains",
|
|
2211
2221
|
group: "tax",
|
|
2212
2222
|
title: "Capital Gains Tax",
|
|
@@ -2255,7 +2265,7 @@ const Rr = {
|
|
|
2255
2265
|
raw: { gain: d.toFixed(2), tax: h ? null : l.toFixed(2), type: p, isLong: c ? 1 : 0 }
|
|
2256
2266
|
};
|
|
2257
2267
|
}
|
|
2258
|
-
},
|
|
2268
|
+
}, Ar = {
|
|
2259
2269
|
id: "tax.hra",
|
|
2260
2270
|
group: "tax",
|
|
2261
2271
|
title: "HRA Exemption",
|
|
@@ -2275,7 +2285,7 @@ const Rr = {
|
|
|
2275
2285
|
l.lt(h) && (h = l), p.lt(h) && (h = p);
|
|
2276
2286
|
const f = s.minus(h);
|
|
2277
2287
|
return {
|
|
2278
|
-
primary:
|
|
2288
|
+
primary: dt("HRA exempt", n.money(h)),
|
|
2279
2289
|
secondary: [
|
|
2280
2290
|
v("Taxable HRA", n.money(f), "negative"),
|
|
2281
2291
|
v("HRA received", n.money(s), "principal"),
|
|
@@ -2290,7 +2300,7 @@ const Rr = {
|
|
|
2290
2300
|
raw: { exempt: h.toFixed(2), taxable: f.toFixed(2), limitRent: l.toFixed(2), limitPct: p.toFixed(2) }
|
|
2291
2301
|
};
|
|
2292
2302
|
}
|
|
2293
|
-
},
|
|
2303
|
+
}, Dr = {
|
|
2294
2304
|
id: "tax.advanceTax",
|
|
2295
2305
|
group: "tax",
|
|
2296
2306
|
title: "Advance Tax Instalments",
|
|
@@ -2331,7 +2341,7 @@ const Rr = {
|
|
|
2331
2341
|
raw: { advanceTaxDue: u.toFixed(2), liability: a.toFixed(2), tdsPaid: r.toFixed(2) }
|
|
2332
2342
|
};
|
|
2333
2343
|
}
|
|
2334
|
-
},
|
|
2344
|
+
}, Lr = {
|
|
2335
2345
|
id: "tax.salesTaxUS",
|
|
2336
2346
|
group: "tax",
|
|
2337
2347
|
title: "Sales Tax",
|
|
@@ -2389,7 +2399,7 @@ const Rr = {
|
|
|
2389
2399
|
{ to: 609350, rate: 35 },
|
|
2390
2400
|
{ to: 1 / 0, rate: 37 }
|
|
2391
2401
|
]
|
|
2392
|
-
},
|
|
2402
|
+
}, Ur = { single: 14600, marriedJoint: 29200, headOfHousehold: 21900 }, Or = {
|
|
2393
2403
|
id: "tax.incomeUS",
|
|
2394
2404
|
group: "tax",
|
|
2395
2405
|
title: "Federal Income Tax",
|
|
@@ -2429,14 +2439,14 @@ const Rr = {
|
|
|
2429
2439
|
}
|
|
2430
2440
|
],
|
|
2431
2441
|
compute(e, t) {
|
|
2432
|
-
const { fmt: n } = t, a = D(e.grossIncome, "60000"), r = _(e.filingStatus, "single"), s = Kt[r] ?? Kt.single, m = _(e.deductionMode, "standard") === "itemized" ? D(e.itemizedAmount, "0") : g(
|
|
2442
|
+
const { fmt: n } = t, a = D(e.grossIncome, "60000"), r = _(e.filingStatus, "single"), s = Kt[r] ?? Kt.single, m = _(e.deductionMode, "standard") === "itemized" ? D(e.itemizedAmount, "0") : g(Ur[r] ?? 14600), d = a.minus(m), i = d.gt(0) ? d : g(0), { tax: c, rows: l } = Ut(i, s, n), p = a.gt(0) ? c.div(a).times(100) : g(0), h = s.find((w) => i.lte(w.to)) ?? s[s.length - 1], f = i.gt(0) ? h.rate : 0, y = a.minus(c);
|
|
2433
2443
|
return {
|
|
2434
2444
|
primary: v("Federal income tax", n.money(c), "negative"),
|
|
2435
2445
|
secondary: [
|
|
2436
2446
|
v("Taxable income", n.money(i), "principal", `after ${n.money(m)} deduction`),
|
|
2437
2447
|
v("Effective rate", n.pct(p), "accent"),
|
|
2438
2448
|
v("Marginal rate", `${f}%`, "default"),
|
|
2439
|
-
|
|
2449
|
+
dt("After-tax income", n.money(y))
|
|
2440
2450
|
],
|
|
2441
2451
|
schedule: {
|
|
2442
2452
|
title: "Bracket breakdown",
|
|
@@ -2458,7 +2468,7 @@ const Rr = {
|
|
|
2458
2468
|
}
|
|
2459
2469
|
};
|
|
2460
2470
|
}
|
|
2461
|
-
},
|
|
2471
|
+
}, Br = {
|
|
2462
2472
|
id: "tax.mortgageDeductionUS",
|
|
2463
2473
|
group: "tax",
|
|
2464
2474
|
title: "Mortgage Interest Deduction",
|
|
@@ -2476,7 +2486,7 @@ const Rr = {
|
|
|
2476
2486
|
"Acquisition-debt limit is $750,000 ($375,000 if married filing separately) for loans after 15 Dec 2017. " + Ne
|
|
2477
2487
|
];
|
|
2478
2488
|
return s.gt(u) && i.unshift(`Loan balance exceeds $750k: only ${n.pct(g(u).div(s).times(100))} of the interest is deductible.`), {
|
|
2479
|
-
primary:
|
|
2489
|
+
primary: dt("Estimated tax savings", n.money(d)),
|
|
2480
2490
|
secondary: [
|
|
2481
2491
|
v("Deductible interest", n.money(m), "principal"),
|
|
2482
2492
|
v("Marginal tax rate", n.pct(g(C(e.marginalTaxRatePct, 24))), "accent")
|
|
@@ -2486,16 +2496,16 @@ const Rr = {
|
|
|
2486
2496
|
raw: { savings: d.toFixed(2), deductibleInterest: m.toFixed(2) }
|
|
2487
2497
|
};
|
|
2488
2498
|
}
|
|
2489
|
-
},
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
Rr,
|
|
2493
|
-
Er,
|
|
2499
|
+
}, _r = [
|
|
2500
|
+
Fr,
|
|
2501
|
+
Ir,
|
|
2494
2502
|
Mr,
|
|
2495
2503
|
$r,
|
|
2496
2504
|
Ar,
|
|
2505
|
+
Dr,
|
|
2497
2506
|
Lr,
|
|
2498
|
-
|
|
2507
|
+
Or,
|
|
2508
|
+
Br
|
|
2499
2509
|
], $e = {
|
|
2500
2510
|
length: { m: 1, km: 1e3, cm: 0.01, mm: 1e-3, mi: 1609.344, yd: 0.9144, ft: 0.3048, in: 0.0254 },
|
|
2501
2511
|
area: { sqm: 1, sqft: 0.092903, sqyd: 0.836127, acre: 4046.8564224, hectare: 1e4, bigha: 1337.8, gunta: 101.17, cent: 40.4686 },
|
|
@@ -2535,10 +2545,10 @@ const Rr = {
|
|
|
2535
2545
|
C: "Celsius (°C)",
|
|
2536
2546
|
F: "Fahrenheit (°F)",
|
|
2537
2547
|
K: "Kelvin (K)"
|
|
2538
|
-
},
|
|
2548
|
+
}, Hr = ["C", "F", "K"], Wt = (e) => e.map((t) => ({ value: t, label: Pt[t] ?? t })), Ae = (e, t, n, a) => [
|
|
2539
2549
|
{ key: `${e}From`, label: "From", kind: "select", default: n, options: Wt(t), showIf: (r) => r.category === e },
|
|
2540
2550
|
{ key: `${e}To`, label: "To", kind: "select", default: a, options: Wt(t), showIf: (r) => r.category === e }
|
|
2541
|
-
],
|
|
2551
|
+
], qr = {
|
|
2542
2552
|
id: "tools.units",
|
|
2543
2553
|
group: "tools",
|
|
2544
2554
|
title: "Unit Converter",
|
|
@@ -2563,7 +2573,7 @@ const Rr = {
|
|
|
2563
2573
|
...Ae("area", Object.keys($e.area), "acre", "sqm"),
|
|
2564
2574
|
...Ae("weight", Object.keys($e.weight), "kg", "lb"),
|
|
2565
2575
|
...Ae("volume", Object.keys($e.volume), "l", "gal_us"),
|
|
2566
|
-
...Ae("temperature",
|
|
2576
|
+
...Ae("temperature", Hr, "C", "F")
|
|
2567
2577
|
],
|
|
2568
2578
|
compute(e, t) {
|
|
2569
2579
|
const { D: n, fmt: a } = t, r = n(C(e.value, 0)), s = _(e.category, "length"), u = _(e[`${s}From`], ""), m = _(e[`${s}To`], ""), d = [];
|
|
@@ -2582,14 +2592,14 @@ const Rr = {
|
|
|
2582
2592
|
raw: { result: i.toFixed(6), from: u, to: m, category: s }
|
|
2583
2593
|
};
|
|
2584
2594
|
}
|
|
2585
|
-
},
|
|
2595
|
+
}, Ve = 864e5, ft = (e) => {
|
|
2586
2596
|
if (!e) {
|
|
2587
2597
|
const r = /* @__PURE__ */ new Date();
|
|
2588
2598
|
return new Date(Date.UTC(r.getUTCFullYear(), r.getUTCMonth(), r.getUTCDate()));
|
|
2589
2599
|
}
|
|
2590
2600
|
const [t, n, a] = e.split("-").map(Number);
|
|
2591
2601
|
return new Date(Date.UTC(t, (n || 1) - 1, a || 1));
|
|
2592
|
-
}, yt = (e, t) => new Date(Date.UTC(e, t, 0)).getUTCDate(),
|
|
2602
|
+
}, yt = (e, t) => new Date(Date.UTC(e, t, 0)).getUTCDate(), Ye = (e) => e.toISOString().slice(0, 10), Gr = {
|
|
2593
2603
|
id: "tools.dateCalc",
|
|
2594
2604
|
group: "tools",
|
|
2595
2605
|
title: "Date Calculator",
|
|
@@ -2639,7 +2649,7 @@ const Rr = {
|
|
|
2639
2649
|
const l = ft(_(e.startDate, "")), p = Math.round(C(e.count, 0)), h = _(e.unit, "days"), f = _(e.direction, "add") === "subtract" ? -1 : 1, y = f * p;
|
|
2640
2650
|
let w;
|
|
2641
2651
|
if (h === "days" || h === "weeks")
|
|
2642
|
-
w = new Date(l.getTime() + y * (h === "weeks" ? 7 : 1) *
|
|
2652
|
+
w = new Date(l.getTime() + y * (h === "weeks" ? 7 : 1) * Ve);
|
|
2643
2653
|
else if (h === "months") {
|
|
2644
2654
|
const S = l.getUTCMonth() + y, F = l.getUTCFullYear() + Math.floor(S / 12), N = (S % 12 + 12) % 12, P = Math.min(l.getUTCDate(), yt(F, N + 1));
|
|
2645
2655
|
w = new Date(Date.UTC(F, N, P));
|
|
@@ -2649,18 +2659,18 @@ const Rr = {
|
|
|
2649
2659
|
}
|
|
2650
2660
|
const k = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"][w.getUTCDay()];
|
|
2651
2661
|
return {
|
|
2652
|
-
primary: v("Result date",
|
|
2653
|
-
secondary: [v("From",
|
|
2654
|
-
raw: { resultDate:
|
|
2662
|
+
primary: v("Result date", Ye(w), "accent", k),
|
|
2663
|
+
secondary: [v("From", Ye(l)), v("Shift", `${f < 0 ? "−" : "+"}${p} ${h}`)],
|
|
2664
|
+
raw: { resultDate: Ye(w), weekday: k, from: Ye(l) }
|
|
2655
2665
|
};
|
|
2656
2666
|
}
|
|
2657
2667
|
let n = ft(_(e.startDate, "")), a = ft(_(e.endDate, "")), r = !1;
|
|
2658
2668
|
a.getTime() < n.getTime() && ([n, a] = [a, n], r = !0);
|
|
2659
2669
|
let s = a.getUTCFullYear() - n.getUTCFullYear(), u = a.getUTCMonth() - n.getUTCMonth(), m = a.getUTCDate() - n.getUTCDate();
|
|
2660
2670
|
m < 0 && (u -= 1, m += yt(a.getUTCFullYear(), a.getUTCMonth())), u < 0 && (s -= 1, u += 12);
|
|
2661
|
-
const d = Math.round((a.getTime() - n.getTime()) /
|
|
2671
|
+
const d = Math.round((a.getTime() - n.getTime()) / Ve);
|
|
2662
2672
|
let i = 0;
|
|
2663
|
-
for (let l = n.getTime() +
|
|
2673
|
+
for (let l = n.getTime() + Ve; l <= a.getTime(); l += Ve) {
|
|
2664
2674
|
const p = new Date(l).getUTCDay();
|
|
2665
2675
|
p !== 0 && p !== 6 && i++;
|
|
2666
2676
|
}
|
|
@@ -2676,10 +2686,10 @@ const Rr = {
|
|
|
2676
2686
|
raw: { years: s, months: u, days: m, totalDays: d, weeks: Number((d / 7).toFixed(2)), businessDays: i }
|
|
2677
2687
|
};
|
|
2678
2688
|
}
|
|
2679
|
-
}, Tt = ["Zero", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen"],
|
|
2689
|
+
}, Tt = ["Zero", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen"], jr = ["", "", "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety"], at = (e) => e < 20 ? Tt[e] : jr[Math.floor(e / 10)] + (e % 10 ? " " + Tt[e % 10] : ""), Ft = (e) => {
|
|
2680
2690
|
const t = Math.floor(e / 100), n = e % 100, a = [];
|
|
2681
|
-
return t && a.push(Tt[t] + " Hundred"), n && a.push(
|
|
2682
|
-
},
|
|
2691
|
+
return t && a.push(Tt[t] + " Hundred"), n && a.push(at(n)), a.join(" ");
|
|
2692
|
+
}, Ln = (e) => {
|
|
2683
2693
|
if (e === 0) return "Zero";
|
|
2684
2694
|
const t = ["", " Thousand", " Million", " Billion", " Trillion"], n = [];
|
|
2685
2695
|
let a = 0;
|
|
@@ -2688,11 +2698,11 @@ const Rr = {
|
|
|
2688
2698
|
r && n.unshift(Ft(r) + t[a]), e = Math.floor(e / 1e3), a++;
|
|
2689
2699
|
}
|
|
2690
2700
|
return n.length ? n.join(" ") : "Zero";
|
|
2691
|
-
},
|
|
2701
|
+
}, Vr = (e) => {
|
|
2692
2702
|
if (e === 0) return "Zero";
|
|
2693
2703
|
const t = Math.floor(e / 1e7), n = Math.floor(e / 1e5) % 100, a = Math.floor(e / 1e3) % 100, r = e % 1e3, s = [];
|
|
2694
|
-
return t && s.push((t <= 999 ? Ft(t) :
|
|
2695
|
-
},
|
|
2704
|
+
return t && s.push((t <= 999 ? Ft(t) : Ln(t)) + " Crore"), n && s.push(at(n) + " Lakh"), a && s.push(at(a) + " Thousand"), r && s.push(Ft(r)), s.join(" ");
|
|
2705
|
+
}, Yr = {
|
|
2696
2706
|
id: "tools.numToWords",
|
|
2697
2707
|
group: "tools",
|
|
2698
2708
|
title: "Number to Words",
|
|
@@ -2714,15 +2724,15 @@ const Rr = {
|
|
|
2714
2724
|
],
|
|
2715
2725
|
compute(e, t) {
|
|
2716
2726
|
const { D: n, fmt: a } = t, r = _(e.scale, "indian"), s = ye(e.cheque, !1), u = n(_(e.amount, "0").replace(/[, ]/g, "") || "0"), m = u.isNegative(), d = u.abs(), i = d.floor(), c = Number(d.minus(i).times(100).toDecimalPlaces(0).toString()), l = Number(i.toString()), p = t.settings.currency.code, h = p === "INR" ? "Rupees" : p === "USD" ? "Dollars" : p, f = p === "INR" ? "Paise" : "Cents";
|
|
2717
|
-
let y = r === "western" ?
|
|
2718
|
-
return c > 0 && (y += ` and ${
|
|
2727
|
+
let y = r === "western" ? Ln(l) : Vr(l);
|
|
2728
|
+
return c > 0 && (y += ` and ${at(c)} ${f}`), s && (y = `${h} ${y} Only`), m && (y = `Minus ${y}`), {
|
|
2719
2729
|
primary: v("In words", y, "accent"),
|
|
2720
2730
|
secondary: [v("In figures", a.num(u, c > 0 ? 2 : 0))],
|
|
2721
2731
|
notes: ['Words are Title Case with the chosen number scale; the cheque format adds the currency name and "Only".'],
|
|
2722
2732
|
raw: { words: y, integer: l, fraction: c }
|
|
2723
2733
|
};
|
|
2724
2734
|
}
|
|
2725
|
-
},
|
|
2735
|
+
}, Kr = [qr, Gr, Yr], Wr = [
|
|
2726
2736
|
{
|
|
2727
2737
|
id: "tools.scientific",
|
|
2728
2738
|
group: "tools",
|
|
@@ -2733,7 +2743,7 @@ const Rr = {
|
|
|
2733
2743
|
compute: () => ({ primary: { label: "Scientific calculator", value: "" } }),
|
|
2734
2744
|
custom: "scientific"
|
|
2735
2745
|
}
|
|
2736
|
-
],
|
|
2746
|
+
], zr = {
|
|
2737
2747
|
id: "loan.emi",
|
|
2738
2748
|
group: "loans",
|
|
2739
2749
|
title: "EMI / Loan",
|
|
@@ -2742,7 +2752,7 @@ const Rr = {
|
|
|
2742
2752
|
inputs: [],
|
|
2743
2753
|
compute: () => ({ primary: { label: "", value: "" } }),
|
|
2744
2754
|
custom: "loan.emi"
|
|
2745
|
-
},
|
|
2755
|
+
}, Jr = {
|
|
2746
2756
|
id: "tools.currency",
|
|
2747
2757
|
group: "tools",
|
|
2748
2758
|
title: "Currency converter",
|
|
@@ -2751,49 +2761,49 @@ const Rr = {
|
|
|
2751
2761
|
inputs: [],
|
|
2752
2762
|
compute: () => ({ primary: { label: "", value: "" } }),
|
|
2753
2763
|
custom: "currency"
|
|
2754
|
-
},
|
|
2755
|
-
|
|
2756
|
-
|
|
2757
|
-
...
|
|
2758
|
-
...
|
|
2759
|
-
...
|
|
2760
|
-
...
|
|
2761
|
-
...
|
|
2762
|
-
...
|
|
2763
|
-
...
|
|
2764
|
-
...
|
|
2764
|
+
}, Zr = [
|
|
2765
|
+
zr,
|
|
2766
|
+
Jr,
|
|
2767
|
+
...Ka,
|
|
2768
|
+
...nr,
|
|
2769
|
+
...cr,
|
|
2770
|
+
...pr,
|
|
2771
|
+
...Cr,
|
|
2772
|
+
..._r,
|
|
2773
|
+
...Kr,
|
|
2774
|
+
...Wr
|
|
2765
2775
|
], It = [];
|
|
2766
|
-
function
|
|
2776
|
+
function bs(e) {
|
|
2767
2777
|
It.some((t) => t.id === e.id) || It.push(e);
|
|
2768
2778
|
}
|
|
2769
|
-
function
|
|
2770
|
-
return [...
|
|
2779
|
+
function Un() {
|
|
2780
|
+
return [...Zr, ...It];
|
|
2771
2781
|
}
|
|
2772
|
-
function
|
|
2773
|
-
return
|
|
2782
|
+
function Xr(e) {
|
|
2783
|
+
return Un().filter((t) => !t.regions || t.regions.includes(e));
|
|
2774
2784
|
}
|
|
2775
2785
|
function Rt(e) {
|
|
2776
|
-
return
|
|
2786
|
+
return Un().find((t) => t.id === e);
|
|
2777
2787
|
}
|
|
2778
|
-
const
|
|
2788
|
+
const Qr = [
|
|
2779
2789
|
{ id: "loans", label: "Loans" },
|
|
2780
2790
|
{ id: "invest", label: "Invest" },
|
|
2781
2791
|
{ id: "returns", label: "Returns" },
|
|
2782
2792
|
{ id: "tax", label: "Tax" },
|
|
2783
2793
|
{ id: "tools", label: "Tools" }
|
|
2784
2794
|
];
|
|
2785
|
-
function
|
|
2795
|
+
function eo(e, t) {
|
|
2786
2796
|
var n;
|
|
2787
2797
|
return ((n = e.labelByRegion) == null ? void 0 : n[t]) ?? e.label;
|
|
2788
2798
|
}
|
|
2789
|
-
function
|
|
2799
|
+
function to({
|
|
2790
2800
|
f: e,
|
|
2791
2801
|
value: t,
|
|
2792
2802
|
onChange: n,
|
|
2793
2803
|
values: a
|
|
2794
2804
|
}) {
|
|
2795
2805
|
var i, c;
|
|
2796
|
-
const { settings: r } = ue(), s = r.region, u =
|
|
2806
|
+
const { settings: r } = ue(), s = r.region, u = eo(e, s), m = r.currency.symbol, d = t == null ? "" : String(t);
|
|
2797
2807
|
switch (e.kind) {
|
|
2798
2808
|
case "money":
|
|
2799
2809
|
case "number":
|
|
@@ -2831,7 +2841,7 @@ function Qr({
|
|
|
2831
2841
|
] })
|
|
2832
2842
|
] });
|
|
2833
2843
|
case "tenure":
|
|
2834
|
-
return /* @__PURE__ */ o(
|
|
2844
|
+
return /* @__PURE__ */ o(no, { f: e, label: u, months: Number(t) || 0, onChange: n });
|
|
2835
2845
|
case "select":
|
|
2836
2846
|
return /* @__PURE__ */ b("label", { className: "field", children: [
|
|
2837
2847
|
/* @__PURE__ */ o("span", { className: "lbl", children: u }),
|
|
@@ -2869,12 +2879,12 @@ function Qr({
|
|
|
2869
2879
|
/* @__PURE__ */ o("div", { className: "input-wrap", children: /* @__PURE__ */ o("input", { value: d, placeholder: e.help, onChange: (l) => n(l.target.value), "aria-label": u }) })
|
|
2870
2880
|
] });
|
|
2871
2881
|
case "cashflows":
|
|
2872
|
-
return /* @__PURE__ */ o(
|
|
2882
|
+
return /* @__PURE__ */ o(ao, { f: e, label: u, value: t ?? [], onChange: n });
|
|
2873
2883
|
default:
|
|
2874
2884
|
return null;
|
|
2875
2885
|
}
|
|
2876
2886
|
}
|
|
2877
|
-
function
|
|
2887
|
+
function no({
|
|
2878
2888
|
f: e,
|
|
2879
2889
|
label: t,
|
|
2880
2890
|
months: n,
|
|
@@ -2914,7 +2924,7 @@ function eo({
|
|
|
2914
2924
|
e.suffix && /* @__PURE__ */ o("div", { className: "solved-note", children: e.suffix })
|
|
2915
2925
|
] });
|
|
2916
2926
|
}
|
|
2917
|
-
function
|
|
2927
|
+
function ao({
|
|
2918
2928
|
label: e,
|
|
2919
2929
|
value: t,
|
|
2920
2930
|
onChange: n
|
|
@@ -2937,7 +2947,7 @@ function to({
|
|
|
2937
2947
|
/* @__PURE__ */ o("button", { type: "button", className: "icon-btn", onClick: () => s([...a, { date: "", amount: "" }]), children: "+ Add cashflow" })
|
|
2938
2948
|
] });
|
|
2939
2949
|
}
|
|
2940
|
-
const
|
|
2950
|
+
const On = {
|
|
2941
2951
|
principal: "pr-txt",
|
|
2942
2952
|
interest: "in-txt",
|
|
2943
2953
|
accent: "accent-txt",
|
|
@@ -2945,11 +2955,11 @@ const Un = {
|
|
|
2945
2955
|
negative: "neg-txt",
|
|
2946
2956
|
default: ""
|
|
2947
2957
|
};
|
|
2948
|
-
function
|
|
2958
|
+
function ro({ view: e }) {
|
|
2949
2959
|
const { settings: t } = ue(), n = t.currency.symbol, a = e.primary.value, r = a.startsWith(n), s = r ? a.slice(n.length).trim() : a, u = /[A-Za-z]{3,}/.test(a);
|
|
2950
2960
|
return /* @__PURE__ */ b("div", { className: "result", "aria-live": "polite", children: [
|
|
2951
2961
|
/* @__PURE__ */ o("div", { className: "label", children: e.primary.label }),
|
|
2952
|
-
/* @__PURE__ */ b("div", { className: `value num ${u ? "value-text" : ""} ${
|
|
2962
|
+
/* @__PURE__ */ b("div", { className: `value num ${u ? "value-text" : ""} ${On[e.primary.tone ?? "default"]}`, children: [
|
|
2953
2963
|
r && /* @__PURE__ */ o("span", { className: "cur", children: n }),
|
|
2954
2964
|
s,
|
|
2955
2965
|
e.primaryPer && /* @__PURE__ */ b("span", { className: "per", children: [
|
|
@@ -2958,18 +2968,18 @@ function no({ view: e }) {
|
|
|
2958
2968
|
] })
|
|
2959
2969
|
] }),
|
|
2960
2970
|
e.primary.sub && /* @__PURE__ */ o("div", { className: "per", children: e.primary.sub }),
|
|
2961
|
-
e.split && e.split.length > 0 && /* @__PURE__ */ o(
|
|
2962
|
-
e.secondary && e.secondary.length > 0 && /* @__PURE__ */ o("div", { className: "secondary", children: e.secondary.map((m, d) => /* @__PURE__ */ o(
|
|
2971
|
+
e.split && e.split.length > 0 && /* @__PURE__ */ o(io, { split: e.split }),
|
|
2972
|
+
e.secondary && e.secondary.length > 0 && /* @__PURE__ */ o("div", { className: "secondary", children: e.secondary.map((m, d) => /* @__PURE__ */ o(oo, { m }, d)) })
|
|
2963
2973
|
] });
|
|
2964
2974
|
}
|
|
2965
|
-
function
|
|
2975
|
+
function oo({ m: e }) {
|
|
2966
2976
|
return /* @__PURE__ */ b("div", { className: "kv", children: [
|
|
2967
2977
|
/* @__PURE__ */ o("div", { className: "k", children: e.label }),
|
|
2968
|
-
/* @__PURE__ */ o("div", { className: `v num ${
|
|
2978
|
+
/* @__PURE__ */ o("div", { className: `v num ${On[e.tone ?? "default"]}`, children: e.value }),
|
|
2969
2979
|
e.sub && /* @__PURE__ */ o("div", { className: "k", children: e.sub })
|
|
2970
2980
|
] });
|
|
2971
2981
|
}
|
|
2972
|
-
function
|
|
2982
|
+
function io({ split: e }) {
|
|
2973
2983
|
const t = e.reduce((a, r) => a + Math.max(0, r.value), 0) || 1, n = e.map((a) => Math.round(Math.max(0, a.value) / t * 100));
|
|
2974
2984
|
return /* @__PURE__ */ b(re, { children: [
|
|
2975
2985
|
/* @__PURE__ */ o("div", { className: "splitbar", role: "img", "aria-label": e.map((a, r) => `${a.label} ${n[r]}%`).join(", "), children: e.map((a, r) => /* @__PURE__ */ o("div", { className: a.tone, style: { width: `${n[r]}%` } }, r)) }),
|
|
@@ -2982,7 +2992,7 @@ function ro({ split: e }) {
|
|
|
2982
2992
|
] }, r)) })
|
|
2983
2993
|
] });
|
|
2984
2994
|
}
|
|
2985
|
-
function
|
|
2995
|
+
function so({ schedule: e }) {
|
|
2986
2996
|
var u;
|
|
2987
2997
|
const [t, n] = M(/* @__PURE__ */ new Set([0])), a = (m) => {
|
|
2988
2998
|
var d;
|
|
@@ -3024,7 +3034,7 @@ const zt = {
|
|
|
3024
3034
|
interest: "var(--fc-interest)",
|
|
3025
3035
|
accent: "var(--fc-accent)"
|
|
3026
3036
|
};
|
|
3027
|
-
function
|
|
3037
|
+
function lo({ chart: e }) {
|
|
3028
3038
|
const m = Math.max(...e.series.map((h) => h.points.length), 1), d = Math.max(...e.series.flatMap((h) => h.points), 1), i = (h) => 8 + h / Math.max(m - 1, 1) * 704, c = (h) => 12 + (1 - h / d) * 226, l = (h) => h.map((f, y) => `${y === 0 ? "M" : "L"}${i(y).toFixed(1)},${c(f).toFixed(1)}`).join(" "), p = (h) => `M${i(0)},${c(0)} ${h.map((f, y) => `L${i(y).toFixed(1)},${c(f).toFixed(1)}`).join(" ")} L${i(h.length - 1)},${c(0)} Z`;
|
|
3029
3039
|
return /* @__PURE__ */ b("div", { className: "chart", children: [
|
|
3030
3040
|
/* @__PURE__ */ b("svg", { viewBox: "0 0 720 260", role: "img", "aria-label": "Projection chart", children: [
|
|
@@ -3040,7 +3050,7 @@ function io({ chart: e }) {
|
|
|
3040
3050
|
] }, f)) })
|
|
3041
3051
|
] });
|
|
3042
3052
|
}
|
|
3043
|
-
const
|
|
3053
|
+
const Bn = 1, co = [
|
|
3044
3054
|
{ id: "csv", label: "CSV (.csv)" },
|
|
3045
3055
|
{ id: "tsv", label: "TSV (.tsv)" },
|
|
3046
3056
|
{ id: "json", label: "JSON (.json)" },
|
|
@@ -3069,7 +3079,7 @@ function _e(e) {
|
|
|
3069
3079
|
for (const n of e.rows) t.push([n.label, ...n.cells]);
|
|
3070
3080
|
return { header: e.columns, rows: t };
|
|
3071
3081
|
}
|
|
3072
|
-
function
|
|
3082
|
+
function uo(e) {
|
|
3073
3083
|
var t;
|
|
3074
3084
|
return e ? e.groups ? e.groups.reduce((n, a) => n + a.rows.length, 0) : ((t = e.rows) == null ? void 0 : t.length) ?? 0 : 0;
|
|
3075
3085
|
}
|
|
@@ -3089,32 +3099,32 @@ function Se(e, t, n = "application/octet-stream") {
|
|
|
3089
3099
|
URL.revokeObjectURL(r), s.remove();
|
|
3090
3100
|
}, 0);
|
|
3091
3101
|
}
|
|
3092
|
-
function
|
|
3102
|
+
function mo(e, t) {
|
|
3093
3103
|
let n = e == null ? "" : String(e);
|
|
3094
3104
|
return /^[=+\-@\t\r]/.test(n) && (n = `'${n}`), (n.includes(t) || n.includes('"') || n.includes(`
|
|
3095
3105
|
`) || n.includes("\r")) && (n = `"${n.replace(/"/g, '""')}"`), n;
|
|
3096
3106
|
}
|
|
3097
|
-
function
|
|
3107
|
+
function po(e) {
|
|
3098
3108
|
var t;
|
|
3099
3109
|
return ((t = e == null ? void 0 : e.numberFormat) == null ? void 0 : t.grouping) === "european" ? ";" : ",";
|
|
3100
3110
|
}
|
|
3101
|
-
function
|
|
3111
|
+
function _n(e, t) {
|
|
3102
3112
|
const n = [["ArthaGanaka export"], ["Calculator", e.title]];
|
|
3103
3113
|
for (const a of Re(e)) n.push(a);
|
|
3104
3114
|
if (n.push([]), e.result.schedule) {
|
|
3105
3115
|
const a = _e(e.result.schedule);
|
|
3106
3116
|
n.push(a.header, ...a.rows);
|
|
3107
3117
|
}
|
|
3108
|
-
return n.map((a) => a.map((r) =>
|
|
3118
|
+
return n.map((a) => a.map((r) => mo(r, t)).join(t)).join(`\r
|
|
3109
3119
|
`);
|
|
3110
3120
|
}
|
|
3111
|
-
function
|
|
3112
|
-
return
|
|
3121
|
+
function ho(e) {
|
|
3122
|
+
return _n(e, po(e.settingsSnapshot));
|
|
3113
3123
|
}
|
|
3114
|
-
function
|
|
3115
|
-
return
|
|
3124
|
+
function fo(e) {
|
|
3125
|
+
return _n(e, " ");
|
|
3116
3126
|
}
|
|
3117
|
-
function
|
|
3127
|
+
function yo(e, t = Bn) {
|
|
3118
3128
|
return JSON.stringify(
|
|
3119
3129
|
{
|
|
3120
3130
|
schemaVersion: t,
|
|
@@ -3134,7 +3144,7 @@ function ho(e, t = On) {
|
|
|
3134
3144
|
2
|
|
3135
3145
|
);
|
|
3136
3146
|
}
|
|
3137
|
-
function
|
|
3147
|
+
function bo(e) {
|
|
3138
3148
|
const t = new TextEncoder().encode(e);
|
|
3139
3149
|
if (typeof btoa == "function") {
|
|
3140
3150
|
let n = "";
|
|
@@ -3143,41 +3153,41 @@ function fo(e) {
|
|
|
3143
3153
|
}
|
|
3144
3154
|
return globalThis.Buffer.from(t).toString("base64");
|
|
3145
3155
|
}
|
|
3146
|
-
const
|
|
3147
|
-
function
|
|
3148
|
-
const n =
|
|
3156
|
+
const go = (e) => bo(e).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
3157
|
+
function Hn(e, t) {
|
|
3158
|
+
const n = go(JSON.stringify({ id: e, values: t }));
|
|
3149
3159
|
return `#fincalc=${encodeURIComponent(e)}&s=${n}`;
|
|
3150
3160
|
}
|
|
3151
|
-
const
|
|
3161
|
+
const Ke = (e) => String(e ?? "").replace(/\|/g, "\\|").replace(/\n/g, " ");
|
|
3152
3162
|
function Jt(e) {
|
|
3153
3163
|
const t = [`# ${e.title}`, ""];
|
|
3154
3164
|
t.push("| Metric | Value |", "| --- | --- |");
|
|
3155
|
-
for (const [n, a] of Re(e)) t.push(`| ${
|
|
3165
|
+
for (const [n, a] of Re(e)) t.push(`| ${Ke(n)} | ${Ke(a)} |`);
|
|
3156
3166
|
if (e.result.schedule) {
|
|
3157
3167
|
const n = _e(e.result.schedule);
|
|
3158
|
-
t.push("", `## ${e.result.schedule.title ?? "Schedule"}`, ""), t.push(`| ${n.header.map(
|
|
3159
|
-
for (const a of n.rows) t.push(`| ${a.map(
|
|
3168
|
+
t.push("", `## ${e.result.schedule.title ?? "Schedule"}`, ""), t.push(`| ${n.header.map(Ke).join(" | ")} |`), t.push(`| ${n.header.map(() => "---").join(" | ")} |`);
|
|
3169
|
+
for (const a of n.rows) t.push(`| ${a.map(Ke).join(" | ")} |`);
|
|
3160
3170
|
}
|
|
3161
3171
|
return t.push("", `_Generated by ArthaGanaka · ${e.meta.computedAt}_`), t.join(`
|
|
3162
3172
|
`);
|
|
3163
3173
|
}
|
|
3164
3174
|
const Pe = (e) => String(e ?? "").replace(/[&<>"]/g, (t) => ({ "&": "&", "<": "<", ">": ">", '"': """ })[t]);
|
|
3165
|
-
function
|
|
3175
|
+
function vo(e) {
|
|
3166
3176
|
return `<table><tbody>${Re(e).map(([n, a]) => `<tr><th>${Pe(n)}</th><td>${Pe(a)}</td></tr>`).join("")}</tbody></table>`;
|
|
3167
3177
|
}
|
|
3168
|
-
function
|
|
3178
|
+
function ko(e) {
|
|
3169
3179
|
const t = _e(e), n = `<tr>${t.header.map((r) => `<th>${Pe(r)}</th>`).join("")}</tr>`, a = t.rows.map((r) => `<tr>${r.map((s) => `<td>${Pe(s)}</td>`).join("")}</tr>`).join("");
|
|
3170
3180
|
return `<table><thead>${n}</thead><tbody>${a}</tbody></table>`;
|
|
3171
3181
|
}
|
|
3172
|
-
function
|
|
3173
|
-
const t = e.result.schedule ? `<h2>${Pe(e.result.schedule.title ?? "Schedule")}</h2>${
|
|
3174
|
-
return `<h1>${Pe(e.title)}</h1>${
|
|
3182
|
+
function qn(e) {
|
|
3183
|
+
const t = e.result.schedule ? `<h2>${Pe(e.result.schedule.title ?? "Schedule")}</h2>${ko(e.result.schedule)}` : "";
|
|
3184
|
+
return `<h1>${Pe(e.title)}</h1>${vo(e)}${t}<p class="fc-print-foot">Generated by ArthaGanaka · ${Pe(e.meta.computedAt)}</p>`;
|
|
3175
3185
|
}
|
|
3176
|
-
const Zt = (e) => String(e ?? "").replace(/\\/g, "\\\\").replace(/[;,]/g, (t) => `\\${t}`).replace(/\n/g, "\\n"), Xt = (e) => `${e.getFullYear()}${String(e.getMonth() + 1).padStart(2, "0")}${String(e.getDate()).padStart(2, "0")}`,
|
|
3186
|
+
const Zt = (e) => String(e ?? "").replace(/\\/g, "\\\\").replace(/[;,]/g, (t) => `\\${t}`).replace(/\n/g, "\\n"), Xt = (e) => `${e.getFullYear()}${String(e.getMonth() + 1).padStart(2, "0")}${String(e.getDate()).padStart(2, "0")}`, wo = (e) => new Date(e || Date.now()).toISOString().replace(/[-:]/g, "").replace(/\.\d{3}Z$/, "Z"), No = (e, t) => {
|
|
3177
3187
|
const n = new Date(e);
|
|
3178
3188
|
return n.setMonth(n.getMonth() + t), n;
|
|
3179
3189
|
};
|
|
3180
|
-
function
|
|
3190
|
+
function xo(e) {
|
|
3181
3191
|
for (const t of Object.values(e))
|
|
3182
3192
|
if (typeof t == "string" && /^\d{4}-\d{2}-\d{2}/.test(t)) {
|
|
3183
3193
|
const n = new Date(t);
|
|
@@ -3185,12 +3195,12 @@ function wo(e) {
|
|
|
3185
3195
|
}
|
|
3186
3196
|
return /* @__PURE__ */ new Date();
|
|
3187
3197
|
}
|
|
3188
|
-
function
|
|
3189
|
-
const t =
|
|
3198
|
+
function So(e) {
|
|
3199
|
+
const t = uo(e.result.schedule);
|
|
3190
3200
|
if (!t) throw new Error("This calculator has no instalment schedule to put on a calendar.");
|
|
3191
|
-
const n =
|
|
3201
|
+
const n = xo(e.values), a = t <= 60, r = a ? t : Math.ceil(t / 12), s = wo(e.meta.computedAt), u = ["BEGIN:VCALENDAR", "VERSION:2.0", "PRODID:-//ArthaGanaka//Export//EN", "CALSCALE:GREGORIAN"];
|
|
3192
3202
|
for (let m = 0; m < r; m++) {
|
|
3193
|
-
const d =
|
|
3203
|
+
const d = No(n, a ? m + 1 : (m + 1) * 12), i = a ? `instalment ${m + 1}` : `year ${m + 1}`;
|
|
3194
3204
|
u.push(
|
|
3195
3205
|
"BEGIN:VEVENT",
|
|
3196
3206
|
`UID:${Zt(e.calculatorId)}-${m + 1}-${Xt(d)}@arthaganaka`,
|
|
@@ -3203,13 +3213,13 @@ function No(e) {
|
|
|
3203
3213
|
return u.push("END:VCALENDAR"), u.join(`\r
|
|
3204
3214
|
`);
|
|
3205
3215
|
}
|
|
3206
|
-
async function
|
|
3216
|
+
async function Gn(e) {
|
|
3207
3217
|
var n;
|
|
3208
3218
|
const t = typeof navigator < "u" ? navigator : void 0;
|
|
3209
3219
|
if ((n = t == null ? void 0 : t.clipboard) != null && n.writeText) return t.clipboard.writeText(e);
|
|
3210
3220
|
throw new Error("Clipboard is not available in this browser.");
|
|
3211
3221
|
}
|
|
3212
|
-
async function
|
|
3222
|
+
async function Co(e, t) {
|
|
3213
3223
|
var a;
|
|
3214
3224
|
const n = typeof navigator < "u" ? navigator : void 0;
|
|
3215
3225
|
if ((a = n == null ? void 0 : n.clipboard) != null && a.write && typeof ClipboardItem < "u" && typeof Blob < "u")
|
|
@@ -3223,18 +3233,18 @@ async function xo(e, t) {
|
|
|
3223
3233
|
return;
|
|
3224
3234
|
} catch {
|
|
3225
3235
|
}
|
|
3226
|
-
await
|
|
3236
|
+
await Gn(t);
|
|
3227
3237
|
}
|
|
3228
|
-
function
|
|
3238
|
+
function Po(e) {
|
|
3229
3239
|
if (!Ot() || typeof window > "u") throw new Error("Print is only available in the browser.");
|
|
3230
3240
|
const t = document.createElement("div");
|
|
3231
|
-
t.className = "fc-print-root", t.innerHTML =
|
|
3241
|
+
t.className = "fc-print-root", t.innerHTML = qn(e), document.body.appendChild(t), document.body.classList.add("fc-printing");
|
|
3232
3242
|
const n = () => {
|
|
3233
3243
|
document.body.classList.remove("fc-printing"), t.remove(), window.removeEventListener("afterprint", n);
|
|
3234
3244
|
};
|
|
3235
3245
|
window.addEventListener("afterprint", n), window.print(), setTimeout(n, 1500);
|
|
3236
3246
|
}
|
|
3237
|
-
function
|
|
3247
|
+
function To(e, t = 2) {
|
|
3238
3248
|
if (!Ot()) return Promise.reject(new Error("PNG export is only available in the browser."));
|
|
3239
3249
|
const n = Re(e), a = 620, r = 120 + n.length * 30 + 30, s = document.createElement("canvas");
|
|
3240
3250
|
s.width = a * t, s.height = r * t;
|
|
@@ -3251,11 +3261,13 @@ function Co(e, t = 2) {
|
|
|
3251
3261
|
(i, c) => s.toBlob((l) => l ? i(l) : c(new Error("Could not render PNG.")), "image/png")
|
|
3252
3262
|
);
|
|
3253
3263
|
}
|
|
3254
|
-
async function
|
|
3264
|
+
async function Fo(e) {
|
|
3255
3265
|
let t;
|
|
3256
3266
|
try {
|
|
3257
3267
|
t = await import(
|
|
3258
3268
|
/* @vite-ignore */
|
|
3269
|
+
/* webpackIgnore: true */
|
|
3270
|
+
/* turbopackIgnore: true */
|
|
3259
3271
|
"jspdf"
|
|
3260
3272
|
);
|
|
3261
3273
|
} catch {
|
|
@@ -3277,12 +3289,14 @@ async function Po(e) {
|
|
|
3277
3289
|
const s = ve(e, "pdf");
|
|
3278
3290
|
return a.save(s), { ok: !0, filename: s };
|
|
3279
3291
|
}
|
|
3280
|
-
async function
|
|
3292
|
+
async function Io(e) {
|
|
3281
3293
|
var i, c;
|
|
3282
3294
|
let t;
|
|
3283
3295
|
try {
|
|
3284
3296
|
t = await import(
|
|
3285
3297
|
/* @vite-ignore */
|
|
3298
|
+
/* webpackIgnore: true */
|
|
3299
|
+
/* turbopackIgnore: true */
|
|
3286
3300
|
"xlsx"
|
|
3287
3301
|
);
|
|
3288
3302
|
} catch {
|
|
@@ -3300,12 +3314,12 @@ async function To(e) {
|
|
|
3300
3314
|
const m = a(u, { type: "array", bookType: "xlsx" }), d = ve(e, "xlsx");
|
|
3301
3315
|
return Se(d, new Blob([m], { type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" })), { ok: !0, filename: d };
|
|
3302
3316
|
}
|
|
3303
|
-
function
|
|
3304
|
-
const t =
|
|
3317
|
+
function jn(e) {
|
|
3318
|
+
const t = Hn(e.calculatorId, e.values);
|
|
3305
3319
|
return (typeof location < "u" ? location.origin + location.pathname : "") + t;
|
|
3306
3320
|
}
|
|
3307
|
-
async function
|
|
3308
|
-
const t =
|
|
3321
|
+
async function Ro(e) {
|
|
3322
|
+
const t = Hn(e.calculatorId, e.values), n = jn(e);
|
|
3309
3323
|
if (typeof location < "u")
|
|
3310
3324
|
try {
|
|
3311
3325
|
location.hash = t;
|
|
@@ -3313,31 +3327,31 @@ async function Fo(e) {
|
|
|
3313
3327
|
}
|
|
3314
3328
|
const a = n.length > 2e3 ? `Link is long (${n.length} chars) — some apps may trim it. ` : "";
|
|
3315
3329
|
try {
|
|
3316
|
-
return await
|
|
3330
|
+
return await Gn(n), { ok: !0, data: n, note: `${a}Link copied to clipboard.` };
|
|
3317
3331
|
} catch {
|
|
3318
3332
|
return { ok: !0, data: n, note: `${a}Link is in the address bar — copy it from there.` };
|
|
3319
3333
|
}
|
|
3320
3334
|
}
|
|
3321
|
-
function
|
|
3335
|
+
function Eo(e) {
|
|
3322
3336
|
return {
|
|
3323
3337
|
ok: !0,
|
|
3324
|
-
data:
|
|
3338
|
+
data: jn(e),
|
|
3325
3339
|
note: "A QR image needs an optional QR library — share this link instead."
|
|
3326
3340
|
};
|
|
3327
3341
|
}
|
|
3328
|
-
function
|
|
3329
|
-
const t = e.schemaVersion ??
|
|
3342
|
+
function Mo(e = {}) {
|
|
3343
|
+
const t = e.schemaVersion ?? Bn, n = {
|
|
3330
3344
|
csv: (a) => {
|
|
3331
3345
|
const r = ve(a, "csv");
|
|
3332
|
-
return Se(r,
|
|
3346
|
+
return Se(r, ho(a), "text/csv;charset=utf-8"), { ok: !0, filename: r };
|
|
3333
3347
|
},
|
|
3334
3348
|
tsv: (a) => {
|
|
3335
3349
|
const r = ve(a, "tsv");
|
|
3336
|
-
return Se(r,
|
|
3350
|
+
return Se(r, fo(a), "text/tab-separated-values;charset=utf-8"), { ok: !0, filename: r };
|
|
3337
3351
|
},
|
|
3338
3352
|
json: (a) => {
|
|
3339
3353
|
const r = ve(a, "json");
|
|
3340
|
-
return Se(r,
|
|
3354
|
+
return Se(r, yo(a, t), "application/json"), { ok: !0, filename: r };
|
|
3341
3355
|
},
|
|
3342
3356
|
markdown: (a) => {
|
|
3343
3357
|
const r = ve(a, "md");
|
|
@@ -3345,18 +3359,18 @@ function Ro(e = {}) {
|
|
|
3345
3359
|
},
|
|
3346
3360
|
ics: (a) => {
|
|
3347
3361
|
const r = ve(a, "ics");
|
|
3348
|
-
return Se(r,
|
|
3362
|
+
return Se(r, So(a), "text/calendar;charset=utf-8"), { ok: !0, filename: r };
|
|
3349
3363
|
},
|
|
3350
|
-
clipboard: async (a) => (await
|
|
3351
|
-
print: (a) => (
|
|
3352
|
-
url: (a) =>
|
|
3353
|
-
qr: (a) =>
|
|
3364
|
+
clipboard: async (a) => (await Co(qn(a), Jt(a)), { ok: !0, note: "Copied table to clipboard." }),
|
|
3365
|
+
print: (a) => (Po(a), { ok: !0 }),
|
|
3366
|
+
url: (a) => Ro(a),
|
|
3367
|
+
qr: (a) => Eo(a),
|
|
3354
3368
|
png: async (a, r) => {
|
|
3355
3369
|
const s = ve(a, "png");
|
|
3356
|
-
return Se(s, await
|
|
3370
|
+
return Se(s, await To(a, r.scale ?? 2)), { ok: !0, filename: s };
|
|
3357
3371
|
},
|
|
3358
|
-
pdf: (a) =>
|
|
3359
|
-
xlsx: (a) =>
|
|
3372
|
+
pdf: (a) => Fo(a),
|
|
3373
|
+
xlsx: (a) => Io(a)
|
|
3360
3374
|
};
|
|
3361
3375
|
return {
|
|
3362
3376
|
formats: Object.keys(n),
|
|
@@ -3366,8 +3380,8 @@ function Ro(e = {}) {
|
|
|
3366
3380
|
}
|
|
3367
3381
|
};
|
|
3368
3382
|
}
|
|
3369
|
-
function
|
|
3370
|
-
const t = X(() =>
|
|
3383
|
+
function Vn({ payload: e }) {
|
|
3384
|
+
const t = X(() => Mo(), []), [n, a] = M(!1), [r, s] = M(null), u = de(null), m = de(null), d = de([]);
|
|
3371
3385
|
Q(() => {
|
|
3372
3386
|
if (!r) return;
|
|
3373
3387
|
const p = setTimeout(() => s(null), 4500);
|
|
@@ -3435,7 +3449,7 @@ function jn({ payload: e }) {
|
|
|
3435
3449
|
}
|
|
3436
3450
|
)
|
|
3437
3451
|
] }),
|
|
3438
|
-
n && /* @__PURE__ */ o("div", { ref: m, className: "menu-list", role: "menu", "aria-label": "Export as", children:
|
|
3452
|
+
n && /* @__PURE__ */ o("div", { ref: m, className: "menu-list", role: "menu", "aria-label": "Export as", children: co.map((p, h) => /* @__PURE__ */ o(
|
|
3439
3453
|
"button",
|
|
3440
3454
|
{
|
|
3441
3455
|
type: "button",
|
|
@@ -3452,10 +3466,10 @@ function jn({ payload: e }) {
|
|
|
3452
3466
|
r && /* @__PURE__ */ o("div", { className: `export-toast ${r.kind}`, role: "status", "aria-live": "polite", children: r.msg })
|
|
3453
3467
|
] });
|
|
3454
3468
|
}
|
|
3455
|
-
const Bt = "calcsuite:history",
|
|
3469
|
+
const Bt = "calcsuite:history", $o = 100, Ao = [];
|
|
3456
3470
|
let Ce = null;
|
|
3457
|
-
const
|
|
3458
|
-
function
|
|
3471
|
+
const Ze = /* @__PURE__ */ new Set();
|
|
3472
|
+
function Yn() {
|
|
3459
3473
|
if (Ce) return Ce;
|
|
3460
3474
|
try {
|
|
3461
3475
|
Ce = JSON.parse(localStorage.getItem(Bt) || "[]");
|
|
@@ -3464,38 +3478,38 @@ function Vn() {
|
|
|
3464
3478
|
}
|
|
3465
3479
|
return Ce;
|
|
3466
3480
|
}
|
|
3467
|
-
function
|
|
3481
|
+
function Kn(e) {
|
|
3468
3482
|
Ce = e;
|
|
3469
3483
|
try {
|
|
3470
3484
|
localStorage.setItem(Bt, JSON.stringify(e));
|
|
3471
3485
|
} catch {
|
|
3472
3486
|
}
|
|
3473
|
-
|
|
3487
|
+
Ze.forEach((t) => t());
|
|
3474
3488
|
}
|
|
3475
3489
|
let Qt = !1;
|
|
3476
|
-
function
|
|
3477
|
-
return
|
|
3478
|
-
t.key === Bt && (Ce = null,
|
|
3479
|
-
})), () =>
|
|
3490
|
+
function Do(e) {
|
|
3491
|
+
return Ze.add(e), !Qt && typeof window < "u" && (Qt = !0, window.addEventListener("storage", (t) => {
|
|
3492
|
+
t.key === Bt && (Ce = null, Ze.forEach((n) => n()));
|
|
3493
|
+
})), () => Ze.delete(e);
|
|
3480
3494
|
}
|
|
3481
|
-
function
|
|
3482
|
-
|
|
3495
|
+
function Wn(e) {
|
|
3496
|
+
Kn([{ ...e, at: Date.now() }, ...Yn()].slice(0, $o));
|
|
3483
3497
|
}
|
|
3484
|
-
function
|
|
3485
|
-
|
|
3498
|
+
function Lo() {
|
|
3499
|
+
Kn([]);
|
|
3486
3500
|
}
|
|
3487
|
-
function
|
|
3488
|
-
const e =
|
|
3501
|
+
function Uo() {
|
|
3502
|
+
const e = va(Do, Yn, () => Ao), t = ke((a) => Wn(a), []), n = ke(() => Lo(), []);
|
|
3489
3503
|
return { items: e, save: t, clear: n };
|
|
3490
3504
|
}
|
|
3491
|
-
function
|
|
3505
|
+
function zn({ item: e }) {
|
|
3492
3506
|
const [t, n] = M(!1), a = de();
|
|
3493
3507
|
return Q(() => () => clearTimeout(a.current), []), /* @__PURE__ */ o("button", { className: `icon-btn ${t ? "saved" : ""}`, onClick: () => {
|
|
3494
|
-
|
|
3508
|
+
Wn(e), n(!0), clearTimeout(a.current), a.current = setTimeout(() => n(!1), 1500);
|
|
3495
3509
|
}, "aria-live": "polite", children: t ? "Saved ✓" : "Save" });
|
|
3496
3510
|
}
|
|
3497
|
-
const
|
|
3498
|
-
function
|
|
3511
|
+
const Oo = { payment: "Payment", principal: "Amount", rate: "Rate", tenure: "Term" };
|
|
3512
|
+
function Jn() {
|
|
3499
3513
|
const { settings: e, fmt: t } = ue(), n = e.region, a = me[n], [r, s] = M("payment"), [u, m] = M(a.defaultBasis), [d, i] = M(n === "IN" ? "2500000" : "300000"), [c, l] = M(a.defaultRatePct), [p, h] = M(String(Math.floor(a.defaultTermMonths / 12))), [f, y] = M(String(a.defaultTermMonths % 12)), [w, k] = M(n === "IN" ? "21934" : "1896"), [S, F] = M("schedule"), N = u === "flat" ? ["payment", "principal"] : ["payment", "principal", "rate", "tenure"], P = (parseInt(p || "0", 10) || 0) * 12 + (parseInt(f || "0", 10) || 0), x = (R) => R.replace(/[, ]/g, "").trim(), { result: T, error: $ } = X(() => {
|
|
3500
3514
|
try {
|
|
3501
3515
|
return { result: Ie({
|
|
@@ -3571,7 +3585,7 @@ function zn() {
|
|
|
3571
3585
|
/* @__PURE__ */ b("section", { className: "card", children: [
|
|
3572
3586
|
/* @__PURE__ */ b("div", { className: "solve-row", children: [
|
|
3573
3587
|
/* @__PURE__ */ o("span", { className: "lbl", children: "Solve for" }),
|
|
3574
|
-
/* @__PURE__ */ o("div", { className: "seg", role: "group", "aria-label": "Solve for", children: N.map((R) => /* @__PURE__ */ o("button", { "aria-pressed": r === R, onClick: () => s(R), children:
|
|
3588
|
+
/* @__PURE__ */ o("div", { className: "seg", role: "group", "aria-label": "Solve for", children: N.map((R) => /* @__PURE__ */ o("button", { "aria-pressed": r === R, onClick: () => s(R), children: Oo[R] }, R)) })
|
|
3575
3589
|
] }),
|
|
3576
3590
|
/* @__PURE__ */ b("div", { className: "field", style: { marginBottom: "calc(var(--fc-space) * 2)" }, children: [
|
|
3577
3591
|
/* @__PURE__ */ o("span", { className: "lbl", children: "Interest basis" }),
|
|
@@ -3625,7 +3639,7 @@ function zn() {
|
|
|
3625
3639
|
/* @__PURE__ */ o("span", { className: "per", children: " /month" })
|
|
3626
3640
|
] })
|
|
3627
3641
|
] }),
|
|
3628
|
-
/* @__PURE__ */ o(
|
|
3642
|
+
/* @__PURE__ */ o(Bo, { result: T }),
|
|
3629
3643
|
/* @__PURE__ */ b("div", { className: "secondary", children: [
|
|
3630
3644
|
/* @__PURE__ */ b("div", { className: "kv", children: [
|
|
3631
3645
|
/* @__PURE__ */ o("div", { className: "k", children: "Principal" }),
|
|
@@ -3646,13 +3660,13 @@ function zn() {
|
|
|
3646
3660
|
] }),
|
|
3647
3661
|
/* @__PURE__ */ b("div", { className: "actions-row", children: [
|
|
3648
3662
|
/* @__PURE__ */ o(
|
|
3649
|
-
|
|
3663
|
+
zn,
|
|
3650
3664
|
{
|
|
3651
3665
|
item: { id: "loan.emi", title: `Loan — ${t.money(T.payment)}/mo`, primary: t.money(T.payment), values: A }
|
|
3652
3666
|
}
|
|
3653
3667
|
),
|
|
3654
3668
|
/* @__PURE__ */ o(
|
|
3655
|
-
|
|
3669
|
+
Vn,
|
|
3656
3670
|
{
|
|
3657
3671
|
payload: {
|
|
3658
3672
|
calculatorId: "loan.emi",
|
|
@@ -3684,8 +3698,8 @@ function zn() {
|
|
|
3684
3698
|
e.ui.showFormulas && /* @__PURE__ */ o("button", { role: "tab", "aria-selected": S === "formula", onClick: () => F("formula"), children: "Formula" })
|
|
3685
3699
|
] }),
|
|
3686
3700
|
/* @__PURE__ */ b("div", { className: "tab-anim", children: [
|
|
3687
|
-
S === "schedule" && /* @__PURE__ */ o(
|
|
3688
|
-
S === "chart" && /* @__PURE__ */ o(
|
|
3701
|
+
S === "schedule" && /* @__PURE__ */ o(_o, { result: T }),
|
|
3702
|
+
S === "chart" && /* @__PURE__ */ o(Ho, { result: T }),
|
|
3689
3703
|
S === "formula" && e.ui.showFormulas && /* @__PURE__ */ b("div", { className: "formula", children: [
|
|
3690
3704
|
/* @__PURE__ */ o("code", { children: T.formula }),
|
|
3691
3705
|
/* @__PURE__ */ b("div", { className: "assumptions", children: [
|
|
@@ -3730,7 +3744,7 @@ function bt({
|
|
|
3730
3744
|
] })
|
|
3731
3745
|
] });
|
|
3732
3746
|
}
|
|
3733
|
-
function
|
|
3747
|
+
function Bo({ result: e }) {
|
|
3734
3748
|
const { fmt: t } = ue(), n = Number(e.principal.toFixed(2)), a = Number(e.totalInterest.toFixed(2)), r = n + a || 1, s = Math.round(n / r * 100);
|
|
3735
3749
|
return /* @__PURE__ */ b(re, { children: [
|
|
3736
3750
|
/* @__PURE__ */ b("div", { className: "splitbar", role: "img", "aria-label": `Principal ${s}%, interest ${100 - s}%`, children: [
|
|
@@ -3755,7 +3769,7 @@ function Uo({ result: e }) {
|
|
|
3755
3769
|
] })
|
|
3756
3770
|
] });
|
|
3757
3771
|
}
|
|
3758
|
-
function
|
|
3772
|
+
function _o({ result: e }) {
|
|
3759
3773
|
const { fmt: t } = ue(), [n, a] = M("yearly"), [r, s] = M(/* @__PURE__ */ new Set([1])), u = (d) => s((i) => {
|
|
3760
3774
|
const c = new Set(i);
|
|
3761
3775
|
return c.has(d) ? c.delete(d) : c.add(d), c;
|
|
@@ -3817,7 +3831,7 @@ function Oo({ result: e }) {
|
|
|
3817
3831
|
] }) })
|
|
3818
3832
|
] });
|
|
3819
3833
|
}
|
|
3820
|
-
function
|
|
3834
|
+
function Ho({ result: e }) {
|
|
3821
3835
|
const { fmt: t } = ue(), n = e.chart.balance.map((k) => k.toNumber()), a = e.chart.cumulativeInterest.map((k) => k.toNumber()), r = n.length, s = 720, u = 260, m = 8, d = 8, i = 12, c = 22, l = e.principal.toNumber(), p = Math.max(l, a[a.length - 1] ?? 0) || 1, h = (k) => m + k / Math.max(r - 1, 1) * (s - m - d), f = (k) => i + (1 - k / p) * (u - i - c), y = (k) => k.map((S, F) => `${F === 0 ? "M" : "L"}${h(F).toFixed(1)},${f(S).toFixed(1)}`).join(" "), w = `M${h(0)},${f(l)} ${n.map((k, S) => `L${h(S).toFixed(1)},${f(k).toFixed(1)}`).join(" ")} L${h(r - 1)},${f(0)} L${h(0)},${f(0)} Z`;
|
|
3822
3836
|
return /* @__PURE__ */ b("div", { className: "chart", children: [
|
|
3823
3837
|
/* @__PURE__ */ b("svg", { viewBox: `0 0 ${s} ${u}`, role: "img", "aria-label": "Balance and cumulative interest over the term", children: [
|
|
@@ -3840,7 +3854,7 @@ function Bo({ result: e }) {
|
|
|
3840
3854
|
] })
|
|
3841
3855
|
] });
|
|
3842
3856
|
}
|
|
3843
|
-
const
|
|
3857
|
+
const qo = /* @__PURE__ */ new Set([
|
|
3844
3858
|
"sin",
|
|
3845
3859
|
"cos",
|
|
3846
3860
|
"tan",
|
|
@@ -3877,7 +3891,7 @@ const _o = /* @__PURE__ */ new Set([
|
|
|
3877
3891
|
"sq",
|
|
3878
3892
|
"cube",
|
|
3879
3893
|
"recip"
|
|
3880
|
-
]),
|
|
3894
|
+
]), Go = {
|
|
3881
3895
|
arcsin: "asin",
|
|
3882
3896
|
arccos: "acos",
|
|
3883
3897
|
arctan: "atan",
|
|
@@ -3885,14 +3899,14 @@ const _o = /* @__PURE__ */ new Set([
|
|
|
3885
3899
|
log10: "log",
|
|
3886
3900
|
ncr: "ncr",
|
|
3887
3901
|
npr: "npr"
|
|
3888
|
-
},
|
|
3889
|
-
` || e === "\r", fe = (e) => e >= "0" && e <= "9", en = (e) => e >= "a" && e <= "z" || e >= "A" && e <= "Z",
|
|
3890
|
-
function
|
|
3891
|
-
return e === "HEX" ?
|
|
3892
|
-
}
|
|
3893
|
-
function
|
|
3894
|
-
const t = e.toLowerCase(), n =
|
|
3895
|
-
if (
|
|
3902
|
+
}, jo = (e) => e === " " || e === " " || e === `
|
|
3903
|
+
` || e === "\r", fe = (e) => e >= "0" && e <= "9", en = (e) => e >= "a" && e <= "z" || e >= "A" && e <= "Z", Zn = (e) => fe(e) || e >= "a" && e <= "f" || e >= "A" && e <= "F", tn = /* @__PURE__ */ new Set(["num", "const", "var", "func", "lparen", "uop"]), Vo = /* @__PURE__ */ new Set(["num", "const", "var", "rparen", "postfix"]);
|
|
3904
|
+
function Yo(e) {
|
|
3905
|
+
return e === "HEX" ? Zn : e === "OCT" ? (t) => t >= "0" && t <= "7" : e === "BIN" ? (t) => t === "0" || t === "1" : fe;
|
|
3906
|
+
}
|
|
3907
|
+
function Ko(e) {
|
|
3908
|
+
const t = e.toLowerCase(), n = Go[t] ?? t;
|
|
3909
|
+
if (qo.has(n)) return { type: "func", value: n };
|
|
3896
3910
|
if (t === "mod") return { type: "op", value: "mod" };
|
|
3897
3911
|
if (t === "and") return { type: "op", value: "and" };
|
|
3898
3912
|
if (t === "or") return { type: "op", value: "or" };
|
|
@@ -3909,12 +3923,12 @@ function Vo(e) {
|
|
|
3909
3923
|
}
|
|
3910
3924
|
throw new Error(`Unknown name: ${e}`);
|
|
3911
3925
|
}
|
|
3912
|
-
function
|
|
3926
|
+
function Wo(e, t = {}) {
|
|
3913
3927
|
const n = t.base ?? "DEC", a = e, r = [];
|
|
3914
3928
|
let s = 0;
|
|
3915
3929
|
for (; s < a.length; ) {
|
|
3916
3930
|
const d = a[s];
|
|
3917
|
-
if (
|
|
3931
|
+
if (jo(d)) {
|
|
3918
3932
|
s++;
|
|
3919
3933
|
continue;
|
|
3920
3934
|
}
|
|
@@ -3922,14 +3936,14 @@ function Yo(e, t = {}) {
|
|
|
3922
3936
|
if (d === "0" && (a[s + 1] === "x" || a[s + 1] === "X" || a[s + 1] === "o" || a[s + 1] === "O" || a[s + 1] === "b" || a[s + 1] === "B")) {
|
|
3923
3937
|
const l = a[s + 1].toLowerCase();
|
|
3924
3938
|
let p = s + 2;
|
|
3925
|
-
const h = l === "x" ?
|
|
3939
|
+
const h = l === "x" ? Zn : l === "o" ? (y) => y >= "0" && y <= "7" : (y) => y === "0" || y === "1", f = p;
|
|
3926
3940
|
for (; p < a.length && h(a[p]); ) p++;
|
|
3927
3941
|
if (p === f) throw new Error(`Malformed 0${l} literal`);
|
|
3928
3942
|
r.push({ type: "num", value: BigInt(`0${l}${a.slice(f, p)}`).toString() }), s = p;
|
|
3929
3943
|
continue;
|
|
3930
3944
|
}
|
|
3931
3945
|
if (n !== "DEC") {
|
|
3932
|
-
const l =
|
|
3946
|
+
const l = Yo(n);
|
|
3933
3947
|
let p = s;
|
|
3934
3948
|
for (; p < a.length && l(a[p]); ) p++;
|
|
3935
3949
|
const h = a.slice(s, p), f = n === "HEX" ? "0x" : n === "OCT" ? "0o" : "0b";
|
|
@@ -3953,7 +3967,7 @@ function Yo(e, t = {}) {
|
|
|
3953
3967
|
if (en(d) || d === "_") {
|
|
3954
3968
|
let c = s;
|
|
3955
3969
|
for (; c < a.length && (en(a[c]) || fe(a[c]) || a[c] === "_"); ) c++;
|
|
3956
|
-
r.push(
|
|
3970
|
+
r.push(Ko(a.slice(s, c))), s = c;
|
|
3957
3971
|
continue;
|
|
3958
3972
|
}
|
|
3959
3973
|
const i = a.slice(s, s + 2);
|
|
@@ -4033,11 +4047,11 @@ function Yo(e, t = {}) {
|
|
|
4033
4047
|
}), m = [];
|
|
4034
4048
|
for (let d = 0; d < u.length; d++) {
|
|
4035
4049
|
const i = u[d], c = m[m.length - 1];
|
|
4036
|
-
c &&
|
|
4050
|
+
c && Vo.has(c.type) && tn.has(i.type) && m.push({ type: "op", value: "*", implicit: !0 }), m.push(i);
|
|
4037
4051
|
}
|
|
4038
4052
|
return m;
|
|
4039
4053
|
}
|
|
4040
|
-
const
|
|
4054
|
+
const zo = {
|
|
4041
4055
|
or: { prec: 1 },
|
|
4042
4056
|
xor: { prec: 2 },
|
|
4043
4057
|
and: { prec: 3 },
|
|
@@ -4051,7 +4065,7 @@ const Ko = {
|
|
|
4051
4065
|
"%": { prec: 6 },
|
|
4052
4066
|
"^": { prec: 8, right: !0 }
|
|
4053
4067
|
}, nn = { neg: 7, bnot: 7, sqrt: 10, cbrt: 10, qdrt: 10 }, De = Symbol("arg");
|
|
4054
|
-
function
|
|
4068
|
+
function Jo(e) {
|
|
4055
4069
|
const t = [], n = [];
|
|
4056
4070
|
let a = !0;
|
|
4057
4071
|
const r = () => {
|
|
@@ -4102,7 +4116,7 @@ function Wo(e) {
|
|
|
4102
4116
|
else if (d.value !== "+") throw new Error(`Unexpected operator: ${d.value}`);
|
|
4103
4117
|
a = !0;
|
|
4104
4118
|
} else {
|
|
4105
|
-
const i =
|
|
4119
|
+
const i = zo[d.value];
|
|
4106
4120
|
if (!i) throw new Error(`Unknown operator: ${d.value}`);
|
|
4107
4121
|
for (; n.length; ) {
|
|
4108
4122
|
const c = n[n.length - 1];
|
|
@@ -4143,7 +4157,7 @@ function Wo(e) {
|
|
|
4143
4157
|
if (m === De) throw new Error("Malformed expression");
|
|
4144
4158
|
return m;
|
|
4145
4159
|
}
|
|
4146
|
-
const
|
|
4160
|
+
const Zo = new H("3.141592653589793238462643383279502884197"), Xo = new H("2.718281828459045235360287471352662497757"), Qo = new H("1.618033988749894848204586834365638117720");
|
|
4147
4161
|
function gt(e, t) {
|
|
4148
4162
|
return t === "deg" ? e * Math.PI / 180 : t === "grad" ? e * Math.PI / 200 : e;
|
|
4149
4163
|
}
|
|
@@ -4157,13 +4171,13 @@ function an(e) {
|
|
|
4157
4171
|
for (let n = 2; n <= e.toNumber(); n++) t = t.times(n);
|
|
4158
4172
|
return t;
|
|
4159
4173
|
}
|
|
4160
|
-
function
|
|
4174
|
+
function ei(e, t) {
|
|
4161
4175
|
if (!e.isInteger() || !t.isInteger() || t.isNegative() || t.gt(e)) throw new Error("nPr domain");
|
|
4162
4176
|
let n = g(1);
|
|
4163
4177
|
for (let a = 0; a < t.toNumber(); a++) n = n.times(e.minus(a));
|
|
4164
4178
|
return n;
|
|
4165
4179
|
}
|
|
4166
|
-
function
|
|
4180
|
+
function ti(e, t) {
|
|
4167
4181
|
if (!e.isInteger() || !t.isInteger() || t.isNegative() || t.gt(e)) throw new Error("nCr domain");
|
|
4168
4182
|
const n = H.min(t, e.minus(t));
|
|
4169
4183
|
let a = g(1);
|
|
@@ -4186,7 +4200,7 @@ function kt(e, t) {
|
|
|
4186
4200
|
return e.pow(g(1).div(t));
|
|
4187
4201
|
}
|
|
4188
4202
|
const ie = (e) => BigInt(e.trunc().toFixed(0));
|
|
4189
|
-
function
|
|
4203
|
+
function ni(e, t = {}) {
|
|
4190
4204
|
const n = t.angleMode ?? "deg", a = t.percentMode ?? "of", r = (i) => {
|
|
4191
4205
|
var l;
|
|
4192
4206
|
if (i === "ans") return g(t.ans ?? 0);
|
|
@@ -4268,9 +4282,9 @@ function ei(e, t = {}) {
|
|
|
4268
4282
|
case "tenpow":
|
|
4269
4283
|
return p(1), g(10).pow(l);
|
|
4270
4284
|
case "ncr":
|
|
4271
|
-
return p(2),
|
|
4285
|
+
return p(2), ti(l, c[1]);
|
|
4272
4286
|
case "npr":
|
|
4273
|
-
return p(2),
|
|
4287
|
+
return p(2), ei(l, c[1]);
|
|
4274
4288
|
case "gcd":
|
|
4275
4289
|
return p(2), rn(l, c[1]);
|
|
4276
4290
|
case "lcm":
|
|
@@ -4336,7 +4350,7 @@ function ei(e, t = {}) {
|
|
|
4336
4350
|
case "num":
|
|
4337
4351
|
return g(i.value);
|
|
4338
4352
|
case "const":
|
|
4339
|
-
return i.name === "PI" ?
|
|
4353
|
+
return i.name === "PI" ? Zo : i.name === "E" ? Xo : Qo;
|
|
4340
4354
|
case "var":
|
|
4341
4355
|
return r(i.name);
|
|
4342
4356
|
case "percent":
|
|
@@ -4363,7 +4377,7 @@ function ei(e, t = {}) {
|
|
|
4363
4377
|
function on(e, t = {}) {
|
|
4364
4378
|
if (e == null || e.trim() === "") return { value: new H(0) };
|
|
4365
4379
|
try {
|
|
4366
|
-
const n =
|
|
4380
|
+
const n = Wo(e, { base: t.base }), a = Jo(n), r = ni(a, t);
|
|
4367
4381
|
return r.isNaN() ? { value: r, error: "Not a number" } : { value: r };
|
|
4368
4382
|
} catch (n) {
|
|
4369
4383
|
return { value: new H(NaN), error: n instanceof Error ? n.message : String(n) };
|
|
@@ -4378,7 +4392,7 @@ function sn(e, t) {
|
|
|
4378
4392
|
}
|
|
4379
4393
|
return e.toSignificantDigits(12).toString();
|
|
4380
4394
|
}
|
|
4381
|
-
function
|
|
4395
|
+
function Xn({ def: e }) {
|
|
4382
4396
|
const { settings: t } = ue(), n = t.percentMode ?? "of", [a, r] = M(""), [s, u] = M("deg"), [m, d] = M("DEC"), [i, c] = M(!1), [l, p] = M(() => new H(0)), [h, f] = M(() => new H(0)), [y, w] = M([]), k = de(null), S = X(
|
|
4383
4397
|
() => on(a, { angleMode: s, percentMode: n, base: m, ans: h, memory: l }),
|
|
4384
4398
|
[a, s, n, m, h, l]
|
|
@@ -4567,7 +4581,7 @@ function Zn({ def: e }) {
|
|
|
4567
4581
|
] })
|
|
4568
4582
|
] });
|
|
4569
4583
|
}
|
|
4570
|
-
const
|
|
4584
|
+
const rt = [
|
|
4571
4585
|
{ code: "USD", name: "US Dollar", symbol: "$" },
|
|
4572
4586
|
{ code: "EUR", name: "Euro", symbol: "€" },
|
|
4573
4587
|
{ code: "GBP", name: "British Pound", symbol: "£" },
|
|
@@ -4612,28 +4626,28 @@ const at = [
|
|
|
4612
4626
|
{ code: "BDT", name: "Bangladeshi Taka", symbol: "৳" },
|
|
4613
4627
|
{ code: "LKR", name: "Sri Lankan Rupee", symbol: "Rs" },
|
|
4614
4628
|
{ code: "NPR", name: "Nepalese Rupee", symbol: "रू" }
|
|
4615
|
-
],
|
|
4629
|
+
], ai = (e) => rt.find((t) => t.code === e), ri = (e) => e === "INR" ? "en-IN" : "en-US", Qn = (e, t) => g(e).times(t), ea = (e) => {
|
|
4616
4630
|
const t = g(e);
|
|
4617
4631
|
return t.gt(0) ? g(1).div(t) : g(0);
|
|
4618
4632
|
};
|
|
4619
4633
|
function Mt(e, t) {
|
|
4620
4634
|
const n = g(e);
|
|
4621
4635
|
try {
|
|
4622
|
-
return new Intl.NumberFormat(
|
|
4636
|
+
return new Intl.NumberFormat(ri(t), { style: "currency", currency: t }).format(
|
|
4623
4637
|
Number(n.toFixed(4))
|
|
4624
4638
|
);
|
|
4625
4639
|
} catch {
|
|
4626
4640
|
return `${new Intl.NumberFormat("en-US", { maximumFractionDigits: 4 }).format(Number(n.toFixed(4)))} ${t}`;
|
|
4627
4641
|
}
|
|
4628
4642
|
}
|
|
4629
|
-
function
|
|
4643
|
+
function ta(e) {
|
|
4630
4644
|
try {
|
|
4631
4645
|
return new Intl.NumberFormat("en-US", { style: "currency", currency: e }).resolvedOptions().maximumFractionDigits ?? 2;
|
|
4632
4646
|
} catch {
|
|
4633
4647
|
return 2;
|
|
4634
4648
|
}
|
|
4635
4649
|
}
|
|
4636
|
-
function
|
|
4650
|
+
function Xe(e, t) {
|
|
4637
4651
|
const n = Math.max(0, Math.floor((t - e) / 1e3));
|
|
4638
4652
|
if (n < 60) return "just now";
|
|
4639
4653
|
const a = Math.floor(n / 60);
|
|
@@ -4645,23 +4659,23 @@ function Ze(e, t) {
|
|
|
4645
4659
|
const u = Math.floor(s / 30);
|
|
4646
4660
|
return `${u} month${u === 1 ? "" : "s"} ago`;
|
|
4647
4661
|
}
|
|
4648
|
-
const
|
|
4662
|
+
const na = (e, t) => t - e > 864e5, gs = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
4649
4663
|
__proto__: null,
|
|
4650
|
-
CURRENCIES:
|
|
4651
|
-
convert:
|
|
4652
|
-
currencyByCode:
|
|
4653
|
-
currencyDecimals:
|
|
4664
|
+
CURRENCIES: rt,
|
|
4665
|
+
convert: Qn,
|
|
4666
|
+
currencyByCode: ai,
|
|
4667
|
+
currencyDecimals: ta,
|
|
4654
4668
|
formatCurrency: Mt,
|
|
4655
|
-
inverseRate:
|
|
4656
|
-
isStale:
|
|
4657
|
-
stalenessLabel:
|
|
4658
|
-
}, Symbol.toStringTag, { value: "Module" })),
|
|
4659
|
-
async function
|
|
4669
|
+
inverseRate: ea,
|
|
4670
|
+
isStale: na,
|
|
4671
|
+
stalenessLabel: Xe
|
|
4672
|
+
}, Symbol.toStringTag, { value: "Module" })), oi = (e) => `https://open.er-api.com/v6/latest/${encodeURIComponent(e)}`;
|
|
4673
|
+
async function ii(e, t, n = {}) {
|
|
4660
4674
|
var m;
|
|
4661
4675
|
if (e === t) return { rate: "1", asOf: "", provider: "identity" };
|
|
4662
4676
|
const a = n.fetchImpl ?? (typeof fetch < "u" ? fetch : void 0);
|
|
4663
4677
|
if (!a) throw new Error("No fetch available in this environment");
|
|
4664
|
-
const r = await a(
|
|
4678
|
+
const r = await a(oi(e), { signal: n.signal });
|
|
4665
4679
|
if (!r.ok) throw new Error(`Rate service returned HTTP ${r.status}`);
|
|
4666
4680
|
const s = await r.json();
|
|
4667
4681
|
if (s != null && s.result && s.result !== "success") throw new Error(s["error-type"] || "Rate service error");
|
|
@@ -4673,35 +4687,35 @@ function ln(e, t) {
|
|
|
4673
4687
|
const n = Date.parse(e);
|
|
4674
4688
|
return Number.isFinite(n) ? n : t;
|
|
4675
4689
|
}
|
|
4676
|
-
const
|
|
4690
|
+
const aa = "calcsuite:fxrates", ra = "calcsuite:fxmode", wt = () => {
|
|
4677
4691
|
try {
|
|
4678
|
-
return JSON.parse(localStorage.getItem(
|
|
4692
|
+
return JSON.parse(localStorage.getItem(aa) || "{}");
|
|
4679
4693
|
} catch {
|
|
4680
4694
|
return {};
|
|
4681
4695
|
}
|
|
4682
|
-
},
|
|
4696
|
+
}, si = (e) => {
|
|
4683
4697
|
try {
|
|
4684
|
-
localStorage.setItem(
|
|
4698
|
+
localStorage.setItem(aa, JSON.stringify(e));
|
|
4685
4699
|
} catch {
|
|
4686
4700
|
}
|
|
4687
|
-
},
|
|
4701
|
+
}, li = () => {
|
|
4688
4702
|
try {
|
|
4689
|
-
return localStorage.getItem(
|
|
4703
|
+
return localStorage.getItem(ra) === "offline" ? "offline" : "online";
|
|
4690
4704
|
} catch {
|
|
4691
4705
|
return "online";
|
|
4692
4706
|
}
|
|
4693
|
-
},
|
|
4694
|
-
function
|
|
4707
|
+
}, We = (e, t) => `${e}_${t}`;
|
|
4708
|
+
function oa() {
|
|
4695
4709
|
var _t;
|
|
4696
|
-
const [e, t] = M("USD"), [n, a] = M("INR"), [r, s] = M(""), [u, m] = M(""), [d, i] = M("none"), [c, l] = M(""), [p, h] = M("idle"), [f, y] = M(""), [w, k] = M(() =>
|
|
4710
|
+
const [e, t] = M("USD"), [n, a] = M("INR"), [r, s] = M(""), [u, m] = M(""), [d, i] = M("none"), [c, l] = M(""), [p, h] = M("idle"), [f, y] = M(""), [w, k] = M(() => li()), [S, F] = M(() => wt()), [N, P] = M(() => Date.now()), x = de(null);
|
|
4697
4711
|
Q(() => {
|
|
4698
4712
|
const O = setInterval(() => P(Date.now()), 3e4);
|
|
4699
4713
|
return () => clearInterval(O);
|
|
4700
4714
|
}, []);
|
|
4701
4715
|
const T = (O, Z) => {
|
|
4702
4716
|
F((ae) => {
|
|
4703
|
-
const oe = { ...ae, [
|
|
4704
|
-
return
|
|
4717
|
+
const oe = { ...ae, [We(e, n)]: { rate: O, at: Z } };
|
|
4718
|
+
return si(oe), oe;
|
|
4705
4719
|
});
|
|
4706
4720
|
}, $ = (O, Z) => {
|
|
4707
4721
|
var oe;
|
|
@@ -4711,11 +4725,11 @@ function ra() {
|
|
|
4711
4725
|
m("1"), i("live"), l(""), h("idle");
|
|
4712
4726
|
return;
|
|
4713
4727
|
}
|
|
4714
|
-
h("loading"), y(""),
|
|
4728
|
+
h("loading"), y(""), ii(O, Z, { signal: ae.signal }).then((xe) => {
|
|
4715
4729
|
ae.signal.aborted || (m(xe.rate), i("live"), l(xe.asOf), h("idle"), T(xe.rate, ln(xe.asOf, Date.now())));
|
|
4716
4730
|
}).catch((xe) => {
|
|
4717
4731
|
if (ae.signal.aborted) return;
|
|
4718
|
-
const Ht = wt()[
|
|
4732
|
+
const Ht = wt()[We(O, Z)];
|
|
4719
4733
|
Ht ? (m(Ht.rate), i("saved"), h("error"), y("Offline — showing your last saved rate. Refresh when back online.")) : (i("none"), h("error"), y(`Couldn’t fetch a live rate (${xe instanceof Error ? xe.message : "offline"}). Enter one manually.`));
|
|
4720
4734
|
});
|
|
4721
4735
|
}, L = (O, Z) => {
|
|
@@ -4724,7 +4738,7 @@ function ra() {
|
|
|
4724
4738
|
m("1"), i("saved");
|
|
4725
4739
|
return;
|
|
4726
4740
|
}
|
|
4727
|
-
const ae = wt()[
|
|
4741
|
+
const ae = wt()[We(O, Z)];
|
|
4728
4742
|
ae ? (m(ae.rate), i("saved")) : (m(""), i("none"));
|
|
4729
4743
|
};
|
|
4730
4744
|
Q(() => (w === "online" ? $(e, n) : L(e, n), () => {
|
|
@@ -4734,21 +4748,21 @@ function ra() {
|
|
|
4734
4748
|
const B = (O) => {
|
|
4735
4749
|
k(O);
|
|
4736
4750
|
try {
|
|
4737
|
-
localStorage.setItem(
|
|
4751
|
+
localStorage.setItem(ra, O);
|
|
4738
4752
|
} catch {
|
|
4739
4753
|
}
|
|
4740
4754
|
}, G = (O) => O.replace(/[, ]/g, "").trim(), q = G(r), A = G(u), I = q !== "" && Number(q) >= 0 && Number.isFinite(Number(q)), R = A !== "" && Number(A) > 0 && Number.isFinite(Number(A)), j = X(
|
|
4741
|
-
() => I && R ?
|
|
4755
|
+
() => I && R ? Qn(q, A) : null,
|
|
4742
4756
|
[I, R, q, A]
|
|
4743
|
-
), Y = R ?
|
|
4757
|
+
), Y = R ? ea(A) : null, V = (O) => {
|
|
4744
4758
|
m(O), i("manual"), h("idle"), y(""), (R || O.trim() !== "") && T(G(O), Date.now());
|
|
4745
4759
|
}, ee = () => {
|
|
4746
4760
|
t(n), a(e);
|
|
4747
|
-
}, Ee = c ?
|
|
4761
|
+
}, Ee = c ? Xe(ln(c, N), N) : "just now", K = (_t = S[We(e, n)]) == null ? void 0 : _t.at, pe = (O) => /* @__PURE__ */ b("option", { value: O.code, children: [
|
|
4748
4762
|
O.code,
|
|
4749
4763
|
" — ",
|
|
4750
4764
|
O.name
|
|
4751
|
-
] }, O.code), Me = Object.entries(S).sort((O, Z) => Z[1].at - O[1].at),
|
|
4765
|
+
] }, O.code), Me = Object.entries(S).sort((O, Z) => Z[1].at - O[1].at), je = () => p === "error" ? /* @__PURE__ */ b("span", { children: [
|
|
4752
4766
|
"⚠ ",
|
|
4753
4767
|
f
|
|
4754
4768
|
] }) : d === "manual" ? /* @__PURE__ */ o("span", { children: "Manual rate (you entered this)" }) : w === "online" ? p === "loading" ? /* @__PURE__ */ o("span", { children: "Fetching live rate…" }) : d === "live" ? /* @__PURE__ */ b("span", { children: [
|
|
@@ -4758,7 +4772,7 @@ function ra() {
|
|
|
4758
4772
|
" · open.er-api.com"
|
|
4759
4773
|
] }) : null : d === "saved" && K ? /* @__PURE__ */ b("span", { children: [
|
|
4760
4774
|
"✈ Offline · saved rate ",
|
|
4761
|
-
|
|
4775
|
+
Xe(K, N)
|
|
4762
4776
|
] }) : /* @__PURE__ */ o("span", { children: "✈ Offline · enter a rate manually" });
|
|
4763
4777
|
return /* @__PURE__ */ b("div", { "data-part": "calculator", "data-calculator": "tools.currency", children: [
|
|
4764
4778
|
/* @__PURE__ */ b("section", { className: "card", children: [
|
|
@@ -4783,12 +4797,12 @@ function ra() {
|
|
|
4783
4797
|
] }),
|
|
4784
4798
|
/* @__PURE__ */ b("label", { className: "field cc-cur", children: [
|
|
4785
4799
|
/* @__PURE__ */ o("span", { className: "lbl", children: "From" }),
|
|
4786
|
-
/* @__PURE__ */ o("div", { className: "input-wrap", children: /* @__PURE__ */ o("select", { value: e, onChange: (O) => t(O.target.value), "aria-label": "From currency", children:
|
|
4800
|
+
/* @__PURE__ */ o("div", { className: "input-wrap", children: /* @__PURE__ */ o("select", { value: e, onChange: (O) => t(O.target.value), "aria-label": "From currency", children: rt.map(pe) }) })
|
|
4787
4801
|
] }),
|
|
4788
4802
|
/* @__PURE__ */ o("button", { type: "button", className: "cc-swap", onClick: ee, "aria-label": "Swap currencies", title: "Swap", children: "⇄" }),
|
|
4789
4803
|
/* @__PURE__ */ b("label", { className: "field cc-cur", children: [
|
|
4790
4804
|
/* @__PURE__ */ o("span", { className: "lbl", children: "To" }),
|
|
4791
|
-
/* @__PURE__ */ o("div", { className: "input-wrap", children: /* @__PURE__ */ o("select", { value: n, onChange: (O) => a(O.target.value), "aria-label": "To currency", children:
|
|
4805
|
+
/* @__PURE__ */ o("div", { className: "input-wrap", children: /* @__PURE__ */ o("select", { value: n, onChange: (O) => a(O.target.value), "aria-label": "To currency", children: rt.map(pe) }) })
|
|
4792
4806
|
] })
|
|
4793
4807
|
] }),
|
|
4794
4808
|
/* @__PURE__ */ b("label", { className: "field", style: { marginTop: 16 }, children: [
|
|
@@ -4822,7 +4836,7 @@ function ra() {
|
|
|
4822
4836
|
}
|
|
4823
4837
|
)
|
|
4824
4838
|
] }),
|
|
4825
|
-
/* @__PURE__ */ o("div", { className: `cc-status ${p === "error" ? "cc-stale" : ""}`, "aria-live": "polite", children:
|
|
4839
|
+
/* @__PURE__ */ o("div", { className: `cc-status ${p === "error" ? "cc-stale" : ""}`, "aria-live": "polite", children: je() }),
|
|
4826
4840
|
e === n && /* @__PURE__ */ o("div", { className: "notice", children: "“From” and “To” are the same currency — the rate is 1." })
|
|
4827
4841
|
] })
|
|
4828
4842
|
] }),
|
|
@@ -4859,7 +4873,7 @@ function ra() {
|
|
|
4859
4873
|
/* @__PURE__ */ b("div", { className: "kv", children: [
|
|
4860
4874
|
/* @__PURE__ */ o("div", { className: "k", children: "Precision" }),
|
|
4861
4875
|
/* @__PURE__ */ b("div", { className: "v num", children: [
|
|
4862
|
-
|
|
4876
|
+
ta(n),
|
|
4863
4877
|
" dp · ",
|
|
4864
4878
|
n
|
|
4865
4879
|
] })
|
|
@@ -4892,7 +4906,7 @@ function ra() {
|
|
|
4892
4906
|
oe
|
|
4893
4907
|
] }),
|
|
4894
4908
|
/* @__PURE__ */ o("span", { className: "num", children: Z.rate }),
|
|
4895
|
-
/* @__PURE__ */ o("span", { className: `cc-book-when ${
|
|
4909
|
+
/* @__PURE__ */ o("span", { className: `cc-book-when ${na(Z.at, N) ? "cc-stale" : ""}`, children: Xe(Z.at, N) })
|
|
4896
4910
|
]
|
|
4897
4911
|
}
|
|
4898
4912
|
) }, O);
|
|
@@ -4900,23 +4914,23 @@ function ra() {
|
|
|
4900
4914
|
] })
|
|
4901
4915
|
] });
|
|
4902
4916
|
}
|
|
4903
|
-
const
|
|
4917
|
+
const ci = {
|
|
4904
4918
|
id: "",
|
|
4905
4919
|
group: "tools",
|
|
4906
4920
|
title: "",
|
|
4907
4921
|
inputs: [],
|
|
4908
4922
|
compute: () => ({ primary: { label: "", value: "" } })
|
|
4909
|
-
},
|
|
4910
|
-
"loan.emi":
|
|
4911
|
-
scientific:
|
|
4912
|
-
currency:
|
|
4923
|
+
}, ui = {
|
|
4924
|
+
"loan.emi": Jn,
|
|
4925
|
+
scientific: Xn,
|
|
4926
|
+
currency: oa
|
|
4913
4927
|
};
|
|
4914
4928
|
function cn(e, t) {
|
|
4915
4929
|
const n = {};
|
|
4916
4930
|
for (const a of e.inputs) a.default !== void 0 && (n[a.key] = a.default);
|
|
4917
4931
|
return t ? { ...n, ...t } : n;
|
|
4918
4932
|
}
|
|
4919
|
-
function
|
|
4933
|
+
function di({
|
|
4920
4934
|
def: e,
|
|
4921
4935
|
id: t,
|
|
4922
4936
|
seed: n,
|
|
@@ -4925,7 +4939,7 @@ function ci({
|
|
|
4925
4939
|
actions: s
|
|
4926
4940
|
}) {
|
|
4927
4941
|
var L, B, G, q;
|
|
4928
|
-
const u = e ?? (t ? Rt(t) : void 0), m = u ??
|
|
4942
|
+
const u = e ?? (t ? Rt(t) : void 0), m = u ?? ci, d = { ...ui, ...a }, { settings: i, fmt: c } = ue(), [l, p] = M(() => cn(m, n)), [h, f] = M("schedule"), [y, w] = M(!1);
|
|
4929
4943
|
Q(() => p(cn(m, n)), [m.id, n]);
|
|
4930
4944
|
const k = i.region, S = (A, I) => p((R) => ({ ...R, [A]: I })), F = m.inputs.filter((A) => A.showIf ? A.showIf(l, k) : !0), N = F.filter((A) => !A.advanced), P = F.filter((A) => A.advanced), { result: x, error: T } = X(() => {
|
|
4931
4945
|
const A = { settings: i, region: k, fmt: c, D: g };
|
|
@@ -4963,7 +4977,7 @@ function ci({
|
|
|
4963
4977
|
T && /* @__PURE__ */ o("div", { className: "error", role: "alert", style: { marginTop: 16 }, children: T })
|
|
4964
4978
|
] }),
|
|
4965
4979
|
x && !T && /* @__PURE__ */ b("section", { className: "card", children: [
|
|
4966
|
-
/* @__PURE__ */ o(
|
|
4980
|
+
/* @__PURE__ */ o(ro, { view: x }),
|
|
4967
4981
|
(B = x.warnings) == null ? void 0 : B.map((A, I) => /* @__PURE__ */ o("div", { className: "notice", children: A }, I)),
|
|
4968
4982
|
s && /* @__PURE__ */ o("div", { className: "actions-row", children: s(x, l) }),
|
|
4969
4983
|
$ && /* @__PURE__ */ b(re, { children: [
|
|
@@ -4974,8 +4988,8 @@ function ci({
|
|
|
4974
4988
|
(((G = x.notes) == null ? void 0 : G.length) ?? 0) > 0 && i.ui.showAssumptions && /* @__PURE__ */ o("button", { role: "tab", "aria-selected": h === "assumptions", onClick: () => f("assumptions"), children: "Assumptions" })
|
|
4975
4989
|
] }),
|
|
4976
4990
|
/* @__PURE__ */ b("div", { className: "tab-anim", children: [
|
|
4977
|
-
h === "schedule" && x.schedule && /* @__PURE__ */ o(
|
|
4978
|
-
h === "chart" && x.chart && /* @__PURE__ */ o(
|
|
4991
|
+
h === "schedule" && x.schedule && /* @__PURE__ */ o(so, { schedule: x.schedule }),
|
|
4992
|
+
h === "chart" && x.chart && /* @__PURE__ */ o(lo, { chart: x.chart }),
|
|
4979
4993
|
h === "formula" && x.formula && i.ui.showFormulas && /* @__PURE__ */ b("div", { className: "formula", children: [
|
|
4980
4994
|
/* @__PURE__ */ o("code", { children: x.formula }),
|
|
4981
4995
|
x.formulaSubstituted && /* @__PURE__ */ o("code", { style: { marginTop: 8 }, children: x.formulaSubstituted })
|
|
@@ -4998,7 +5012,7 @@ function un({ def: e, region: t }) {
|
|
|
4998
5012
|
}
|
|
4999
5013
|
function dn({ f: e, values: t, set: n }) {
|
|
5000
5014
|
const a = e.kind === "cashflows" || e.kind === "segmented" ? "span2" : "";
|
|
5001
|
-
return /* @__PURE__ */ o("div", { className: a, children: /* @__PURE__ */ o(
|
|
5015
|
+
return /* @__PURE__ */ o("div", { className: a, children: /* @__PURE__ */ o(to, { f: e, value: t[e.key], onChange: (r) => n(e.key, r), values: t }) });
|
|
5002
5016
|
}
|
|
5003
5017
|
class z extends Error {
|
|
5004
5018
|
constructor(n, a = { code: "transport_error" }) {
|
|
@@ -5010,17 +5024,17 @@ class z extends Error {
|
|
|
5010
5024
|
this.name = "TransportError", this.code = a.code, this.status = a.status ?? 0, this.request = a.request;
|
|
5011
5025
|
}
|
|
5012
5026
|
}
|
|
5013
|
-
const
|
|
5027
|
+
const mi = ["authorization", "cookie", "x-api-key", "x-auth-token", "api-key"], pi = {
|
|
5014
5028
|
attempts: 3,
|
|
5015
5029
|
backoff: "exponential",
|
|
5016
5030
|
baseDelayMs: 300,
|
|
5017
5031
|
retryOn: [408, 429, 500, 502, 503, 504],
|
|
5018
5032
|
respectRetryAfter: !0
|
|
5019
|
-
},
|
|
5033
|
+
}, hi = {
|
|
5020
5034
|
enabled: !0,
|
|
5021
5035
|
headerName: "Idempotency-Key",
|
|
5022
5036
|
keyFrom: "inputsHash"
|
|
5023
|
-
},
|
|
5037
|
+
}, fi = {
|
|
5024
5038
|
enabled: !0,
|
|
5025
5039
|
storage: "memory",
|
|
5026
5040
|
maxItems: 200,
|
|
@@ -5032,7 +5046,7 @@ const ui = ["authorization", "cookie", "x-api-key", "x-auth-token", "api-key"],
|
|
|
5032
5046
|
return !1;
|
|
5033
5047
|
}
|
|
5034
5048
|
};
|
|
5035
|
-
function
|
|
5049
|
+
function ia() {
|
|
5036
5050
|
const e = globalThis.crypto;
|
|
5037
5051
|
return e != null && e.randomUUID ? e.randomUUID() : "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (t) => {
|
|
5038
5052
|
const n = Math.random() * 16 | 0;
|
|
@@ -5040,21 +5054,21 @@ function oa() {
|
|
|
5040
5054
|
});
|
|
5041
5055
|
}
|
|
5042
5056
|
const pn = (e) => new Promise((t) => setTimeout(t, Math.max(0, e)));
|
|
5043
|
-
function
|
|
5057
|
+
function yi(e) {
|
|
5044
5058
|
let t = String(e).replace(/[\\/]+/g, "-").replace(/[\x00-\x1f\x7f]+/g, "").replace(/[<>:"|?*]+/g, "").replace(/^\.+/, "");
|
|
5045
5059
|
return t = t.trim(), t || "file";
|
|
5046
5060
|
}
|
|
5047
|
-
function
|
|
5061
|
+
function sa(e, t) {
|
|
5048
5062
|
var m;
|
|
5049
5063
|
const n = /* @__PURE__ */ new Date(), a = (d) => String(d).padStart(2, "0"), r = (((m = t.filename) == null ? void 0 : m.split(".").pop()) || t.kind || "bin").toLowerCase(), s = (t.inputsHash || "").replace(/^sha256:/, "").slice(0, 8) || "00000000", u = e.replace(/\{calculator\}/g, t.calculator || "calc").replace(/\{yyyy\}/g, String(n.getFullYear())).replace(/\{MM\}/g, a(n.getMonth() + 1)).replace(/\{dd\}/g, a(n.getDate())).replace(/\{hash8\}/g, s).replace(/\{ext\}/g, r).replace(/\{kind\}/g, t.kind || "file");
|
|
5050
|
-
return
|
|
5064
|
+
return yi(u);
|
|
5051
5065
|
}
|
|
5052
5066
|
function $t(e, t = []) {
|
|
5053
|
-
const n = /* @__PURE__ */ new Set([...
|
|
5067
|
+
const n = /* @__PURE__ */ new Set([...mi, ...t.map((r) => r.toLowerCase())]), a = {};
|
|
5054
5068
|
for (const [r, s] of Object.entries(e)) a[r] = n.has(r.toLowerCase()) ? "***" : s;
|
|
5055
5069
|
return a;
|
|
5056
5070
|
}
|
|
5057
|
-
class
|
|
5071
|
+
class bi {
|
|
5058
5072
|
constructor(t, n) {
|
|
5059
5073
|
ge(this, "items", []);
|
|
5060
5074
|
ge(this, "key");
|
|
@@ -5082,7 +5096,7 @@ class fi {
|
|
|
5082
5096
|
return this.items.length;
|
|
5083
5097
|
}
|
|
5084
5098
|
enqueue(t) {
|
|
5085
|
-
const n = { ...t, id:
|
|
5099
|
+
const n = { ...t, id: ia(), createdAt: (/* @__PURE__ */ new Date()).toISOString(), retryCount: 0 };
|
|
5086
5100
|
for (this.items.push(n); this.items.length > this.cfg.maxItems; ) this.items.shift();
|
|
5087
5101
|
return this.save(), n;
|
|
5088
5102
|
}
|
|
@@ -5104,12 +5118,12 @@ class fi {
|
|
|
5104
5118
|
}
|
|
5105
5119
|
}
|
|
5106
5120
|
const hn = /* @__PURE__ */ new Set(["POST", "PUT", "PATCH", "DELETE"]);
|
|
5107
|
-
function
|
|
5108
|
-
const t = e.fetch ?? globalThis.fetch, n = { ...
|
|
5121
|
+
function gi(e) {
|
|
5122
|
+
const t = e.fetch ?? globalThis.fetch, n = { ...pi, ...e.retry }, a = { ...hi, ...e.idempotency }, r = { ...fi, ...e.offlineQueue }, s = e.timeoutMs ?? 15e3, u = e.credentials ?? "same-origin", m = new bi(r, "calcsuite");
|
|
5109
5123
|
function d(N, P) {
|
|
5110
5124
|
const x = e.endpoints[N];
|
|
5111
5125
|
if (!x) throw new z(`Endpoint "${N}" is not configured`, { code: "no_endpoint" });
|
|
5112
|
-
let T = /^https?:\/\//i.test(x) ? x :
|
|
5126
|
+
let T = /^https?:\/\//i.test(x) ? x : vi(e.baseUrl, x);
|
|
5113
5127
|
return P != null && (T = T.replace(/:id\b/, encodeURIComponent(P))), T;
|
|
5114
5128
|
}
|
|
5115
5129
|
function i() {
|
|
@@ -5124,10 +5138,10 @@ function yi(e) {
|
|
|
5124
5138
|
if (!a.enabled || x) return x;
|
|
5125
5139
|
if (hn.has(fn(N))) {
|
|
5126
5140
|
if (a.keyFrom === "inputsHash") {
|
|
5127
|
-
const T =
|
|
5141
|
+
const T = wi(P);
|
|
5128
5142
|
if (T) return T;
|
|
5129
5143
|
}
|
|
5130
|
-
return
|
|
5144
|
+
return ia();
|
|
5131
5145
|
}
|
|
5132
5146
|
}
|
|
5133
5147
|
async function p(N, P, x) {
|
|
@@ -5154,7 +5168,7 @@ function yi(e) {
|
|
|
5154
5168
|
}
|
|
5155
5169
|
async function f(N, P = {}) {
|
|
5156
5170
|
var B, G, q, A;
|
|
5157
|
-
const x = fn(N), T =
|
|
5171
|
+
const x = fn(N), T = ki(d(N, P.pathParam), P.query), $ = l(N, P.body, P.idempotencyKey);
|
|
5158
5172
|
let L;
|
|
5159
5173
|
for (let I = 1; I <= Math.max(1, n.attempts); I++) {
|
|
5160
5174
|
const R = await c(), j = {
|
|
@@ -5184,7 +5198,7 @@ function yi(e) {
|
|
|
5184
5198
|
await pn(h(I, K));
|
|
5185
5199
|
continue;
|
|
5186
5200
|
}
|
|
5187
|
-
const pe = await
|
|
5201
|
+
const pe = await la(K), Me = {
|
|
5188
5202
|
...ee,
|
|
5189
5203
|
status: K.status,
|
|
5190
5204
|
ok: K.ok,
|
|
@@ -5192,12 +5206,12 @@ function yi(e) {
|
|
|
5192
5206
|
data: pe
|
|
5193
5207
|
};
|
|
5194
5208
|
if ((G = e.onResponse) == null || G.call(e, Me), !K.ok) {
|
|
5195
|
-
const
|
|
5209
|
+
const je = new z(`Request failed with ${K.status}`, {
|
|
5196
5210
|
code: "http_error",
|
|
5197
5211
|
status: K.status,
|
|
5198
5212
|
request: ee
|
|
5199
5213
|
});
|
|
5200
|
-
throw (q = e.onError) == null || q.call(e,
|
|
5214
|
+
throw (q = e.onError) == null || q.call(e, je, ee), je;
|
|
5201
5215
|
}
|
|
5202
5216
|
return e.transformResponse ? e.transformResponse(pe, ee) : pe;
|
|
5203
5217
|
} catch (K) {
|
|
@@ -5223,8 +5237,8 @@ function yi(e) {
|
|
|
5223
5237
|
}
|
|
5224
5238
|
async function y(N, P, x = {}) {
|
|
5225
5239
|
const T = e.upload;
|
|
5226
|
-
|
|
5227
|
-
const $ = P.filename ??
|
|
5240
|
+
xi(N, P, T.accept, T.maxBytes);
|
|
5241
|
+
const $ = P.filename ?? sa(T.filenameTemplate, P), L = { ...P, filename: $, bytes: N.size, contentType: P.contentType ?? ca(N) };
|
|
5228
5242
|
if (T.beforeUpload && !await T.beforeUpload(N, L))
|
|
5229
5243
|
throw new z("Upload cancelled by host", { code: "upload_cancelled" });
|
|
5230
5244
|
return T.strategy === "presigned" ? F(N, L, x) : T.strategy === "base64Json" ? S(N, L, x) : k(N, L, x);
|
|
@@ -5255,10 +5269,10 @@ function yi(e) {
|
|
|
5255
5269
|
{ method: "POST", credentials: u, headers: B, body: $ },
|
|
5256
5270
|
x.signal
|
|
5257
5271
|
);
|
|
5258
|
-
return
|
|
5272
|
+
return Ni(G);
|
|
5259
5273
|
}
|
|
5260
5274
|
async function S(N, P, x) {
|
|
5261
|
-
const T = await
|
|
5275
|
+
const T = await Si(N);
|
|
5262
5276
|
return f("upload", {
|
|
5263
5277
|
...x,
|
|
5264
5278
|
body: {
|
|
@@ -5345,23 +5359,23 @@ function fn(e) {
|
|
|
5345
5359
|
function yn() {
|
|
5346
5360
|
return typeof performance < "u" && performance.now ? performance.now() : Date.now();
|
|
5347
5361
|
}
|
|
5348
|
-
function
|
|
5362
|
+
function vi(e, t) {
|
|
5349
5363
|
return e ? `${e.replace(/\/+$/, "")}/${t.replace(/^\/+/, "")}` : t;
|
|
5350
5364
|
}
|
|
5351
|
-
function
|
|
5365
|
+
function ki(e, t) {
|
|
5352
5366
|
if (!t) return e;
|
|
5353
5367
|
const n = [];
|
|
5354
5368
|
for (const [a, r] of Object.entries(t))
|
|
5355
5369
|
r == null || r === "" || n.push(`${encodeURIComponent(a)}=${encodeURIComponent(String(r))}`);
|
|
5356
5370
|
return n.length ? e + (e.includes("?") ? "&" : "?") + n.join("&") : e;
|
|
5357
5371
|
}
|
|
5358
|
-
function
|
|
5372
|
+
function wi(e) {
|
|
5359
5373
|
var a;
|
|
5360
5374
|
if (!e || typeof e != "object") return;
|
|
5361
5375
|
const t = e, n = ((a = t == null ? void 0 : t.meta) == null ? void 0 : a.inputsHash) ?? (t == null ? void 0 : t.inputsHash);
|
|
5362
5376
|
return typeof n == "string" && n ? n : void 0;
|
|
5363
5377
|
}
|
|
5364
|
-
async function
|
|
5378
|
+
async function la(e) {
|
|
5365
5379
|
const t = e.headers.get("content-type") || "";
|
|
5366
5380
|
try {
|
|
5367
5381
|
return t.includes("application/json") ? await e.json() : await e.text() || null;
|
|
@@ -5369,21 +5383,21 @@ async function sa(e) {
|
|
|
5369
5383
|
return null;
|
|
5370
5384
|
}
|
|
5371
5385
|
}
|
|
5372
|
-
async function
|
|
5386
|
+
async function Ni(e) {
|
|
5373
5387
|
if (!e.ok) throw new z(`Upload failed (${e.status})`, { code: "upload_failed", status: e.status });
|
|
5374
|
-
return
|
|
5388
|
+
return la(e);
|
|
5375
5389
|
}
|
|
5376
|
-
function
|
|
5390
|
+
function ca(e) {
|
|
5377
5391
|
return e.type || "application/octet-stream";
|
|
5378
5392
|
}
|
|
5379
|
-
function
|
|
5393
|
+
function xi(e, t, n, a) {
|
|
5380
5394
|
if (e.size > a)
|
|
5381
5395
|
throw new z(`File exceeds ${a} bytes`, { code: "too_large" });
|
|
5382
|
-
const r = t.contentType ??
|
|
5396
|
+
const r = t.contentType ?? ca(e);
|
|
5383
5397
|
if (n.length && r && !n.includes(r))
|
|
5384
5398
|
throw new z(`Content type ${r} not accepted`, { code: "bad_type" });
|
|
5385
5399
|
}
|
|
5386
|
-
async function
|
|
5400
|
+
async function Si(e) {
|
|
5387
5401
|
const t = await e.arrayBuffer(), n = new Uint8Array(t);
|
|
5388
5402
|
if (typeof btoa == "function") {
|
|
5389
5403
|
let r = "";
|
|
@@ -5394,7 +5408,7 @@ async function Ni(e) {
|
|
|
5394
5408
|
if (a) return a.from(n).toString("base64");
|
|
5395
5409
|
throw new z("No base64 encoder available", { code: "no_base64" });
|
|
5396
5410
|
}
|
|
5397
|
-
function
|
|
5411
|
+
function ze(e, t) {
|
|
5398
5412
|
if (!t) return e;
|
|
5399
5413
|
let n = e;
|
|
5400
5414
|
for (const a of t.split(".")) {
|
|
@@ -5412,15 +5426,15 @@ function bn(e, t, n) {
|
|
|
5412
5426
|
}
|
|
5413
5427
|
r[a[a.length - 1]] = n;
|
|
5414
5428
|
}
|
|
5415
|
-
function
|
|
5429
|
+
function Ci(e, t) {
|
|
5416
5430
|
if (t === "asIs") return e;
|
|
5417
5431
|
const n = e.replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/[_\-\s]+/g, " ").trim().split(" ").filter(Boolean);
|
|
5418
5432
|
return n.length === 0 ? e : t === "snake" ? n.map((a) => a.toLowerCase()).join("_") : t === "kebab" ? n.map((a) => a.toLowerCase()).join("-") : n.map((a, r) => r === 0 ? a.toLowerCase() : a[0].toUpperCase() + a.slice(1).toLowerCase()).join("");
|
|
5419
5433
|
}
|
|
5420
5434
|
function gn(e, t) {
|
|
5421
|
-
return e.split(".").map((n) =>
|
|
5435
|
+
return e.split(".").map((n) => Ci(n, t)).join(".");
|
|
5422
5436
|
}
|
|
5423
|
-
function
|
|
5437
|
+
function Pi(e, t) {
|
|
5424
5438
|
switch (t) {
|
|
5425
5439
|
case "toFixed2":
|
|
5426
5440
|
return Number(e).toFixed(2);
|
|
@@ -5437,11 +5451,11 @@ function Si(e, t) {
|
|
|
5437
5451
|
return e;
|
|
5438
5452
|
}
|
|
5439
5453
|
}
|
|
5440
|
-
function
|
|
5454
|
+
function Ti(e, t) {
|
|
5441
5455
|
const n = e instanceof Date ? e : new Date(e);
|
|
5442
5456
|
return Number.isNaN(n.getTime()) ? String(e) : n.toISOString();
|
|
5443
5457
|
}
|
|
5444
|
-
function
|
|
5458
|
+
function Fi(e, t, n) {
|
|
5445
5459
|
switch (t) {
|
|
5446
5460
|
case "number": {
|
|
5447
5461
|
if (n.numberEncoding === "number") {
|
|
@@ -5453,7 +5467,7 @@ function Pi(e, t, n) {
|
|
|
5453
5467
|
case "boolean":
|
|
5454
5468
|
return typeof e == "string" ? e.toLowerCase() === "true" : !!e;
|
|
5455
5469
|
case "date":
|
|
5456
|
-
return
|
|
5470
|
+
return Ti(e, n.dateFormat);
|
|
5457
5471
|
case "json":
|
|
5458
5472
|
return e;
|
|
5459
5473
|
case "string":
|
|
@@ -5461,30 +5475,30 @@ function Pi(e, t, n) {
|
|
|
5461
5475
|
return String(e);
|
|
5462
5476
|
}
|
|
5463
5477
|
}
|
|
5464
|
-
function
|
|
5478
|
+
function ot(e, t) {
|
|
5465
5479
|
if (t === "number") return e;
|
|
5466
5480
|
if (typeof e == "number") return String(e);
|
|
5467
|
-
if (Array.isArray(e)) return e.map((n) =>
|
|
5481
|
+
if (Array.isArray(e)) return e.map((n) => ot(n, t));
|
|
5468
5482
|
if (e && typeof e == "object") {
|
|
5469
5483
|
const n = {};
|
|
5470
|
-
for (const [a, r] of Object.entries(e)) n[a] =
|
|
5484
|
+
for (const [a, r] of Object.entries(e)) n[a] = ot(r, t);
|
|
5471
5485
|
return n;
|
|
5472
5486
|
}
|
|
5473
5487
|
return e;
|
|
5474
5488
|
}
|
|
5475
|
-
function
|
|
5489
|
+
function Ii(e, t) {
|
|
5476
5490
|
var n;
|
|
5477
5491
|
switch (e.kind) {
|
|
5478
5492
|
case "static":
|
|
5479
5493
|
return e.value;
|
|
5480
5494
|
case "input":
|
|
5481
|
-
return
|
|
5495
|
+
return ze(t.inputs, e.path);
|
|
5482
5496
|
case "output":
|
|
5483
|
-
return
|
|
5497
|
+
return ze(t.outputs, e.path);
|
|
5484
5498
|
case "setting":
|
|
5485
|
-
return
|
|
5499
|
+
return ze(t.settings, e.path);
|
|
5486
5500
|
case "context":
|
|
5487
|
-
return
|
|
5501
|
+
return ze(t.context, e.path);
|
|
5488
5502
|
case "token":
|
|
5489
5503
|
return (n = t.tokens) == null ? void 0 : n[e.name];
|
|
5490
5504
|
case "callback":
|
|
@@ -5493,10 +5507,10 @@ function Ti(e, t) {
|
|
|
5493
5507
|
return;
|
|
5494
5508
|
}
|
|
5495
5509
|
}
|
|
5496
|
-
function
|
|
5510
|
+
function Ri(e, t, n) {
|
|
5497
5511
|
const a = {};
|
|
5498
5512
|
for (const u of e) {
|
|
5499
|
-
let m =
|
|
5513
|
+
let m = Ii(u.source, n);
|
|
5500
5514
|
const d = m === "" || m == null;
|
|
5501
5515
|
if (u.omitWhenEmpty && d) continue;
|
|
5502
5516
|
const i = gn(u.key, t.keyCase);
|
|
@@ -5505,14 +5519,14 @@ function Fi(e, t, n) {
|
|
|
5505
5519
|
bn(a, i, null);
|
|
5506
5520
|
continue;
|
|
5507
5521
|
}
|
|
5508
|
-
u.transform && u.transform !== "none" && (m =
|
|
5522
|
+
u.transform && u.transform !== "none" && (m = Pi(m, u.transform)), bn(a, i, Fi(m, u.type, t));
|
|
5509
5523
|
}
|
|
5510
5524
|
const r = t.include, s = (u, m) => {
|
|
5511
|
-
m !== void 0 && (a[gn(u, t.keyCase)] =
|
|
5525
|
+
m !== void 0 && (a[gn(u, t.keyCase)] = ot(m, t.numberEncoding));
|
|
5512
5526
|
};
|
|
5513
5527
|
return r != null && r.inputs && s("inputs", n.inputs), r != null && r.outputs && s("outputs", n.outputs), r != null && r.schedule && s("schedule", n.schedule), r != null && r.settingsSnapshot && s("settingsSnapshot", n.settings), r != null && r.meta && s("meta", n.context), t.numberEncoding === "number" && console.warn('[fincalc] numberEncoding="number" reintroduces float error; prefer "string".'), t.mode === "wrapped" && t.wrapperKey ? { [t.wrapperKey]: a } : a;
|
|
5514
5528
|
}
|
|
5515
|
-
const
|
|
5529
|
+
const vs = {
|
|
5516
5530
|
mode: "flat",
|
|
5517
5531
|
keyCase: "asIs",
|
|
5518
5532
|
dateFormat: "iso",
|
|
@@ -5521,9 +5535,9 @@ const bs = {
|
|
|
5521
5535
|
include: { inputs: !0, outputs: !0, schedule: !1, settingsSnapshot: !0, meta: !0 }
|
|
5522
5536
|
};
|
|
5523
5537
|
function vn(e) {
|
|
5524
|
-
return
|
|
5538
|
+
return ot(e, "string");
|
|
5525
5539
|
}
|
|
5526
|
-
function
|
|
5540
|
+
function ks(e) {
|
|
5527
5541
|
const t = e.settings;
|
|
5528
5542
|
return {
|
|
5529
5543
|
schemaVersion: 1,
|
|
@@ -5557,17 +5571,17 @@ function gs(e) {
|
|
|
5557
5571
|
warnings: e.warnings ?? []
|
|
5558
5572
|
},
|
|
5559
5573
|
...e.attachments && e.attachments.length ? { attachments: e.attachments } : {},
|
|
5560
|
-
client: { tz: e.clientTz ??
|
|
5574
|
+
client: { tz: e.clientTz ?? Ei(), platform: "web" }
|
|
5561
5575
|
};
|
|
5562
5576
|
}
|
|
5563
|
-
function
|
|
5577
|
+
function Ei() {
|
|
5564
5578
|
try {
|
|
5565
5579
|
return Intl.DateTimeFormat().resolvedOptions().timeZone || "UTC";
|
|
5566
5580
|
} catch {
|
|
5567
5581
|
return "UTC";
|
|
5568
5582
|
}
|
|
5569
5583
|
}
|
|
5570
|
-
const He = ["save", "update", "get", "list", "delete", "upload", "uploadUrl", "rates", "settings"],
|
|
5584
|
+
const He = ["save", "update", "get", "list", "delete", "upload", "uploadUrl", "rates", "settings"], Mi = {
|
|
5571
5585
|
save: "POST",
|
|
5572
5586
|
update: "PUT",
|
|
5573
5587
|
get: "GET",
|
|
@@ -5577,7 +5591,7 @@ const He = ["save", "update", "get", "list", "delete", "upload", "uploadUrl", "r
|
|
|
5577
5591
|
uploadUrl: "GET",
|
|
5578
5592
|
rates: "GET",
|
|
5579
5593
|
settings: "GET"
|
|
5580
|
-
},
|
|
5594
|
+
}, ua = ["bearer", "apiKeyHeader", "basic", "custom"], $i = {
|
|
5581
5595
|
strategy: "multipart",
|
|
5582
5596
|
fieldName: "file",
|
|
5583
5597
|
maxBytes: 10 * 1024 * 1024,
|
|
@@ -5586,10 +5600,10 @@ const He = ["save", "update", "get", "list", "delete", "upload", "uploadUrl", "r
|
|
|
5586
5600
|
checksum: "none",
|
|
5587
5601
|
chunked: { enabled: !1, chunkBytes: 1024 * 1024 }
|
|
5588
5602
|
};
|
|
5589
|
-
function
|
|
5603
|
+
function da() {
|
|
5590
5604
|
const e = {};
|
|
5591
5605
|
for (const t of He)
|
|
5592
|
-
e[t] = { path: `/calculations${t === "save" || t === "list" ? "" : t === "get" || t === "update" || t === "delete" ? "/:id" : "/" + t}`, method:
|
|
5606
|
+
e[t] = { path: `/calculations${t === "save" || t === "list" ? "" : t === "get" || t === "update" || t === "delete" ? "/:id" : "/" + t}`, method: Mi[t], enabled: t === "save" || t === "list" };
|
|
5593
5607
|
return {
|
|
5594
5608
|
baseUrl: "https://api.example.com/v1",
|
|
5595
5609
|
auth: { strategy: "bearer", headerName: "Authorization" },
|
|
@@ -5597,17 +5611,17 @@ function ua() {
|
|
|
5597
5611
|
credentials: "same-origin",
|
|
5598
5612
|
retry: { attempts: 3, backoff: "exponential", baseDelayMs: 300, retryOn: [408, 429, 500, 502, 503, 504], respectRetryAfter: !0 },
|
|
5599
5613
|
endpoints: e,
|
|
5600
|
-
upload:
|
|
5614
|
+
upload: $i
|
|
5601
5615
|
};
|
|
5602
5616
|
}
|
|
5603
|
-
const
|
|
5617
|
+
const Ai = {
|
|
5604
5618
|
mode: "flat",
|
|
5605
5619
|
keyCase: "asIs",
|
|
5606
5620
|
dateFormat: "iso",
|
|
5607
5621
|
nullHandling: "omit",
|
|
5608
5622
|
numberEncoding: "string",
|
|
5609
5623
|
include: { inputs: !0, outputs: !0, schedule: !1, settingsSnapshot: !0, meta: !0 }
|
|
5610
|
-
},
|
|
5624
|
+
}, Di = [
|
|
5611
5625
|
{ key: "calculator", source: { kind: "context", path: "calculator" }, type: "string", required: !0, omitWhenEmpty: !1 },
|
|
5612
5626
|
{ key: "principal", source: { kind: "input", path: "principal" }, type: "number", required: !0, omitWhenEmpty: !1 },
|
|
5613
5627
|
{ key: "payment", source: { kind: "output", path: "payment" }, type: "number", required: !1, omitWhenEmpty: !1 },
|
|
@@ -5626,7 +5640,7 @@ function kn(e) {
|
|
|
5626
5640
|
n /= 1024, a++;
|
|
5627
5641
|
return `${n.toFixed(n < 10 ? 1 : 0)} ${t[a]}`;
|
|
5628
5642
|
}
|
|
5629
|
-
function
|
|
5643
|
+
function ma(e, t, n) {
|
|
5630
5644
|
switch (e) {
|
|
5631
5645
|
case "bearer":
|
|
5632
5646
|
return { Authorization: `Bearer ${n}` };
|
|
@@ -5644,9 +5658,9 @@ function da(e, t, n) {
|
|
|
5644
5658
|
function qe(e, t) {
|
|
5645
5659
|
return t ? /^https?:\/\//i.test(t) ? t : `${e.replace(/\/+$/, "")}/${t.replace(/^\/+/, "")}` : e;
|
|
5646
5660
|
}
|
|
5647
|
-
const
|
|
5648
|
-
function
|
|
5649
|
-
const { settings: n } = ue(), [a, r] = M("Connection"), [s, u] = M(
|
|
5661
|
+
const Li = ["Connection", "Endpoints", "Upload", "Payload", "Test", "cURL", "Queue"];
|
|
5662
|
+
function pa({ hostConfig: e, getToken: t } = {}) {
|
|
5663
|
+
const { settings: n } = ue(), [a, r] = M("Connection"), [s, u] = M(da), [m, d] = M(Ai), [i, c] = M(Di);
|
|
5650
5664
|
if (!n.features.integrationPanel)
|
|
5651
5665
|
return /* @__PURE__ */ o("section", { className: "card", "data-part": "integration-panel", children: /* @__PURE__ */ b("div", { className: "panel-head", children: [
|
|
5652
5666
|
/* @__PURE__ */ o("h2", { children: "Integration" }),
|
|
@@ -5668,12 +5682,12 @@ function ma({ hostConfig: e, getToken: t } = {}) {
|
|
|
5668
5682
|
/* @__PURE__ */ o("h2", { children: "Integration" }),
|
|
5669
5683
|
/* @__PURE__ */ o("p", { children: "Point the library at your backend without a code change. Nothing here stores a secret." })
|
|
5670
5684
|
] }),
|
|
5671
|
-
/* @__PURE__ */ o("div", { className: "tabs", role: "tablist", "aria-label": "Integration settings", children:
|
|
5685
|
+
/* @__PURE__ */ o("div", { className: "tabs", role: "tablist", "aria-label": "Integration settings", children: Li.map((f) => /* @__PURE__ */ o("button", { role: "tab", "aria-selected": a === f, onClick: () => r(f), children: f }, f)) }),
|
|
5672
5686
|
/* @__PURE__ */ b("div", { role: "tabpanel", "aria-label": a, children: [
|
|
5673
|
-
a === "Connection" && /* @__PURE__ */ o(
|
|
5674
|
-
a === "Endpoints" && /* @__PURE__ */ o(
|
|
5687
|
+
a === "Connection" && /* @__PURE__ */ o(Ui, { cfg: s, patch: p, hostLocked: l, getToken: t }),
|
|
5688
|
+
a === "Endpoints" && /* @__PURE__ */ o(Oi, { cfg: s, setCfg: u, locked: l("endpoints") }),
|
|
5675
5689
|
a === "Upload" && /* @__PURE__ */ o(
|
|
5676
|
-
|
|
5690
|
+
Bi,
|
|
5677
5691
|
{
|
|
5678
5692
|
upload: s.upload,
|
|
5679
5693
|
baseUrl: s.baseUrl,
|
|
@@ -5683,7 +5697,7 @@ function ma({ hostConfig: e, getToken: t } = {}) {
|
|
|
5683
5697
|
}
|
|
5684
5698
|
),
|
|
5685
5699
|
a === "Payload" && /* @__PURE__ */ o(
|
|
5686
|
-
|
|
5700
|
+
ji,
|
|
5687
5701
|
{
|
|
5688
5702
|
fields: i,
|
|
5689
5703
|
setFields: c,
|
|
@@ -5692,11 +5706,11 @@ function ma({ hostConfig: e, getToken: t } = {}) {
|
|
|
5692
5706
|
ctx: h
|
|
5693
5707
|
}
|
|
5694
5708
|
),
|
|
5695
|
-
a === "Test" && /* @__PURE__ */ o(
|
|
5696
|
-
a === "cURL" && /* @__PURE__ */ o(
|
|
5697
|
-
a === "Queue" && /* @__PURE__ */ o(
|
|
5709
|
+
a === "Test" && /* @__PURE__ */ o(Yi, { cfg: s, getToken: t }),
|
|
5710
|
+
a === "cURL" && /* @__PURE__ */ o(Ki, { cfg: s }),
|
|
5711
|
+
a === "Queue" && /* @__PURE__ */ o(Wi, { cfg: s, getToken: t })
|
|
5698
5712
|
] }),
|
|
5699
|
-
/* @__PURE__ */ o(
|
|
5713
|
+
/* @__PURE__ */ o(zi, { cfg: s, setCfg: u })
|
|
5700
5714
|
] });
|
|
5701
5715
|
}
|
|
5702
5716
|
function Fe({ on: e, children: t }) {
|
|
@@ -5747,13 +5761,13 @@ function le({
|
|
|
5747
5761
|
/* @__PURE__ */ o("div", { className: "input-wrap", children: /* @__PURE__ */ o("select", { value: t, onChange: (s) => a(s.target.value), "aria-label": e, children: r.map((s) => /* @__PURE__ */ o("option", { value: s.value, children: s.label }, s.value)) }) })
|
|
5748
5762
|
] });
|
|
5749
5763
|
}
|
|
5750
|
-
function
|
|
5764
|
+
function Ui({
|
|
5751
5765
|
cfg: e,
|
|
5752
5766
|
patch: t,
|
|
5753
5767
|
hostLocked: n,
|
|
5754
5768
|
getToken: a
|
|
5755
5769
|
}) {
|
|
5756
|
-
const r =
|
|
5770
|
+
const r = ua.includes(e.auth.strategy);
|
|
5757
5771
|
return /* @__PURE__ */ b("div", { className: "grid two", children: [
|
|
5758
5772
|
/* @__PURE__ */ o(Fe, { on: n("baseUrl"), children: /* @__PURE__ */ o(ne, { label: "Base URL", value: e.baseUrl, onChange: (s) => t({ baseUrl: s }), help: "Absolute origin + base path" }) }),
|
|
5759
5773
|
/* @__PURE__ */ o(
|
|
@@ -5806,7 +5820,7 @@ function Di({
|
|
|
5806
5820
|
)
|
|
5807
5821
|
] });
|
|
5808
5822
|
}
|
|
5809
|
-
function
|
|
5823
|
+
function Oi({ cfg: e, setCfg: t, locked: n }) {
|
|
5810
5824
|
const a = (r, s) => t((u) => ({ ...u, endpoints: { ...u.endpoints, [r]: { ...u.endpoints[r], ...s } } }));
|
|
5811
5825
|
return /* @__PURE__ */ o(Fe, { on: n, children: /* @__PURE__ */ o("div", { className: "int-table-wrap", children: /* @__PURE__ */ b("table", { className: "int-table", children: [
|
|
5812
5826
|
/* @__PURE__ */ o("thead", { children: /* @__PURE__ */ b("tr", { children: [
|
|
@@ -5829,10 +5843,10 @@ function Li({ cfg: e, setCfg: t, locked: n }) {
|
|
|
5829
5843
|
}) })
|
|
5830
5844
|
] }) }) });
|
|
5831
5845
|
}
|
|
5832
|
-
function
|
|
5846
|
+
function Bi({ upload: e, baseUrl: t, uploadUri: n, onChange: a, locked: r }) {
|
|
5833
5847
|
var m, d, i;
|
|
5834
5848
|
const s = (c) => a({ ...e, ...c }), u = X(
|
|
5835
|
-
() =>
|
|
5849
|
+
() => sa(e.filenameTemplate, { calculator: "loan.emi", kind: "pdf", inputsHash: Ue.inputsHash, filename: "x.pdf" }),
|
|
5836
5850
|
[e.filenameTemplate]
|
|
5837
5851
|
);
|
|
5838
5852
|
return /* @__PURE__ */ o(Fe, { on: r, children: /* @__PURE__ */ b("div", { className: "grid two", children: [
|
|
@@ -5884,14 +5898,14 @@ function Ui({ upload: e, baseUrl: t, uploadUri: n, onChange: a, locked: r }) {
|
|
|
5884
5898
|
] })
|
|
5885
5899
|
] }) });
|
|
5886
5900
|
}
|
|
5887
|
-
const
|
|
5888
|
-
function
|
|
5901
|
+
const _i = ["static", "input", "output", "setting", "context", "token", "callback"];
|
|
5902
|
+
function Hi(e) {
|
|
5889
5903
|
return e.kind === "static" ? String(e.value) : e.kind === "token" ? e.name : e.kind === "callback" ? "fn()" : e.path;
|
|
5890
5904
|
}
|
|
5891
|
-
function
|
|
5905
|
+
function qi(e, t) {
|
|
5892
5906
|
return e.kind === "static" ? { kind: "static", value: t } : e.kind === "token" ? { kind: "token", name: t } : e.kind === "callback" ? e : { kind: e.kind, path: t };
|
|
5893
5907
|
}
|
|
5894
|
-
function
|
|
5908
|
+
function Gi(e) {
|
|
5895
5909
|
switch (e) {
|
|
5896
5910
|
case "static":
|
|
5897
5911
|
return { kind: "static", value: "" };
|
|
@@ -5903,7 +5917,7 @@ function Hi(e) {
|
|
|
5903
5917
|
return { kind: e, path: "" };
|
|
5904
5918
|
}
|
|
5905
5919
|
}
|
|
5906
|
-
function
|
|
5920
|
+
function ji({
|
|
5907
5921
|
fields: e,
|
|
5908
5922
|
setFields: t,
|
|
5909
5923
|
envelope: n,
|
|
@@ -5912,7 +5926,7 @@ function qi({
|
|
|
5912
5926
|
}) {
|
|
5913
5927
|
const s = X(() => {
|
|
5914
5928
|
try {
|
|
5915
|
-
return JSON.stringify(
|
|
5929
|
+
return JSON.stringify(Ri(e, n, r), null, 2);
|
|
5916
5930
|
} catch (i) {
|
|
5917
5931
|
return `// ${i instanceof Error ? i.message : "preview failed"}`;
|
|
5918
5932
|
}
|
|
@@ -5953,13 +5967,13 @@ function qi({
|
|
|
5953
5967
|
] }) }),
|
|
5954
5968
|
/* @__PURE__ */ o("tbody", { children: e.map((i, c) => /* @__PURE__ */ b("tr", { children: [
|
|
5955
5969
|
/* @__PURE__ */ o("td", { children: /* @__PURE__ */ o("input", { value: i.key, onChange: (l) => u(c, { key: l.target.value }), "aria-label": "key", className: "int-cell-input" }) }),
|
|
5956
|
-
/* @__PURE__ */ o("td", { children: /* @__PURE__ */ o("select", { value: i.source.kind, onChange: (l) => u(c, { source:
|
|
5970
|
+
/* @__PURE__ */ o("td", { children: /* @__PURE__ */ o("select", { value: i.source.kind, onChange: (l) => u(c, { source: Gi(l.target.value) }), "aria-label": "source kind", children: _i.map((l) => /* @__PURE__ */ o("option", { children: l }, l)) }) }),
|
|
5957
5971
|
/* @__PURE__ */ o("td", { children: /* @__PURE__ */ o(
|
|
5958
5972
|
"input",
|
|
5959
5973
|
{
|
|
5960
|
-
value:
|
|
5974
|
+
value: Hi(i.source),
|
|
5961
5975
|
disabled: i.source.kind === "callback",
|
|
5962
|
-
onChange: (l) => u(c, { source:
|
|
5976
|
+
onChange: (l) => u(c, { source: qi(i.source, l.target.value) }),
|
|
5963
5977
|
"aria-label": "source value",
|
|
5964
5978
|
className: "int-cell-input"
|
|
5965
5979
|
}
|
|
@@ -5990,7 +6004,7 @@ function qi({
|
|
|
5990
6004
|
] })
|
|
5991
6005
|
] });
|
|
5992
6006
|
}
|
|
5993
|
-
function
|
|
6007
|
+
function Vi(e, t) {
|
|
5994
6008
|
const n = {};
|
|
5995
6009
|
for (const a of He) {
|
|
5996
6010
|
const r = e.endpoints[a];
|
|
@@ -6004,10 +6018,10 @@ function Gi(e, t) {
|
|
|
6004
6018
|
retry: e.retry,
|
|
6005
6019
|
upload: e.upload,
|
|
6006
6020
|
offlineQueue: { enabled: !0, storage: "memory", maxItems: 200, flushOn: "manual" },
|
|
6007
|
-
getAuth: t ? async () =>
|
|
6021
|
+
getAuth: t ? async () => ma(e.auth.strategy, e.auth.headerName, await t()) : void 0
|
|
6008
6022
|
};
|
|
6009
6023
|
}
|
|
6010
|
-
function
|
|
6024
|
+
function Yi({ cfg: e, getToken: t }) {
|
|
6011
6025
|
const [n, a] = M({ loading: !1 }), [r, s] = M("save");
|
|
6012
6026
|
return /* @__PURE__ */ b("div", { children: [
|
|
6013
6027
|
/* @__PURE__ */ b("div", { className: "grid two", children: [
|
|
@@ -6015,11 +6029,11 @@ function ji({ cfg: e, getToken: t }) {
|
|
|
6015
6029
|
/* @__PURE__ */ o("div", { className: "field", style: { display: "flex", alignItems: "flex-end" }, children: /* @__PURE__ */ o("button", { type: "button", className: "icon-btn", onClick: async () => {
|
|
6016
6030
|
a({ loading: !0 });
|
|
6017
6031
|
const m = e.endpoints[r], d = qe(e.baseUrl, m.path).replace(/:id\b/, "sample-id"), i = { "content-type": "application/json", "X-FinCalc-Test": "1" };
|
|
6018
|
-
t && Object.assign(i,
|
|
6032
|
+
t && Object.assign(i, ma(e.auth.strategy, e.auth.headerName, await t()));
|
|
6019
6033
|
const c = performance.now();
|
|
6020
6034
|
try {
|
|
6021
6035
|
const l = await fetch(d, { method: m.method, headers: i, credentials: e.credentials }), p = await l.text(), h = {};
|
|
6022
|
-
l.headers.forEach((f, y) => h[y] = f), a({ loading: !1, ok: l.ok, status: l.status, ms: Math.round(performance.now() - c), headers: h, body:
|
|
6036
|
+
l.headers.forEach((f, y) => h[y] = f), a({ loading: !1, ok: l.ok, status: l.status, ms: Math.round(performance.now() - c), headers: h, body: Ji(p), sent: { url: d, method: m.method, headers: $t(i) } });
|
|
6023
6037
|
} catch (l) {
|
|
6024
6038
|
a({ loading: !1, ok: !1, ms: Math.round(performance.now() - c), error: l instanceof Error ? l.message : "request failed", sent: { url: d, method: m.method, headers: $t(i) } });
|
|
6025
6039
|
}
|
|
@@ -6049,9 +6063,9 @@ ${JSON.stringify(n.sent.headers, null, 2)}` })
|
|
|
6049
6063
|
] })
|
|
6050
6064
|
] });
|
|
6051
6065
|
}
|
|
6052
|
-
function
|
|
6066
|
+
function Ki({ cfg: e }) {
|
|
6053
6067
|
const [t, n] = M(!1), [a, r] = M("save"), s = e.endpoints[a], u = qe(e.baseUrl, s.path).replace(/:id\b/, "sample-id"), m = { "content-type": "application/json" };
|
|
6054
|
-
|
|
6068
|
+
ua.includes(e.auth.strategy) && (m[e.auth.strategy === "apiKeyHeader" || e.auth.strategy === "custom" ? e.auth.headerName || "X-API-Key" : "Authorization"] = t ? "<token>" : "***");
|
|
6055
6069
|
const d = [`curl -X ${s.method} '${u}'`];
|
|
6056
6070
|
for (const [c, l] of Object.entries(m)) d.push(` -H '${c}: ${l}'`);
|
|
6057
6071
|
["POST", "PUT", "PATCH"].includes(s.method) && d.push(` -d '{"example":"body"}'`);
|
|
@@ -6072,8 +6086,8 @@ function Vi({ cfg: e }) {
|
|
|
6072
6086
|
}, children: "Copy" })
|
|
6073
6087
|
] });
|
|
6074
6088
|
}
|
|
6075
|
-
function
|
|
6076
|
-
const n = X(() =>
|
|
6089
|
+
function Wi({ cfg: e, getToken: t }) {
|
|
6090
|
+
const n = X(() => gi(Vi(e, t)), [e, t]), [a, r] = M(() => n.queue.list()), [s, u] = M(""), m = () => r(n.queue.list());
|
|
6077
6091
|
return /* @__PURE__ */ b("div", { children: [
|
|
6078
6092
|
/* @__PURE__ */ b("div", { className: "actions-row", style: { marginTop: 0 }, children: [
|
|
6079
6093
|
/* @__PURE__ */ o("button", { type: "button", className: "icon-btn", onClick: m, children: "Refresh" }),
|
|
@@ -6102,7 +6116,7 @@ function Yi({ cfg: e, getToken: t }) {
|
|
|
6102
6116
|
] }) })
|
|
6103
6117
|
] });
|
|
6104
6118
|
}
|
|
6105
|
-
function
|
|
6119
|
+
function zi({ cfg: e, setCfg: t }) {
|
|
6106
6120
|
const [n, a] = M(""), [r, s] = M("");
|
|
6107
6121
|
return /* @__PURE__ */ b("div", { className: "accordion", style: { marginTop: 20 }, children: [
|
|
6108
6122
|
/* @__PURE__ */ o("span", { className: "lbl", children: "Import / export config (JSON)" }),
|
|
@@ -6116,7 +6130,7 @@ function Ki({ cfg: e, setCfg: t }) {
|
|
|
6116
6130
|
const d = JSON.parse(n);
|
|
6117
6131
|
for (const i of ["token", "apiKey", "getAuth", "authorization"])
|
|
6118
6132
|
i in d && (delete d[i], s(`Refused to import "${i}" — the panel never persists a secret.`));
|
|
6119
|
-
t(() => ({ ...
|
|
6133
|
+
t(() => ({ ...da(), ...d })), r || s("Imported.");
|
|
6120
6134
|
} catch {
|
|
6121
6135
|
s("Invalid JSON.");
|
|
6122
6136
|
}
|
|
@@ -6125,16 +6139,16 @@ function Ki({ cfg: e, setCfg: t }) {
|
|
|
6125
6139
|
r && /* @__PURE__ */ o("div", { className: "int-note", children: r })
|
|
6126
6140
|
] });
|
|
6127
6141
|
}
|
|
6128
|
-
function
|
|
6142
|
+
function Ji(e) {
|
|
6129
6143
|
try {
|
|
6130
6144
|
return JSON.stringify(JSON.parse(e), null, 2);
|
|
6131
6145
|
} catch {
|
|
6132
6146
|
return e;
|
|
6133
6147
|
}
|
|
6134
6148
|
}
|
|
6135
|
-
const
|
|
6136
|
-
function
|
|
6137
|
-
const { settings: e, update: t, setRegion: n, reset: a, replace: r } = ue(), s = de(null), u = Sn(e).money(g(
|
|
6149
|
+
const Zi = "1234567.891";
|
|
6150
|
+
function Xi() {
|
|
6151
|
+
const { settings: e, update: t, setRegion: n, reset: a, replace: r } = ue(), s = de(null), u = Sn(e).money(g(Zi)), m = () => {
|
|
6138
6152
|
const i = new Blob([JSON.stringify(e, null, 2)], { type: "application/json" }), c = URL.createObjectURL(i), l = document.createElement("a");
|
|
6139
6153
|
l.href = c, l.download = "calcsuite-settings.json", l.click(), URL.revokeObjectURL(c);
|
|
6140
6154
|
}, d = (i) => {
|
|
@@ -6225,7 +6239,7 @@ function Ji() {
|
|
|
6225
6239
|
options: [["system", "System"], ["light", "Light"], ["dark", "Dark"], ["highContrast", "High contrast"]]
|
|
6226
6240
|
}
|
|
6227
6241
|
) }),
|
|
6228
|
-
/* @__PURE__ */ o(W, { label: "Accent colour", children: /* @__PURE__ */ o("div", { className: "swatches", children:
|
|
6242
|
+
/* @__PURE__ */ o(W, { label: "Accent colour", children: /* @__PURE__ */ o("div", { className: "swatches", children: Cn.map((i) => {
|
|
6229
6243
|
const c = e.ui.accent.toLowerCase() === i.main.toLowerCase();
|
|
6230
6244
|
return /* @__PURE__ */ o(
|
|
6231
6245
|
"button",
|
|
@@ -6246,7 +6260,7 @@ function Ji() {
|
|
|
6246
6260
|
{
|
|
6247
6261
|
value: e.ui.fontFamily,
|
|
6248
6262
|
onChange: (i) => t({ ui: { fontFamily: i } }),
|
|
6249
|
-
options:
|
|
6263
|
+
options: Pn.map((i) => [i.id, i.label])
|
|
6250
6264
|
}
|
|
6251
6265
|
) }),
|
|
6252
6266
|
/* @__PURE__ */ o(W, { label: "Density", children: /* @__PURE__ */ o(
|
|
@@ -6269,7 +6283,7 @@ function Ji() {
|
|
|
6269
6283
|
" — so exports (PDF/CSV/…) and saved calculations post directly to your own server. No secret is ever stored by the app."
|
|
6270
6284
|
] })
|
|
6271
6285
|
] }),
|
|
6272
|
-
e.features.integrationPanel && /* @__PURE__ */ o(
|
|
6286
|
+
e.features.integrationPanel && /* @__PURE__ */ o(pa, {}),
|
|
6273
6287
|
/* @__PURE__ */ b("div", { className: "actions-row", children: [
|
|
6274
6288
|
/* @__PURE__ */ o("button", { className: "icon-btn", onClick: m, children: "Export settings" }),
|
|
6275
6289
|
/* @__PURE__ */ o("button", { className: "icon-btn", onClick: () => {
|
|
@@ -6302,7 +6316,7 @@ function he({ value: e, onChange: t, options: n }) {
|
|
|
6302
6316
|
function Le({ on: e, onClick: t }) {
|
|
6303
6317
|
return /* @__PURE__ */ o("button", { type: "button", role: "switch", "aria-checked": e, className: `toggle ${e ? "on" : ""}`, onClick: t, children: /* @__PURE__ */ o("span", { className: "knob" }) });
|
|
6304
6318
|
}
|
|
6305
|
-
function
|
|
6319
|
+
function Qi({
|
|
6306
6320
|
items: e,
|
|
6307
6321
|
onRestore: t,
|
|
6308
6322
|
onClear: n
|
|
@@ -6331,7 +6345,7 @@ function wn(e, t) {
|
|
|
6331
6345
|
for (let s = 0; s < n.length && r < e.length; s++) n[s] === e[r] && r++;
|
|
6332
6346
|
return r === e.length ? 10 : -1;
|
|
6333
6347
|
}
|
|
6334
|
-
function
|
|
6348
|
+
function es({
|
|
6335
6349
|
calculators: e,
|
|
6336
6350
|
actions: t,
|
|
6337
6351
|
onPick: n,
|
|
@@ -6341,7 +6355,7 @@ function Xi({
|
|
|
6341
6355
|
Q(() => {
|
|
6342
6356
|
var l;
|
|
6343
6357
|
return (l = d.current) == null ? void 0 : l.focus();
|
|
6344
|
-
}, []), Q(() => (
|
|
6358
|
+
}, []), Q(() => (Pa(), () => Ta()), []);
|
|
6345
6359
|
const i = X(() => {
|
|
6346
6360
|
const l = e.map((y) => ({
|
|
6347
6361
|
key: `calc:${y.id}`,
|
|
@@ -6391,7 +6405,7 @@ function Xi({
|
|
|
6391
6405
|
] })
|
|
6392
6406
|
] }) });
|
|
6393
6407
|
}
|
|
6394
|
-
const
|
|
6408
|
+
const Ge = (e) => ({
|
|
6395
6409
|
width: e,
|
|
6396
6410
|
height: e,
|
|
6397
6411
|
viewBox: "0 0 24 24",
|
|
@@ -6402,31 +6416,44 @@ const dt = (e) => ({
|
|
|
6402
6416
|
strokeLinejoin: "round",
|
|
6403
6417
|
"aria-hidden": !0
|
|
6404
6418
|
});
|
|
6405
|
-
function
|
|
6406
|
-
return /* @__PURE__ */ b("svg", { ...
|
|
6419
|
+
function ts({ size: e = 17 }) {
|
|
6420
|
+
return /* @__PURE__ */ b("svg", { ...Ge(e), children: [
|
|
6407
6421
|
/* @__PURE__ */ o("circle", { cx: "12", cy: "12", r: "3" }),
|
|
6408
6422
|
/* @__PURE__ */ o("path", { d: "M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1Z" })
|
|
6409
6423
|
] });
|
|
6410
6424
|
}
|
|
6411
|
-
function
|
|
6412
|
-
return /* @__PURE__ */ b("svg", { ...
|
|
6425
|
+
function ns({ size: e = 17 }) {
|
|
6426
|
+
return /* @__PURE__ */ b("svg", { ...Ge(e), children: [
|
|
6413
6427
|
/* @__PURE__ */ o("circle", { cx: "12", cy: "12", r: "4" }),
|
|
6414
6428
|
/* @__PURE__ */ o("path", { d: "M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41" })
|
|
6415
6429
|
] });
|
|
6416
6430
|
}
|
|
6417
|
-
function
|
|
6418
|
-
return /* @__PURE__ */ o("svg", { ...
|
|
6431
|
+
function as({ size: e = 17 }) {
|
|
6432
|
+
return /* @__PURE__ */ o("svg", { ...Ge(e), children: /* @__PURE__ */ o("path", { d: "M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z" }) });
|
|
6433
|
+
}
|
|
6434
|
+
function ha({ size: e = 17 }) {
|
|
6435
|
+
return /* @__PURE__ */ b("svg", { ...Ge(e), children: [
|
|
6436
|
+
/* @__PURE__ */ o("rect", { x: "4", y: "2", width: "16", height: "20", rx: "2" }),
|
|
6437
|
+
/* @__PURE__ */ o("line", { x1: "8", y1: "6", x2: "16", y2: "6" }),
|
|
6438
|
+
/* @__PURE__ */ o("line", { x1: "8", y1: "10", x2: "8", y2: "10" }),
|
|
6439
|
+
/* @__PURE__ */ o("line", { x1: "12", y1: "10", x2: "12", y2: "10" }),
|
|
6440
|
+
/* @__PURE__ */ o("line", { x1: "16", y1: "10", x2: "16", y2: "10" }),
|
|
6441
|
+
/* @__PURE__ */ o("line", { x1: "8", y1: "14", x2: "8", y2: "14" }),
|
|
6442
|
+
/* @__PURE__ */ o("line", { x1: "12", y1: "14", x2: "12", y2: "14" }),
|
|
6443
|
+
/* @__PURE__ */ o("line", { x1: "16", y1: "14", x2: "16", y2: "14" }),
|
|
6444
|
+
/* @__PURE__ */ o("line", { x1: "8", y1: "18", x2: "12", y2: "18" })
|
|
6445
|
+
] });
|
|
6419
6446
|
}
|
|
6420
|
-
function
|
|
6421
|
-
return /* @__PURE__ */ b("svg", { ...
|
|
6447
|
+
function rs({ size: e = 17 }) {
|
|
6448
|
+
return /* @__PURE__ */ b("svg", { ...Ge(e), children: [
|
|
6422
6449
|
/* @__PURE__ */ o("path", { d: "M3 3v5h5" }),
|
|
6423
6450
|
/* @__PURE__ */ o("path", { d: "M3.05 13A9 9 0 1 0 6 5.3L3 8" }),
|
|
6424
6451
|
/* @__PURE__ */ o("path", { d: "M12 7v5l4 2" })
|
|
6425
6452
|
] });
|
|
6426
6453
|
}
|
|
6427
|
-
const
|
|
6428
|
-
function
|
|
6429
|
-
const { settings: t, setRegion: n, update: a, resolvedTheme: r } = ue(), s = t.region, u = X(() =>
|
|
6454
|
+
const os = { "loan.emi": Jn, scientific: Xn, currency: oa };
|
|
6455
|
+
function is({ onClose: e }) {
|
|
6456
|
+
const { settings: t, setRegion: n, update: a, resolvedTheme: r } = ue(), s = t.region, u = X(() => Xr(s), [s]), [m, d] = M("loan.emi"), [i, c] = M("calc"), [l, p] = M(void 0), [h, f] = M(!1), { items: y, clear: w } = Uo();
|
|
6430
6457
|
Q(() => {
|
|
6431
6458
|
const x = () => {
|
|
6432
6459
|
const T = new URLSearchParams(location.hash.replace(/^#/, "") || location.search), $ = T.get("fincalc");
|
|
@@ -6469,8 +6496,11 @@ function rs({ onClose: e }) {
|
|
|
6469
6496
|
return /* @__PURE__ */ b("div", { className: "fc-shell", onKeyDown: k, children: [
|
|
6470
6497
|
/* @__PURE__ */ b("header", { className: "fc-topbar", children: [
|
|
6471
6498
|
/* @__PURE__ */ b("div", { className: "brand fc-brand", children: [
|
|
6472
|
-
/* @__PURE__ */ o("
|
|
6473
|
-
/* @__PURE__ */
|
|
6499
|
+
/* @__PURE__ */ o("span", { className: "fc-brand-mark", "aria-hidden": "true", children: /* @__PURE__ */ o(ha, { size: 22 }) }),
|
|
6500
|
+
/* @__PURE__ */ b("div", { className: "fc-brand-text", children: [
|
|
6501
|
+
/* @__PURE__ */ o("strong", { children: "CalcSuite" }),
|
|
6502
|
+
/* @__PURE__ */ o("a", { className: "fc-brand-sub", href: "https://acecbm.com", target: "_blank", rel: "noopener noreferrer", children: "an AceCBM product ↗" })
|
|
6503
|
+
] })
|
|
6474
6504
|
] }),
|
|
6475
6505
|
/* @__PURE__ */ b("div", { className: "fc-top-actions", children: [
|
|
6476
6506
|
/* @__PURE__ */ o("button", { className: "icon-btn", onClick: () => f(!0), "aria-label": "Search", children: "⌘K Search" }),
|
|
@@ -6478,17 +6508,17 @@ function rs({ onClose: e }) {
|
|
|
6478
6508
|
/* @__PURE__ */ o("button", { "aria-pressed": s === "IN", onClick: () => n("IN"), children: "🇮🇳" }),
|
|
6479
6509
|
/* @__PURE__ */ o("button", { "aria-pressed": s === "US", onClick: () => n("US"), children: "🇺🇸" })
|
|
6480
6510
|
] }),
|
|
6481
|
-
/* @__PURE__ */ o("button", { className: "icon-btn icon-only", onClick: () => a({ ui: { theme: r === "dark" ? "light" : "dark" } }), "aria-label": r === "dark" ? "Switch to light mode" : "Switch to dark mode", children: r === "dark" ? /* @__PURE__ */ o(
|
|
6511
|
+
/* @__PURE__ */ o("button", { className: "icon-btn icon-only", onClick: () => a({ ui: { theme: r === "dark" ? "light" : "dark" } }), "aria-label": r === "dark" ? "Switch to light mode" : "Switch to dark mode", children: r === "dark" ? /* @__PURE__ */ o(ns, {}) : /* @__PURE__ */ o(as, {}) }),
|
|
6482
6512
|
/* @__PURE__ */ b("button", { className: "icon-btn", "aria-label": "History", onClick: () => c("history"), children: [
|
|
6483
|
-
/* @__PURE__ */ o(
|
|
6513
|
+
/* @__PURE__ */ o(rs, {}),
|
|
6484
6514
|
" History"
|
|
6485
6515
|
] }),
|
|
6486
|
-
/* @__PURE__ */ o("button", { className: "icon-btn icon-only", "aria-label": "Settings", onClick: () => c("settings"), children: /* @__PURE__ */ o(
|
|
6516
|
+
/* @__PURE__ */ o("button", { className: "icon-btn icon-only", "aria-label": "Settings", onClick: () => c("settings"), children: /* @__PURE__ */ o(ts, {}) }),
|
|
6487
6517
|
e && /* @__PURE__ */ o("button", { className: "icon-btn icon-only", "aria-label": "Close", onClick: e, children: "✕" })
|
|
6488
6518
|
] })
|
|
6489
6519
|
] }),
|
|
6490
6520
|
/* @__PURE__ */ b("div", { className: "fc-body", children: [
|
|
6491
|
-
/* @__PURE__ */ o("nav", { className: "fc-rail", "aria-label": "Calculators", children:
|
|
6521
|
+
/* @__PURE__ */ o("nav", { className: "fc-rail", "aria-label": "Calculators", children: Qr.map((x) => {
|
|
6492
6522
|
const T = u.filter(($) => $.group === x.id);
|
|
6493
6523
|
return T.length === 0 ? null : /* @__PURE__ */ b("div", { className: "rail-group", children: [
|
|
6494
6524
|
/* @__PURE__ */ o("div", { className: "rail-group-label", children: x.label }),
|
|
@@ -6504,24 +6534,24 @@ function rs({ onClose: e }) {
|
|
|
6504
6534
|
] }, x.id);
|
|
6505
6535
|
}) }),
|
|
6506
6536
|
/* @__PURE__ */ o("main", { className: "fc-main", children: /* @__PURE__ */ b("div", { className: "fc-anim-in", children: [
|
|
6507
|
-
i === "settings" && /* @__PURE__ */ o(
|
|
6508
|
-
i === "history" && /* @__PURE__ */ o(
|
|
6509
|
-
i === "integration" && /* @__PURE__ */ o(
|
|
6537
|
+
i === "settings" && /* @__PURE__ */ o(Xi, {}),
|
|
6538
|
+
i === "history" && /* @__PURE__ */ o(Qi, { items: y, onRestore: P, onClear: w }),
|
|
6539
|
+
i === "integration" && /* @__PURE__ */ o(pa, {}),
|
|
6510
6540
|
i === "calc" && /* @__PURE__ */ o(
|
|
6511
|
-
|
|
6541
|
+
di,
|
|
6512
6542
|
{
|
|
6513
6543
|
def: F,
|
|
6514
6544
|
seed: l,
|
|
6515
|
-
customRegistry:
|
|
6545
|
+
customRegistry: os,
|
|
6516
6546
|
actions: (x, T) => x ? /* @__PURE__ */ b(re, { children: [
|
|
6517
6547
|
/* @__PURE__ */ o(
|
|
6518
|
-
|
|
6548
|
+
zn,
|
|
6519
6549
|
{
|
|
6520
6550
|
item: { id: F.id, title: `${F.title} — ${x.primary.value}`, primary: x.primary.value, values: T }
|
|
6521
6551
|
}
|
|
6522
6552
|
),
|
|
6523
6553
|
/* @__PURE__ */ o(
|
|
6524
|
-
|
|
6554
|
+
Vn,
|
|
6525
6555
|
{
|
|
6526
6556
|
payload: {
|
|
6527
6557
|
calculatorId: F.id,
|
|
@@ -6538,37 +6568,11 @@ function rs({ onClose: e }) {
|
|
|
6538
6568
|
)
|
|
6539
6569
|
] }, i === "calc" ? `calc:${F.id}` : i) })
|
|
6540
6570
|
] }),
|
|
6541
|
-
h && /* @__PURE__ */ o(
|
|
6571
|
+
h && /* @__PURE__ */ o(es, { calculators: u, actions: N, onPick: S, onClose: () => f(!1) })
|
|
6542
6572
|
] });
|
|
6543
6573
|
}
|
|
6544
|
-
|
|
6545
|
-
|
|
6546
|
-
"svg",
|
|
6547
|
-
{
|
|
6548
|
-
width: e,
|
|
6549
|
-
height: e,
|
|
6550
|
-
viewBox: "0 0 24 24",
|
|
6551
|
-
fill: "none",
|
|
6552
|
-
stroke: "currentColor",
|
|
6553
|
-
strokeWidth: 2,
|
|
6554
|
-
strokeLinecap: "round",
|
|
6555
|
-
strokeLinejoin: "round",
|
|
6556
|
-
"aria-hidden": "true",
|
|
6557
|
-
children: [
|
|
6558
|
-
/* @__PURE__ */ o("rect", { x: "4", y: "2", width: "16", height: "20", rx: "2" }),
|
|
6559
|
-
/* @__PURE__ */ o("line", { x1: "8", y1: "6", x2: "16", y2: "6" }),
|
|
6560
|
-
/* @__PURE__ */ o("line", { x1: "8", y1: "10", x2: "8", y2: "10" }),
|
|
6561
|
-
/* @__PURE__ */ o("line", { x1: "12", y1: "10", x2: "12", y2: "10" }),
|
|
6562
|
-
/* @__PURE__ */ o("line", { x1: "16", y1: "10", x2: "16", y2: "10" }),
|
|
6563
|
-
/* @__PURE__ */ o("line", { x1: "8", y1: "14", x2: "8", y2: "14" }),
|
|
6564
|
-
/* @__PURE__ */ o("line", { x1: "12", y1: "14", x2: "12", y2: "14" }),
|
|
6565
|
-
/* @__PURE__ */ o("line", { x1: "16", y1: "14", x2: "16", y2: "14" }),
|
|
6566
|
-
/* @__PURE__ */ o("line", { x1: "8", y1: "18", x2: "12", y2: "18" })
|
|
6567
|
-
]
|
|
6568
|
-
}
|
|
6569
|
-
);
|
|
6570
|
-
}
|
|
6571
|
-
function vs({
|
|
6574
|
+
const Nn = ({ size: e = 22 }) => /* @__PURE__ */ o(ha, { size: e });
|
|
6575
|
+
function ws({
|
|
6572
6576
|
variant: e = "fab",
|
|
6573
6577
|
position: t = "bottom-right",
|
|
6574
6578
|
hotkey: n = "mod+shift+k",
|
|
@@ -6605,12 +6609,12 @@ function vs({
|
|
|
6605
6609
|
/* @__PURE__ */ o("span", { "aria-hidden": !0, style: { marginRight: 6, display: "inline-flex", alignItems: "center" }, children: m ?? /* @__PURE__ */ o(Nn, { size: 16 }) }),
|
|
6606
6610
|
u
|
|
6607
6611
|
] }),
|
|
6608
|
-
/* @__PURE__ */ o(
|
|
6612
|
+
/* @__PURE__ */ o(Ra, { open: k, onClose: F.close, title: h, size: p, children: /* @__PURE__ */ o(is, { onClose: F.close }) })
|
|
6609
6613
|
] });
|
|
6610
6614
|
}
|
|
6611
|
-
const
|
|
6612
|
-
function
|
|
6613
|
-
const n = t.ttlMs ??
|
|
6615
|
+
const ss = 60 * 60 * 1e3, Nt = (e, t) => `${e}|${[...t].sort().join(",")}`;
|
|
6616
|
+
function Ns(e, t = {}) {
|
|
6617
|
+
const n = t.ttlMs ?? ss, a = t.now ?? Date.now, r = /* @__PURE__ */ new Map();
|
|
6614
6618
|
let s = null;
|
|
6615
6619
|
function u(i) {
|
|
6616
6620
|
var l;
|
|
@@ -6656,71 +6660,71 @@ function ks(e, t = {}) {
|
|
|
6656
6660
|
clear: () => r.clear()
|
|
6657
6661
|
};
|
|
6658
6662
|
}
|
|
6659
|
-
const
|
|
6663
|
+
const xs = { solve: Ie, REGIONS: me };
|
|
6660
6664
|
export {
|
|
6661
|
-
|
|
6662
|
-
|
|
6663
|
-
|
|
6664
|
-
|
|
6665
|
+
di as CalculatorPanel,
|
|
6666
|
+
lo as Chart,
|
|
6667
|
+
es as CommandPalette,
|
|
6668
|
+
oa as CurrencyConverter,
|
|
6665
6669
|
g as D,
|
|
6666
|
-
|
|
6667
|
-
|
|
6670
|
+
vs as DEFAULT_ENVELOPE,
|
|
6671
|
+
Qe as DEFAULT_SETTINGS,
|
|
6668
6672
|
H as Decimal,
|
|
6669
|
-
|
|
6670
|
-
|
|
6671
|
-
|
|
6672
|
-
|
|
6673
|
-
|
|
6673
|
+
Ra as Dialog,
|
|
6674
|
+
co as EXPORT_FORMATS,
|
|
6675
|
+
Vn as ExportMenu,
|
|
6676
|
+
to as Field,
|
|
6677
|
+
Ra as FinCalcDialog,
|
|
6674
6678
|
se as FinCalcError,
|
|
6675
|
-
|
|
6676
|
-
|
|
6677
|
-
|
|
6678
|
-
|
|
6679
|
-
|
|
6680
|
-
|
|
6681
|
-
|
|
6682
|
-
|
|
6683
|
-
|
|
6684
|
-
|
|
6685
|
-
|
|
6686
|
-
|
|
6687
|
-
|
|
6688
|
-
|
|
6689
|
-
|
|
6690
|
-
|
|
6691
|
-
|
|
6679
|
+
ws as FinCalcLauncher,
|
|
6680
|
+
fs as FinCalcProvider,
|
|
6681
|
+
is as FinCalcRoot,
|
|
6682
|
+
Qr as GROUPS,
|
|
6683
|
+
Qi as HistoryPanel,
|
|
6684
|
+
pa as IntegrationPanel,
|
|
6685
|
+
ws as Launcher,
|
|
6686
|
+
Jn as LoanEmiPanel,
|
|
6687
|
+
ka as POLICY_DEFAULT,
|
|
6688
|
+
ro as ResultCard,
|
|
6689
|
+
zn as SaveButton,
|
|
6690
|
+
so as ScheduleTable,
|
|
6691
|
+
Xn as SciCalculator,
|
|
6692
|
+
Xi as SettingsPanel,
|
|
6693
|
+
fs as SettingsProvider,
|
|
6694
|
+
is as Shell,
|
|
6695
|
+
Un as allCalculators,
|
|
6692
6696
|
ye as boolval,
|
|
6693
|
-
|
|
6694
|
-
|
|
6695
|
-
|
|
6697
|
+
sa as buildFilename,
|
|
6698
|
+
Ri as buildPayload,
|
|
6699
|
+
ks as buildSavePayload,
|
|
6696
6700
|
Rt as calculatorById,
|
|
6697
|
-
|
|
6698
|
-
|
|
6699
|
-
|
|
6700
|
-
|
|
6701
|
-
|
|
6702
|
-
|
|
6701
|
+
Xr as calculatorsForRegion,
|
|
6702
|
+
Lo as clearHistory,
|
|
6703
|
+
Mo as createExporter,
|
|
6704
|
+
Ns as createFxCache,
|
|
6705
|
+
gi as createTransport,
|
|
6706
|
+
gs as currency,
|
|
6703
6707
|
D as dmoney,
|
|
6704
|
-
|
|
6708
|
+
ms as eq,
|
|
6705
6709
|
on as evalExpression,
|
|
6706
|
-
|
|
6707
|
-
|
|
6708
|
-
|
|
6709
|
-
|
|
6710
|
+
ni as evaluateExpression,
|
|
6711
|
+
ii as fetchLiveRate,
|
|
6712
|
+
ys as finance,
|
|
6713
|
+
ps as gt,
|
|
6710
6714
|
ce as isZeroish,
|
|
6711
|
-
|
|
6712
|
-
|
|
6715
|
+
xs as loan,
|
|
6716
|
+
hs as lt,
|
|
6713
6717
|
Sn as makeFormatter,
|
|
6714
6718
|
v as metric,
|
|
6715
6719
|
C as numval,
|
|
6716
|
-
|
|
6720
|
+
Jo as parseExpression,
|
|
6717
6721
|
xt as regionDefaults,
|
|
6718
|
-
|
|
6719
|
-
|
|
6720
|
-
|
|
6722
|
+
bs as registerCalculator,
|
|
6723
|
+
yi as sanitizeFilename,
|
|
6724
|
+
Wn as saveHistory,
|
|
6721
6725
|
Ie as solveLoan,
|
|
6722
6726
|
_ as strval,
|
|
6723
6727
|
ue as useFinCalc,
|
|
6724
|
-
|
|
6728
|
+
Uo as useHistory,
|
|
6725
6729
|
ue as useSettings
|
|
6726
6730
|
};
|