@burdenoff/microfe-hookmovies 2026.706.2 → 2026.706.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/dist/hookmovies/HookMoviesRoutes.js +54 -6
- package/dist/hookmovies/HookMoviesRoutes.js.map +1 -1
- package/dist/hookmovies/components/index.js +1 -1
- package/dist/hookmovies/context/HookMoviesContext.js +64 -40
- package/dist/hookmovies/context/HookMoviesContext.js.map +1 -1
- package/dist/hookmovies/hooks/useHookMoviesApi.js +592 -134
- package/dist/hookmovies/hooks/useHookMoviesApi.js.map +1 -1
- package/dist/hookmovies/pages/HomePage.js +211 -139
- package/dist/hookmovies/pages/HomePage.js.map +1 -1
- package/dist/hookmovies/pages/ai/ConciergePage.js +330 -0
- package/dist/hookmovies/pages/ai/ConciergePage.js.map +1 -0
- package/dist/hookmovies/pages/analytics/AnalyticsPage.js +450 -0
- package/dist/hookmovies/pages/analytics/AnalyticsPage.js.map +1 -0
- package/dist/hookmovies/pages/analytics/PayoutsPage.js +499 -0
- package/dist/hookmovies/pages/analytics/PayoutsPage.js.map +1 -0
- package/dist/hookmovies/pages/auditions/AuditionDetailPage.js +223 -140
- package/dist/hookmovies/pages/auditions/AuditionDetailPage.js.map +1 -1
- package/dist/hookmovies/pages/auditions/AuditionsPage.js +161 -83
- package/dist/hookmovies/pages/auditions/AuditionsPage.js.map +1 -1
- package/dist/hookmovies/pages/catalog/PeoplePage.js +177 -103
- package/dist/hookmovies/pages/catalog/PeoplePage.js.map +1 -1
- package/dist/hookmovies/pages/catalog/StudiosPage.js +191 -108
- package/dist/hookmovies/pages/catalog/StudiosPage.js.map +1 -1
- package/dist/hookmovies/pages/catalog/TitleDetailPage.js +744 -622
- package/dist/hookmovies/pages/catalog/TitleDetailPage.js.map +1 -1
- package/dist/hookmovies/pages/catalog/TitlesPage.js +218 -138
- package/dist/hookmovies/pages/catalog/TitlesPage.js.map +1 -1
- package/dist/hookmovies/pages/commerce/CheckoutPage.js +430 -0
- package/dist/hookmovies/pages/commerce/CheckoutPage.js.map +1 -0
- package/dist/hookmovies/pages/consumer/DiscoveryPage.js +21 -21
- package/dist/hookmovies/pages/consumer/HooksPage.js +5 -5
- package/dist/hookmovies/pages/consumer/TitleViewPage.js +32 -32
- package/dist/hookmovies/pages/consumer/TitleViewPage.js.map +1 -1
- package/dist/hookmovies/pages/developer/DevPortalPage.js +815 -0
- package/dist/hookmovies/pages/developer/DevPortalPage.js.map +1 -0
- package/dist/hookmovies/pages/distribution/RightsWindowsPage.js +235 -162
- package/dist/hookmovies/pages/distribution/RightsWindowsPage.js.map +1 -1
- package/dist/hookmovies/pages/engagement/ReviewsPage.js +201 -143
- package/dist/hookmovies/pages/engagement/ReviewsPage.js.map +1 -1
- package/dist/hookmovies/pages/library/EntitlementsPage.js +447 -221
- package/dist/hookmovies/pages/library/EntitlementsPage.js.map +1 -1
- package/dist/hookmovies/pages/library/ListsPage.js +243 -167
- package/dist/hookmovies/pages/library/ListsPage.js.map +1 -1
- package/dist/hookmovies/pages/live/LivePage.js +608 -0
- package/dist/hookmovies/pages/live/LivePage.js.map +1 -0
- package/dist/hookmovies/pages/localization/LocalizationPage.js +656 -0
- package/dist/hookmovies/pages/localization/LocalizationPage.js.map +1 -0
- package/dist/hookmovies/pages/onboarding/OnboardingPage.js +366 -0
- package/dist/hookmovies/pages/onboarding/OnboardingPage.js.map +1 -0
- package/dist/hookmovies/pages/productions/ProductionDetailPage.js +265 -179
- package/dist/hookmovies/pages/productions/ProductionDetailPage.js.map +1 -1
- package/dist/hookmovies/pages/productions/ProductionsPage.js +264 -71
- package/dist/hookmovies/pages/productions/ProductionsPage.js.map +1 -1
- package/dist/hookmovies/pages/social/ProfilesPage.js +701 -0
- package/dist/hookmovies/pages/social/ProfilesPage.js.map +1 -0
- package/dist/hookmovies/pages/social/WatchPartyListPage.js +281 -0
- package/dist/hookmovies/pages/social/WatchPartyListPage.js.map +1 -0
- package/dist/hookmovies/pages/social/WatchPartyRoomPage.js +567 -0
- package/dist/hookmovies/pages/social/WatchPartyRoomPage.js.map +1 -0
- package/dist/hookmovies/pages/trust/ModerationPage.js +320 -0
- package/dist/hookmovies/pages/trust/ModerationPage.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,499 @@
|
|
|
1
|
+
import { PageLayout as e } from "../../components/PageLayout.js";
|
|
2
|
+
import { MetricsCard as t } from "../../components/MetricsCard.js";
|
|
3
|
+
import { StatusBadge as n } from "../../components/StatusBadge.js";
|
|
4
|
+
import { useMyBillingAccounts as ee, useMyEarningsEntries as r, useMyEarningsSummary as te, useMyPayoutAccounts as ne, useMyPayoutRequests as re, useRequestPayout as ie } from "../../hooks/useHookMoviesApi.js";
|
|
5
|
+
import { formatDate as i, formatEnumLabel as a } from "../../utils/formatters.js";
|
|
6
|
+
import { EmptyState as o } from "../../components/EmptyState.js";
|
|
7
|
+
import { ErrorState as s, LoadingState as c } from "../../components/StateViews.js";
|
|
8
|
+
import { Pagination as l } from "../../components/Pagination.js";
|
|
9
|
+
import { useMemo as u, useState as d } from "react";
|
|
10
|
+
import { useQueryClient as ae } from "@tanstack/react-query";
|
|
11
|
+
import { ArrowDownToLine as oe, BadgeCheck as se, CircleDollarSign as ce, Clock as f, Coins as le, Info as ue, Landmark as de, ReceiptText as fe, Wallet as p, X as pe } from "lucide-react";
|
|
12
|
+
import { jsx as m, jsxs as h } from "react/jsx-runtime";
|
|
13
|
+
import { GlassCard as g } from "@burdenoff/fe-libs/ui";
|
|
14
|
+
//#region src/hookmovies/pages/analytics/PayoutsPage.tsx
|
|
15
|
+
var _ = 10, v = 10, me = [
|
|
16
|
+
"AVAILABLE",
|
|
17
|
+
"RESERVED",
|
|
18
|
+
"PAID",
|
|
19
|
+
"REVERSED"
|
|
20
|
+
], y = "w-full rounded-lg border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary placeholder:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]", b = "mb-1.5 block text-xs font-medium text-text-secondary";
|
|
21
|
+
function x(e, t) {
|
|
22
|
+
try {
|
|
23
|
+
return new Intl.NumberFormat(void 0, {
|
|
24
|
+
style: "currency",
|
|
25
|
+
currency: t
|
|
26
|
+
}).format(e);
|
|
27
|
+
} catch {
|
|
28
|
+
return `${e.toFixed(2)} ${t}`;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
function S(e) {
|
|
32
|
+
let t = [a(e.type)];
|
|
33
|
+
return e.accountLast4 && t.push(`••••${e.accountLast4}`), t.join(" · ");
|
|
34
|
+
}
|
|
35
|
+
var C = () => {
|
|
36
|
+
let C = ae(), w = ee(), T = u(() => w.data ?? [], [w.data]), he = u(() => {
|
|
37
|
+
if (T.length !== 0) return (T.find((e) => e.isDefault) ?? T[0]).id;
|
|
38
|
+
}, [T]), [ge, _e] = d(null), E = ge ?? he, ve = T.find((e) => e.id === E), [D, ye] = d(""), [O, k] = d(0), [A, j] = d(0), [be, M] = d(!1), [N, P] = d(""), [F, I] = d(""), [L, R] = d(""), [z, B] = d(null), V = te(E), H = ne(E), U = r(E, D ? { status: D } : void 0, _, O * _), W = re(E, v, A * v), G = r(E, { status: "RESERVED" }, 100, 0), K = ie(), q = V.data, J = H.data ?? [], Y = J.find((e) => e.isDefault) ?? J[0] ?? null, X = ve?.currency ?? U.data?.items[0]?.currency ?? "USD", Z = u(() => {
|
|
39
|
+
let e = Date.now();
|
|
40
|
+
return (G.data?.items ?? []).map((e) => ({
|
|
41
|
+
raw: e.availableAt,
|
|
42
|
+
t: new Date(e.availableAt).getTime()
|
|
43
|
+
})).filter((t) => Number.isFinite(t.t) && t.t >= e).sort((e, t) => e.t - t.t)[0]?.raw ?? null;
|
|
44
|
+
}, [G.data]), xe = () => {
|
|
45
|
+
B(null), P(Y?.id ?? ""), I(q && q.availableAmount > 0 ? String(q.availableAmount) : ""), R(""), M(!0);
|
|
46
|
+
}, Se = async (e) => {
|
|
47
|
+
if (e.preventDefault(), B(null), !E) return;
|
|
48
|
+
if (!N) {
|
|
49
|
+
B("Select a payout method.");
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
let t = Number(F);
|
|
53
|
+
if (!Number.isFinite(t) || t <= 0) {
|
|
54
|
+
B("Enter a valid amount greater than zero.");
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
if (q && t > q.availableAmount) {
|
|
58
|
+
B(`Amount exceeds your available balance (${x(q.availableAmount, X)}).`);
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
try {
|
|
62
|
+
await K.mutateAsync({
|
|
63
|
+
billingAccountId: E,
|
|
64
|
+
payoutAccountId: N,
|
|
65
|
+
amount: t,
|
|
66
|
+
currency: X,
|
|
67
|
+
notes: L.trim() || void 0
|
|
68
|
+
}), C.invalidateQueries({ queryKey: ["hookmovies", "earnings-entries"] }), C.invalidateQueries({ queryKey: [
|
|
69
|
+
"hookmovies",
|
|
70
|
+
"payout-accounts",
|
|
71
|
+
E
|
|
72
|
+
] }), M(!1), j(0);
|
|
73
|
+
} catch (e) {
|
|
74
|
+
B(e instanceof Error ? e.message : "Payout request failed");
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
if (w.isLoading) return /* @__PURE__ */ m(e, {
|
|
78
|
+
title: "Creator Royalty Ledger & Payouts",
|
|
79
|
+
description: "Your earnings, ledger & withdrawals",
|
|
80
|
+
children: /* @__PURE__ */ m(c, { label: "Loading your billing account…" })
|
|
81
|
+
});
|
|
82
|
+
if (w.isError) return /* @__PURE__ */ m(e, {
|
|
83
|
+
title: "Creator Royalty Ledger & Payouts",
|
|
84
|
+
description: "Your earnings, ledger & withdrawals",
|
|
85
|
+
children: /* @__PURE__ */ m(s, { onRetry: () => void w.refetch() })
|
|
86
|
+
});
|
|
87
|
+
if (!E) return /* @__PURE__ */ m(e, {
|
|
88
|
+
title: "Creator Royalty Ledger & Payouts",
|
|
89
|
+
description: "Your earnings, ledger & withdrawals",
|
|
90
|
+
purpose: "Royalties from your titles — rentals, purchases and revenue share — accrue to a billing account. Once you have one, your earnings ledger and payout options appear here.",
|
|
91
|
+
children: /* @__PURE__ */ m(o, {
|
|
92
|
+
icon: /* @__PURE__ */ m(p, { className: "h-12 w-12" }),
|
|
93
|
+
title: "No billing account yet",
|
|
94
|
+
description: "Royalties are paid into a billing account. You do not have one associated with this workspace yet, so there is nothing to display."
|
|
95
|
+
})
|
|
96
|
+
});
|
|
97
|
+
let Q = U.data?.items ?? [], $ = W.data?.items ?? [], Ce = !!(q && q.availableAmount > 0) && J.length > 0;
|
|
98
|
+
return /* @__PURE__ */ h(e, {
|
|
99
|
+
title: "Creator Royalty Ledger & Payouts",
|
|
100
|
+
description: "Your earnings, ledger & withdrawals",
|
|
101
|
+
purpose: "Every royalty your titles earn is recorded as a ledger entry against your billing account. Funds move from reserved → available, and you can withdraw the available balance to a verified payout method.",
|
|
102
|
+
actions: /* @__PURE__ */ h("div", {
|
|
103
|
+
className: "flex items-center gap-3",
|
|
104
|
+
children: [T.length > 1 && /* @__PURE__ */ m("select", {
|
|
105
|
+
value: E,
|
|
106
|
+
onChange: (e) => {
|
|
107
|
+
_e(e.target.value), k(0), j(0);
|
|
108
|
+
},
|
|
109
|
+
"aria-label": "Billing account",
|
|
110
|
+
className: "rounded-lg border border-border-subtle bg-bg-surface px-3 py-2 text-xs text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]",
|
|
111
|
+
children: T.map((e) => /* @__PURE__ */ m("option", {
|
|
112
|
+
value: e.id,
|
|
113
|
+
children: e.name ?? e.id
|
|
114
|
+
}, e.id))
|
|
115
|
+
}), /* @__PURE__ */ h("button", {
|
|
116
|
+
type: "button",
|
|
117
|
+
onClick: xe,
|
|
118
|
+
disabled: !Ce,
|
|
119
|
+
className: "inline-flex items-center gap-2 rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:opacity-90 disabled:opacity-50 disabled:cursor-not-allowed transition-opacity",
|
|
120
|
+
children: [/* @__PURE__ */ m(oe, { className: "h-4 w-4" }), "Withdraw"]
|
|
121
|
+
})]
|
|
122
|
+
}),
|
|
123
|
+
children: [
|
|
124
|
+
be && /* @__PURE__ */ h(g, {
|
|
125
|
+
treatment: "glass",
|
|
126
|
+
className: "mb-6 border-border-seam p-5",
|
|
127
|
+
children: [/* @__PURE__ */ h("div", {
|
|
128
|
+
className: "mb-3 flex items-center justify-between",
|
|
129
|
+
children: [/* @__PURE__ */ m("h2", {
|
|
130
|
+
className: "text-sm font-semibold text-text-primary",
|
|
131
|
+
children: "Withdraw available balance"
|
|
132
|
+
}), /* @__PURE__ */ m("button", {
|
|
133
|
+
type: "button",
|
|
134
|
+
onClick: () => M(!1),
|
|
135
|
+
className: "rounded-md p-1 text-text-secondary hover:text-text-primary",
|
|
136
|
+
"aria-label": "Close",
|
|
137
|
+
children: /* @__PURE__ */ m(pe, { className: "h-4 w-4" })
|
|
138
|
+
})]
|
|
139
|
+
}), /* @__PURE__ */ h("form", {
|
|
140
|
+
onSubmit: Se,
|
|
141
|
+
className: "space-y-4",
|
|
142
|
+
children: [
|
|
143
|
+
z && /* @__PURE__ */ m("div", {
|
|
144
|
+
className: "rounded-lg border border-status-error-border bg-status-error-bg-subtle px-3 py-2 text-sm text-status-error-text",
|
|
145
|
+
children: z
|
|
146
|
+
}),
|
|
147
|
+
/* @__PURE__ */ h("div", {
|
|
148
|
+
className: "grid grid-cols-1 gap-4 sm:grid-cols-2",
|
|
149
|
+
children: [/* @__PURE__ */ h("div", { children: [/* @__PURE__ */ m("label", {
|
|
150
|
+
htmlFor: "withdraw-account",
|
|
151
|
+
className: b,
|
|
152
|
+
children: "Payout method *"
|
|
153
|
+
}), /* @__PURE__ */ h("select", {
|
|
154
|
+
id: "withdraw-account",
|
|
155
|
+
value: N,
|
|
156
|
+
onChange: (e) => P(e.target.value),
|
|
157
|
+
className: y,
|
|
158
|
+
required: !0,
|
|
159
|
+
children: [/* @__PURE__ */ m("option", {
|
|
160
|
+
value: "",
|
|
161
|
+
children: "Select a method…"
|
|
162
|
+
}), J.map((e) => /* @__PURE__ */ h("option", {
|
|
163
|
+
value: e.id,
|
|
164
|
+
children: [
|
|
165
|
+
e.label,
|
|
166
|
+
" — ",
|
|
167
|
+
S(e)
|
|
168
|
+
]
|
|
169
|
+
}, e.id))]
|
|
170
|
+
})] }), /* @__PURE__ */ h("div", { children: [
|
|
171
|
+
/* @__PURE__ */ h("label", {
|
|
172
|
+
htmlFor: "withdraw-amount",
|
|
173
|
+
className: b,
|
|
174
|
+
children: [
|
|
175
|
+
"Amount (",
|
|
176
|
+
X,
|
|
177
|
+
") *"
|
|
178
|
+
]
|
|
179
|
+
}),
|
|
180
|
+
/* @__PURE__ */ m("input", {
|
|
181
|
+
id: "withdraw-amount",
|
|
182
|
+
type: "number",
|
|
183
|
+
min: "0",
|
|
184
|
+
step: "0.01",
|
|
185
|
+
value: F,
|
|
186
|
+
onChange: (e) => I(e.target.value),
|
|
187
|
+
placeholder: "0.00",
|
|
188
|
+
className: y,
|
|
189
|
+
required: !0
|
|
190
|
+
}),
|
|
191
|
+
q && /* @__PURE__ */ h("p", {
|
|
192
|
+
className: "mt-1 text-xs text-text-secondary",
|
|
193
|
+
children: ["Available: ", x(q.availableAmount, X)]
|
|
194
|
+
})
|
|
195
|
+
] })]
|
|
196
|
+
}),
|
|
197
|
+
/* @__PURE__ */ h("div", { children: [/* @__PURE__ */ m("label", {
|
|
198
|
+
htmlFor: "withdraw-notes",
|
|
199
|
+
className: b,
|
|
200
|
+
children: "Notes (optional)"
|
|
201
|
+
}), /* @__PURE__ */ m("input", {
|
|
202
|
+
id: "withdraw-notes",
|
|
203
|
+
type: "text",
|
|
204
|
+
value: L,
|
|
205
|
+
onChange: (e) => R(e.target.value),
|
|
206
|
+
placeholder: "Reference for this withdrawal",
|
|
207
|
+
className: y
|
|
208
|
+
})] }),
|
|
209
|
+
/* @__PURE__ */ m("button", {
|
|
210
|
+
type: "submit",
|
|
211
|
+
disabled: K.isPending,
|
|
212
|
+
className: "rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:opacity-90 disabled:opacity-50 transition-opacity",
|
|
213
|
+
children: K.isPending ? "Requesting…" : "Request payout"
|
|
214
|
+
})
|
|
215
|
+
]
|
|
216
|
+
})]
|
|
217
|
+
}),
|
|
218
|
+
V.isLoading ? /* @__PURE__ */ m(c, { label: "Loading earnings summary…" }) : V.isError ? /* @__PURE__ */ m(s, { onRetry: () => void V.refetch() }) : q ? /* @__PURE__ */ h("div", {
|
|
219
|
+
className: "grid grid-cols-1 gap-4 sm:grid-cols-2 xl:grid-cols-4",
|
|
220
|
+
children: [
|
|
221
|
+
/* @__PURE__ */ m(t, {
|
|
222
|
+
featured: !0,
|
|
223
|
+
icon: /* @__PURE__ */ m(p, { className: "h-5 w-5" }),
|
|
224
|
+
value: x(q.availableAmount, X),
|
|
225
|
+
label: "Available to withdraw"
|
|
226
|
+
}),
|
|
227
|
+
/* @__PURE__ */ m(t, {
|
|
228
|
+
icon: /* @__PURE__ */ m(f, { className: "h-5 w-5" }),
|
|
229
|
+
value: x(q.reservedAmount, X),
|
|
230
|
+
label: "Reserved (clearing)"
|
|
231
|
+
}),
|
|
232
|
+
/* @__PURE__ */ m(t, {
|
|
233
|
+
icon: /* @__PURE__ */ m(se, { className: "h-5 w-5" }),
|
|
234
|
+
value: x(q.paidAmount, X),
|
|
235
|
+
label: "Paid out"
|
|
236
|
+
}),
|
|
237
|
+
/* @__PURE__ */ m(t, {
|
|
238
|
+
icon: /* @__PURE__ */ m(ce, { className: "h-5 w-5" }),
|
|
239
|
+
value: x(q.totalLifetimeAmount, X),
|
|
240
|
+
label: "Lifetime earnings"
|
|
241
|
+
})
|
|
242
|
+
]
|
|
243
|
+
}) : null,
|
|
244
|
+
/* @__PURE__ */ h("div", {
|
|
245
|
+
className: "mt-4 grid grid-cols-1 gap-4 lg:grid-cols-2",
|
|
246
|
+
children: [/* @__PURE__ */ h(g, {
|
|
247
|
+
treatment: "metric",
|
|
248
|
+
className: "border-border-seam p-5",
|
|
249
|
+
children: [/* @__PURE__ */ h("div", {
|
|
250
|
+
className: "flex items-center gap-2 text-text-secondary",
|
|
251
|
+
children: [/* @__PURE__ */ m(de, { className: "h-4 w-4" }), /* @__PURE__ */ m("h3", {
|
|
252
|
+
className: "text-xs font-medium uppercase tracking-wide",
|
|
253
|
+
children: "Payout method"
|
|
254
|
+
})]
|
|
255
|
+
}), H.isLoading ? /* @__PURE__ */ m("p", {
|
|
256
|
+
className: "mt-3 text-sm text-text-secondary",
|
|
257
|
+
children: "Loading…"
|
|
258
|
+
}) : Y ? /* @__PURE__ */ h("div", {
|
|
259
|
+
className: "mt-3",
|
|
260
|
+
children: [/* @__PURE__ */ h("div", {
|
|
261
|
+
className: "flex items-center gap-2",
|
|
262
|
+
children: [
|
|
263
|
+
/* @__PURE__ */ m("p", {
|
|
264
|
+
className: "text-sm font-semibold text-text-primary",
|
|
265
|
+
children: Y.label
|
|
266
|
+
}),
|
|
267
|
+
Y.isDefault && /* @__PURE__ */ m("span", {
|
|
268
|
+
className: "rounded-full bg-bg-sunken px-2 py-0.5 text-[10px] text-text-secondary",
|
|
269
|
+
children: "Default"
|
|
270
|
+
}),
|
|
271
|
+
/* @__PURE__ */ m(n, { status: Y.status })
|
|
272
|
+
]
|
|
273
|
+
}), /* @__PURE__ */ h("p", {
|
|
274
|
+
className: "mt-1 text-sm text-text-secondary",
|
|
275
|
+
children: [
|
|
276
|
+
S(Y),
|
|
277
|
+
" · ",
|
|
278
|
+
Y.currency
|
|
279
|
+
]
|
|
280
|
+
})]
|
|
281
|
+
}) : /* @__PURE__ */ h("p", {
|
|
282
|
+
className: "mt-3 flex items-start gap-2 text-sm text-text-secondary",
|
|
283
|
+
children: [/* @__PURE__ */ m(ue, { className: "mt-0.5 h-4 w-4 shrink-0" }), "No payout method on file. Add a verified bank / UPI / wallet destination in your billing settings to enable withdrawals."]
|
|
284
|
+
})]
|
|
285
|
+
}), /* @__PURE__ */ h(g, {
|
|
286
|
+
treatment: "metric",
|
|
287
|
+
className: "border-border-seam p-5",
|
|
288
|
+
children: [/* @__PURE__ */ h("div", {
|
|
289
|
+
className: "flex items-center gap-2 text-text-secondary",
|
|
290
|
+
children: [/* @__PURE__ */ m(f, { className: "h-4 w-4" }), /* @__PURE__ */ m("h3", {
|
|
291
|
+
className: "text-xs font-medium uppercase tracking-wide",
|
|
292
|
+
children: "Next funds available"
|
|
293
|
+
})]
|
|
294
|
+
}), G.isLoading ? /* @__PURE__ */ m("p", {
|
|
295
|
+
className: "mt-3 text-sm text-text-secondary",
|
|
296
|
+
children: "Loading…"
|
|
297
|
+
}) : Z ? /* @__PURE__ */ h("div", {
|
|
298
|
+
className: "mt-3",
|
|
299
|
+
children: [/* @__PURE__ */ m("p", {
|
|
300
|
+
className: "text-sm font-semibold text-text-primary",
|
|
301
|
+
children: i(Z, {
|
|
302
|
+
hour: void 0,
|
|
303
|
+
minute: void 0
|
|
304
|
+
})
|
|
305
|
+
}), /* @__PURE__ */ m("p", {
|
|
306
|
+
className: "mt-1 text-sm text-text-secondary",
|
|
307
|
+
children: "Reserved royalties clear to your available balance on this date."
|
|
308
|
+
})]
|
|
309
|
+
}) : /* @__PURE__ */ m("p", {
|
|
310
|
+
className: "mt-3 text-sm text-text-secondary",
|
|
311
|
+
children: "No reserved royalties are currently pending clearance."
|
|
312
|
+
})]
|
|
313
|
+
})]
|
|
314
|
+
}),
|
|
315
|
+
/* @__PURE__ */ h("div", {
|
|
316
|
+
className: "mt-6",
|
|
317
|
+
children: [
|
|
318
|
+
/* @__PURE__ */ h("div", {
|
|
319
|
+
className: "mb-3 flex flex-wrap items-center justify-between gap-3",
|
|
320
|
+
children: [/* @__PURE__ */ m("h2", {
|
|
321
|
+
className: "text-sm font-semibold text-text-primary",
|
|
322
|
+
children: "Royalty ledger"
|
|
323
|
+
}), /* @__PURE__ */ h("select", {
|
|
324
|
+
value: D,
|
|
325
|
+
onChange: (e) => {
|
|
326
|
+
ye(e.target.value), k(0);
|
|
327
|
+
},
|
|
328
|
+
"aria-label": "Filter ledger by status",
|
|
329
|
+
className: "rounded-lg border border-border-subtle bg-bg-surface px-3 py-2 text-xs text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]",
|
|
330
|
+
children: [/* @__PURE__ */ m("option", {
|
|
331
|
+
value: "",
|
|
332
|
+
children: "Any status"
|
|
333
|
+
}), me.map((e) => /* @__PURE__ */ m("option", {
|
|
334
|
+
value: e,
|
|
335
|
+
children: a(e)
|
|
336
|
+
}, e))]
|
|
337
|
+
})]
|
|
338
|
+
}),
|
|
339
|
+
U.isLoading ? /* @__PURE__ */ m(c, { label: "Loading ledger…" }) : U.isError ? /* @__PURE__ */ m(s, { onRetry: () => void U.refetch() }) : Q.length === 0 ? /* @__PURE__ */ m(o, {
|
|
340
|
+
icon: /* @__PURE__ */ m(fe, { className: "h-12 w-12" }),
|
|
341
|
+
title: "No royalty entries yet",
|
|
342
|
+
description: D ? "No ledger entries match this status filter." : "Your titles have not generated any royalties on this billing account yet. Earnings appear here as they accrue."
|
|
343
|
+
}) : /* @__PURE__ */ m("div", {
|
|
344
|
+
className: "overflow-x-auto rounded-lg border border-border-seam bg-bg-surface",
|
|
345
|
+
children: /* @__PURE__ */ h("table", {
|
|
346
|
+
className: "w-full min-w-[36rem] text-sm",
|
|
347
|
+
children: [/* @__PURE__ */ m("thead", { children: /* @__PURE__ */ h("tr", {
|
|
348
|
+
className: "border-b border-border-seam text-left text-xs text-text-secondary",
|
|
349
|
+
children: [
|
|
350
|
+
/* @__PURE__ */ m("th", {
|
|
351
|
+
className: "px-4 py-3 font-medium",
|
|
352
|
+
children: "Date"
|
|
353
|
+
}),
|
|
354
|
+
/* @__PURE__ */ m("th", {
|
|
355
|
+
className: "px-4 py-3 font-medium",
|
|
356
|
+
children: "Source"
|
|
357
|
+
}),
|
|
358
|
+
/* @__PURE__ */ m("th", {
|
|
359
|
+
className: "px-4 py-3 text-right font-medium",
|
|
360
|
+
children: "Amount"
|
|
361
|
+
}),
|
|
362
|
+
/* @__PURE__ */ m("th", {
|
|
363
|
+
className: "px-4 py-3 font-medium",
|
|
364
|
+
children: "Status"
|
|
365
|
+
})
|
|
366
|
+
]
|
|
367
|
+
}) }), /* @__PURE__ */ m("tbody", {
|
|
368
|
+
className: "divide-y divide-border-seam",
|
|
369
|
+
children: Q.map((e) => /* @__PURE__ */ h("tr", {
|
|
370
|
+
className: "hover:bg-bg-sunken transition-colors",
|
|
371
|
+
children: [
|
|
372
|
+
/* @__PURE__ */ m("td", {
|
|
373
|
+
className: "whitespace-nowrap px-4 py-3 text-text-secondary",
|
|
374
|
+
children: i(e.createdAt, {
|
|
375
|
+
hour: void 0,
|
|
376
|
+
minute: void 0
|
|
377
|
+
})
|
|
378
|
+
}),
|
|
379
|
+
/* @__PURE__ */ h("td", {
|
|
380
|
+
className: "px-4 py-3",
|
|
381
|
+
children: [/* @__PURE__ */ m("p", {
|
|
382
|
+
className: "font-medium text-text-primary",
|
|
383
|
+
children: a(e.sourceCategory)
|
|
384
|
+
}), e.description && /* @__PURE__ */ m("p", {
|
|
385
|
+
className: "line-clamp-1 text-xs text-text-secondary",
|
|
386
|
+
children: e.description
|
|
387
|
+
})]
|
|
388
|
+
}),
|
|
389
|
+
/* @__PURE__ */ m("td", {
|
|
390
|
+
className: "whitespace-nowrap px-4 py-3 text-right font-medium tabular-nums text-text-primary",
|
|
391
|
+
children: x(e.amount, e.currency)
|
|
392
|
+
}),
|
|
393
|
+
/* @__PURE__ */ m("td", {
|
|
394
|
+
className: "px-4 py-3",
|
|
395
|
+
children: /* @__PURE__ */ m(n, { status: e.status })
|
|
396
|
+
})
|
|
397
|
+
]
|
|
398
|
+
}, e.id))
|
|
399
|
+
})]
|
|
400
|
+
})
|
|
401
|
+
}),
|
|
402
|
+
!U.isLoading && !U.isError && /* @__PURE__ */ m(l, {
|
|
403
|
+
page: O,
|
|
404
|
+
hasMore: U.data?.hasMore ?? !1,
|
|
405
|
+
onPageChange: k,
|
|
406
|
+
shownCount: Q.length
|
|
407
|
+
})
|
|
408
|
+
]
|
|
409
|
+
}),
|
|
410
|
+
/* @__PURE__ */ h("div", {
|
|
411
|
+
className: "mt-8",
|
|
412
|
+
children: [
|
|
413
|
+
/* @__PURE__ */ m("h2", {
|
|
414
|
+
className: "mb-3 text-sm font-semibold text-text-primary",
|
|
415
|
+
children: "Withdrawal history"
|
|
416
|
+
}),
|
|
417
|
+
W.isLoading ? /* @__PURE__ */ m(c, { label: "Loading withdrawals…" }) : W.isError ? /* @__PURE__ */ m(s, { onRetry: () => void W.refetch() }) : $.length === 0 ? /* @__PURE__ */ m(o, {
|
|
418
|
+
icon: /* @__PURE__ */ m(le, { className: "h-12 w-12" }),
|
|
419
|
+
title: "No withdrawals yet",
|
|
420
|
+
description: "When you request a payout, each withdrawal and its status will be listed here."
|
|
421
|
+
}) : /* @__PURE__ */ m("div", {
|
|
422
|
+
className: "overflow-x-auto rounded-lg border border-border-seam bg-bg-surface",
|
|
423
|
+
children: /* @__PURE__ */ h("table", {
|
|
424
|
+
className: "w-full min-w-[36rem] text-sm",
|
|
425
|
+
children: [/* @__PURE__ */ m("thead", { children: /* @__PURE__ */ h("tr", {
|
|
426
|
+
className: "border-b border-border-seam text-left text-xs text-text-secondary",
|
|
427
|
+
children: [
|
|
428
|
+
/* @__PURE__ */ m("th", {
|
|
429
|
+
className: "px-4 py-3 font-medium",
|
|
430
|
+
children: "Requested"
|
|
431
|
+
}),
|
|
432
|
+
/* @__PURE__ */ m("th", {
|
|
433
|
+
className: "px-4 py-3 text-right font-medium",
|
|
434
|
+
children: "Amount"
|
|
435
|
+
}),
|
|
436
|
+
/* @__PURE__ */ m("th", {
|
|
437
|
+
className: "px-4 py-3 font-medium",
|
|
438
|
+
children: "Provider"
|
|
439
|
+
}),
|
|
440
|
+
/* @__PURE__ */ m("th", {
|
|
441
|
+
className: "px-4 py-3 font-medium",
|
|
442
|
+
children: "Status"
|
|
443
|
+
}),
|
|
444
|
+
/* @__PURE__ */ m("th", {
|
|
445
|
+
className: "hidden px-4 py-3 font-medium md:table-cell",
|
|
446
|
+
children: "Paid"
|
|
447
|
+
})
|
|
448
|
+
]
|
|
449
|
+
}) }), /* @__PURE__ */ m("tbody", {
|
|
450
|
+
className: "divide-y divide-border-seam",
|
|
451
|
+
children: $.map((e) => /* @__PURE__ */ h("tr", {
|
|
452
|
+
className: "hover:bg-bg-sunken transition-colors",
|
|
453
|
+
children: [
|
|
454
|
+
/* @__PURE__ */ m("td", {
|
|
455
|
+
className: "whitespace-nowrap px-4 py-3 text-text-secondary",
|
|
456
|
+
children: i(e.createdAt, {
|
|
457
|
+
hour: void 0,
|
|
458
|
+
minute: void 0
|
|
459
|
+
})
|
|
460
|
+
}),
|
|
461
|
+
/* @__PURE__ */ m("td", {
|
|
462
|
+
className: "whitespace-nowrap px-4 py-3 text-right font-medium tabular-nums text-text-primary",
|
|
463
|
+
children: x(e.approvedAmount ?? e.requestedAmount, e.currency)
|
|
464
|
+
}),
|
|
465
|
+
/* @__PURE__ */ m("td", {
|
|
466
|
+
className: "px-4 py-3 text-text-secondary",
|
|
467
|
+
children: e.provider ? a(e.provider) : "—"
|
|
468
|
+
}),
|
|
469
|
+
/* @__PURE__ */ m("td", {
|
|
470
|
+
className: "px-4 py-3",
|
|
471
|
+
children: /* @__PURE__ */ m(n, { status: e.status })
|
|
472
|
+
}),
|
|
473
|
+
/* @__PURE__ */ m("td", {
|
|
474
|
+
className: "hidden whitespace-nowrap px-4 py-3 text-text-secondary md:table-cell",
|
|
475
|
+
children: e.paidAt ? i(e.paidAt, {
|
|
476
|
+
hour: void 0,
|
|
477
|
+
minute: void 0
|
|
478
|
+
}) : "—"
|
|
479
|
+
})
|
|
480
|
+
]
|
|
481
|
+
}, e.id))
|
|
482
|
+
})]
|
|
483
|
+
})
|
|
484
|
+
}),
|
|
485
|
+
!W.isLoading && !W.isError && /* @__PURE__ */ m(l, {
|
|
486
|
+
page: A,
|
|
487
|
+
hasMore: W.data?.hasMore ?? !1,
|
|
488
|
+
onPageChange: j,
|
|
489
|
+
shownCount: $.length
|
|
490
|
+
})
|
|
491
|
+
]
|
|
492
|
+
})
|
|
493
|
+
]
|
|
494
|
+
});
|
|
495
|
+
};
|
|
496
|
+
//#endregion
|
|
497
|
+
export { C as PayoutsPage };
|
|
498
|
+
|
|
499
|
+
//# sourceMappingURL=PayoutsPage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PayoutsPage.js","names":[],"sources":["../../../../src/hookmovies/pages/analytics/PayoutsPage.tsx"],"sourcesContent":["/**\n * Creator Royalty Ledger & Payouts\n * @module hookmovies/pages/analytics\n *\n * The creator's money surface. Reuses the platform billing service\n * (`global-billing-svc`, GLOBAL gateway) rather than any HookMovies-local\n * ledger:\n * - `myEarningsSummary` → available / reserved / paid / lifetime headline\n * - `myEarningsEntries` → the royalty ledger (date · source · amount · status)\n * - `myPayoutAccounts` → the destination method funds are paid out to\n * - `myPayoutRequests` → withdrawal history\n * - `requestBillingPayout` → the Withdraw action\n *\n * Everything shown is real billing data for the caller's billing account. When\n * an account has no earnings we say so honestly — nothing is fabricated.\n */\n\nimport { type FC, type FormEvent, useMemo, useState } from 'react';\nimport {\n Wallet,\n Coins,\n BadgeCheck,\n CircleDollarSign,\n ArrowDownToLine,\n Landmark,\n Clock,\n ReceiptText,\n Info,\n X,\n} from 'lucide-react';\nimport { GlassCard } from '@burdenoff/fe-libs/ui';\nimport { useQueryClient } from '@tanstack/react-query';\n\nimport { PageLayout } from '../../components/PageLayout';\nimport { MetricsCard } from '../../components/MetricsCard';\nimport { StatusBadge } from '../../components/StatusBadge';\nimport { EmptyState } from '../../components/EmptyState';\nimport { LoadingState, ErrorState } from '../../components/StateViews';\nimport { Pagination } from '../../components/Pagination';\nimport {\n useMyBillingAccounts,\n useMyEarningsSummary,\n useMyEarningsEntries,\n useMyPayoutAccounts,\n useMyPayoutRequests,\n useRequestPayout,\n type EarningsEntryStatus,\n type PayoutAccount,\n} from '../../hooks/useHookMoviesApi';\nimport { formatDate, formatEnumLabel } from '../../utils/formatters';\n\nconst LEDGER_LIMIT = 10;\nconst PAYOUTS_LIMIT = 10;\n\nconst LEDGER_STATUS_OPTIONS: EarningsEntryStatus[] = ['AVAILABLE', 'RESERVED', 'PAID', 'REVERSED'];\n\nconst fieldClass =\n 'w-full rounded-lg border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary placeholder:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]';\nconst labelClass = 'mb-1.5 block text-xs font-medium text-text-secondary';\n\n/** Format a major-unit money amount with the given ISO currency, gracefully. */\nfunction formatMoney(amount: number, currency: string): string {\n try {\n return new Intl.NumberFormat(undefined, { style: 'currency', currency }).format(amount);\n } catch {\n return `${amount.toFixed(2)} ${currency}`;\n }\n}\n\n/** Human summary of a payout destination (e.g. \"UPI · ****4321\"). */\nfunction describePayoutAccount(account: PayoutAccount): string {\n const parts = [formatEnumLabel(account.type)];\n if (account.accountLast4) {\n parts.push(`••••${account.accountLast4}`);\n }\n return parts.join(' · ');\n}\n\nexport const PayoutsPage: FC = () => {\n const queryClient = useQueryClient();\n\n const accountsQuery = useMyBillingAccounts();\n const accounts = useMemo(() => accountsQuery.data ?? [], [accountsQuery.data]);\n\n // Default to the account flagged default, else the first one; allow override.\n const defaultAccountId = useMemo(() => {\n if (accounts.length === 0) return undefined;\n return (accounts.find((a) => a.isDefault) ?? accounts[0]).id;\n }, [accounts]);\n const [selectedAccountId, setSelectedAccountId] = useState<string | null>(null);\n const billingAccountId = selectedAccountId ?? defaultAccountId;\n const activeAccount = accounts.find((a) => a.id === billingAccountId);\n\n const [ledgerStatus, setLedgerStatus] = useState<EarningsEntryStatus | ''>('');\n const [ledgerPage, setLedgerPage] = useState(0);\n const [payoutsPage, setPayoutsPage] = useState(0);\n const [showWithdraw, setShowWithdraw] = useState(false);\n const [withdrawAccountId, setWithdrawAccountId] = useState('');\n const [withdrawAmount, setWithdrawAmount] = useState('');\n const [withdrawNotes, setWithdrawNotes] = useState('');\n const [withdrawError, setWithdrawError] = useState<string | null>(null);\n\n const summaryQuery = useMyEarningsSummary(billingAccountId);\n const payoutAccountsQuery = useMyPayoutAccounts(billingAccountId);\n const ledgerQuery = useMyEarningsEntries(\n billingAccountId,\n ledgerStatus ? { status: ledgerStatus } : undefined,\n LEDGER_LIMIT,\n ledgerPage * LEDGER_LIMIT\n );\n const payoutRequestsQuery = useMyPayoutRequests(\n billingAccountId,\n PAYOUTS_LIMIT,\n payoutsPage * PAYOUTS_LIMIT\n );\n // Reserved entries carry the future `availableAt` date — the earliest of these\n // is the soonest funds become withdrawable (\"next payout\" horizon).\n const reservedQuery = useMyEarningsEntries(billingAccountId, { status: 'RESERVED' }, 100, 0);\n const requestPayout = useRequestPayout();\n\n const summary = summaryQuery.data;\n const payoutAccounts = payoutAccountsQuery.data ?? [];\n const defaultPayoutAccount = payoutAccounts.find((a) => a.isDefault) ?? payoutAccounts[0] ?? null;\n\n // Currency: prefer the billing account's, fall back to a ledger row, else USD.\n const currency = activeAccount?.currency ?? ledgerQuery.data?.items[0]?.currency ?? 'USD';\n\n const nextAvailableAt = useMemo(() => {\n const now = Date.now();\n const upcoming = (reservedQuery.data?.items ?? [])\n .map((e) => ({ raw: e.availableAt, t: new Date(e.availableAt).getTime() }))\n .filter((x) => Number.isFinite(x.t) && x.t >= now)\n .sort((a, b) => a.t - b.t);\n return upcoming[0]?.raw ?? null;\n }, [reservedQuery.data]);\n\n const openWithdraw = () => {\n setWithdrawError(null);\n setWithdrawAccountId(defaultPayoutAccount?.id ?? '');\n setWithdrawAmount(\n summary && summary.availableAmount > 0 ? String(summary.availableAmount) : ''\n );\n setWithdrawNotes('');\n setShowWithdraw(true);\n };\n\n const handleWithdraw = async (e: FormEvent) => {\n e.preventDefault();\n setWithdrawError(null);\n if (!billingAccountId) return;\n if (!withdrawAccountId) {\n setWithdrawError('Select a payout method.');\n return;\n }\n const amount = Number(withdrawAmount);\n if (!Number.isFinite(amount) || amount <= 0) {\n setWithdrawError('Enter a valid amount greater than zero.');\n return;\n }\n if (summary && amount > summary.availableAmount) {\n setWithdrawError(\n `Amount exceeds your available balance (${formatMoney(summary.availableAmount, currency)}).`\n );\n return;\n }\n try {\n await requestPayout.mutateAsync({\n billingAccountId,\n payoutAccountId: withdrawAccountId,\n amount,\n currency,\n notes: withdrawNotes.trim() || undefined,\n });\n // The mutation hook invalidates payout-requests + earnings-summary; also\n // refresh the ledger + reserved horizon + payout accounts so reserved\n // funds and the new request appear immediately.\n void queryClient.invalidateQueries({ queryKey: ['hookmovies', 'earnings-entries'] });\n void queryClient.invalidateQueries({\n queryKey: ['hookmovies', 'payout-accounts', billingAccountId],\n });\n setShowWithdraw(false);\n setPayoutsPage(0);\n } catch (err) {\n setWithdrawError(err instanceof Error ? err.message : 'Payout request failed');\n }\n };\n\n // ---- Top-level gates on the billing account list -------------------------\n\n if (accountsQuery.isLoading) {\n return (\n <PageLayout\n title=\"Creator Royalty Ledger & Payouts\"\n description=\"Your earnings, ledger & withdrawals\"\n >\n <LoadingState label=\"Loading your billing account…\" />\n </PageLayout>\n );\n }\n\n if (accountsQuery.isError) {\n return (\n <PageLayout\n title=\"Creator Royalty Ledger & Payouts\"\n description=\"Your earnings, ledger & withdrawals\"\n >\n <ErrorState onRetry={() => void accountsQuery.refetch()} />\n </PageLayout>\n );\n }\n\n if (!billingAccountId) {\n return (\n <PageLayout\n title=\"Creator Royalty Ledger & Payouts\"\n description=\"Your earnings, ledger & withdrawals\"\n purpose=\"Royalties from your titles — rentals, purchases and revenue share — accrue to a billing account. Once you have one, your earnings ledger and payout options appear here.\"\n >\n <EmptyState\n icon={<Wallet className=\"h-12 w-12\" />}\n title=\"No billing account yet\"\n description=\"Royalties are paid into a billing account. You do not have one associated with this workspace yet, so there is nothing to display.\"\n />\n </PageLayout>\n );\n }\n\n const ledgerItems = ledgerQuery.data?.items ?? [];\n const payoutItems = payoutRequestsQuery.data?.items ?? [];\n const canWithdraw = Boolean(summary && summary.availableAmount > 0) && payoutAccounts.length > 0;\n\n return (\n <PageLayout\n title=\"Creator Royalty Ledger & Payouts\"\n description=\"Your earnings, ledger & withdrawals\"\n purpose=\"Every royalty your titles earn is recorded as a ledger entry against your billing account. Funds move from reserved → available, and you can withdraw the available balance to a verified payout method.\"\n actions={\n <div className=\"flex items-center gap-3\">\n {accounts.length > 1 && (\n <select\n value={billingAccountId}\n onChange={(e) => {\n setSelectedAccountId(e.target.value);\n setLedgerPage(0);\n setPayoutsPage(0);\n }}\n aria-label=\"Billing account\"\n className=\"rounded-lg border border-border-subtle bg-bg-surface px-3 py-2 text-xs text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n >\n {accounts.map((a) => (\n <option key={a.id} value={a.id}>\n {a.name ?? a.id}\n </option>\n ))}\n </select>\n )}\n <button\n type=\"button\"\n onClick={openWithdraw}\n disabled={!canWithdraw}\n className=\"inline-flex items-center gap-2 rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:opacity-90 disabled:opacity-50 disabled:cursor-not-allowed transition-opacity\"\n >\n <ArrowDownToLine className=\"h-4 w-4\" />\n Withdraw\n </button>\n </div>\n }\n >\n {/* Withdraw form */}\n {showWithdraw && (\n <GlassCard treatment=\"glass\" className=\"mb-6 border-border-seam p-5\">\n <div className=\"mb-3 flex items-center justify-between\">\n <h2 className=\"text-sm font-semibold text-text-primary\">Withdraw available balance</h2>\n <button\n type=\"button\"\n onClick={() => setShowWithdraw(false)}\n className=\"rounded-md p-1 text-text-secondary hover:text-text-primary\"\n aria-label=\"Close\"\n >\n <X className=\"h-4 w-4\" />\n </button>\n </div>\n <form onSubmit={handleWithdraw} className=\"space-y-4\">\n {withdrawError && (\n <div className=\"rounded-lg border border-status-error-border bg-status-error-bg-subtle px-3 py-2 text-sm text-status-error-text\">\n {withdrawError}\n </div>\n )}\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2\">\n <div>\n <label htmlFor=\"withdraw-account\" className={labelClass}>\n Payout method *\n </label>\n <select\n id=\"withdraw-account\"\n value={withdrawAccountId}\n onChange={(e) => setWithdrawAccountId(e.target.value)}\n className={fieldClass}\n required\n >\n <option value=\"\">Select a method…</option>\n {payoutAccounts.map((a) => (\n <option key={a.id} value={a.id}>\n {a.label} — {describePayoutAccount(a)}\n </option>\n ))}\n </select>\n </div>\n <div>\n <label htmlFor=\"withdraw-amount\" className={labelClass}>\n Amount ({currency}) *\n </label>\n <input\n id=\"withdraw-amount\"\n type=\"number\"\n min=\"0\"\n step=\"0.01\"\n value={withdrawAmount}\n onChange={(e) => setWithdrawAmount(e.target.value)}\n placeholder=\"0.00\"\n className={fieldClass}\n required\n />\n {summary && (\n <p className=\"mt-1 text-xs text-text-secondary\">\n Available: {formatMoney(summary.availableAmount, currency)}\n </p>\n )}\n </div>\n </div>\n <div>\n <label htmlFor=\"withdraw-notes\" className={labelClass}>\n Notes (optional)\n </label>\n <input\n id=\"withdraw-notes\"\n type=\"text\"\n value={withdrawNotes}\n onChange={(e) => setWithdrawNotes(e.target.value)}\n placeholder=\"Reference for this withdrawal\"\n className={fieldClass}\n />\n </div>\n <button\n type=\"submit\"\n disabled={requestPayout.isPending}\n className=\"rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:opacity-90 disabled:opacity-50 transition-opacity\"\n >\n {requestPayout.isPending ? 'Requesting…' : 'Request payout'}\n </button>\n </form>\n </GlassCard>\n )}\n\n {/* Summary metrics */}\n {summaryQuery.isLoading ? (\n <LoadingState label=\"Loading earnings summary…\" />\n ) : summaryQuery.isError ? (\n <ErrorState onRetry={() => void summaryQuery.refetch()} />\n ) : summary ? (\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 xl:grid-cols-4\">\n <MetricsCard\n featured\n icon={<Wallet className=\"h-5 w-5\" />}\n value={formatMoney(summary.availableAmount, currency)}\n label=\"Available to withdraw\"\n />\n <MetricsCard\n icon={<Clock className=\"h-5 w-5\" />}\n value={formatMoney(summary.reservedAmount, currency)}\n label=\"Reserved (clearing)\"\n />\n <MetricsCard\n icon={<BadgeCheck className=\"h-5 w-5\" />}\n value={formatMoney(summary.paidAmount, currency)}\n label=\"Paid out\"\n />\n <MetricsCard\n icon={<CircleDollarSign className=\"h-5 w-5\" />}\n value={formatMoney(summary.totalLifetimeAmount, currency)}\n label=\"Lifetime earnings\"\n />\n </div>\n ) : null}\n\n {/* Payout method + next-available horizon */}\n <div className=\"mt-4 grid grid-cols-1 gap-4 lg:grid-cols-2\">\n <GlassCard treatment=\"metric\" className=\"border-border-seam p-5\">\n <div className=\"flex items-center gap-2 text-text-secondary\">\n <Landmark className=\"h-4 w-4\" />\n <h3 className=\"text-xs font-medium uppercase tracking-wide\">Payout method</h3>\n </div>\n {payoutAccountsQuery.isLoading ? (\n <p className=\"mt-3 text-sm text-text-secondary\">Loading…</p>\n ) : defaultPayoutAccount ? (\n <div className=\"mt-3\">\n <div className=\"flex items-center gap-2\">\n <p className=\"text-sm font-semibold text-text-primary\">\n {defaultPayoutAccount.label}\n </p>\n {defaultPayoutAccount.isDefault && (\n <span className=\"rounded-full bg-bg-sunken px-2 py-0.5 text-[10px] text-text-secondary\">\n Default\n </span>\n )}\n <StatusBadge status={defaultPayoutAccount.status} />\n </div>\n <p className=\"mt-1 text-sm text-text-secondary\">\n {describePayoutAccount(defaultPayoutAccount)} · {defaultPayoutAccount.currency}\n </p>\n </div>\n ) : (\n <p className=\"mt-3 flex items-start gap-2 text-sm text-text-secondary\">\n <Info className=\"mt-0.5 h-4 w-4 shrink-0\" />\n No payout method on file. Add a verified bank / UPI / wallet destination in your\n billing settings to enable withdrawals.\n </p>\n )}\n </GlassCard>\n\n <GlassCard treatment=\"metric\" className=\"border-border-seam p-5\">\n <div className=\"flex items-center gap-2 text-text-secondary\">\n <Clock className=\"h-4 w-4\" />\n <h3 className=\"text-xs font-medium uppercase tracking-wide\">Next funds available</h3>\n </div>\n {reservedQuery.isLoading ? (\n <p className=\"mt-3 text-sm text-text-secondary\">Loading…</p>\n ) : nextAvailableAt ? (\n <div className=\"mt-3\">\n <p className=\"text-sm font-semibold text-text-primary\">\n {formatDate(nextAvailableAt, { hour: undefined, minute: undefined })}\n </p>\n <p className=\"mt-1 text-sm text-text-secondary\">\n Reserved royalties clear to your available balance on this date.\n </p>\n </div>\n ) : (\n <p className=\"mt-3 text-sm text-text-secondary\">\n No reserved royalties are currently pending clearance.\n </p>\n )}\n </GlassCard>\n </div>\n\n {/* Royalty ledger */}\n <div className=\"mt-6\">\n <div className=\"mb-3 flex flex-wrap items-center justify-between gap-3\">\n <h2 className=\"text-sm font-semibold text-text-primary\">Royalty ledger</h2>\n <select\n value={ledgerStatus}\n onChange={(e) => {\n setLedgerStatus(e.target.value as EarningsEntryStatus | '');\n setLedgerPage(0);\n }}\n aria-label=\"Filter ledger by status\"\n className=\"rounded-lg border border-border-subtle bg-bg-surface px-3 py-2 text-xs text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n >\n <option value=\"\">Any status</option>\n {LEDGER_STATUS_OPTIONS.map((s) => (\n <option key={s} value={s}>\n {formatEnumLabel(s)}\n </option>\n ))}\n </select>\n </div>\n\n {ledgerQuery.isLoading ? (\n <LoadingState label=\"Loading ledger…\" />\n ) : ledgerQuery.isError ? (\n <ErrorState onRetry={() => void ledgerQuery.refetch()} />\n ) : ledgerItems.length === 0 ? (\n <EmptyState\n icon={<ReceiptText className=\"h-12 w-12\" />}\n title=\"No royalty entries yet\"\n description={\n ledgerStatus\n ? 'No ledger entries match this status filter.'\n : 'Your titles have not generated any royalties on this billing account yet. Earnings appear here as they accrue.'\n }\n />\n ) : (\n <div className=\"overflow-x-auto rounded-lg border border-border-seam bg-bg-surface\">\n <table className=\"w-full min-w-[36rem] text-sm\">\n <thead>\n <tr className=\"border-b border-border-seam text-left text-xs text-text-secondary\">\n <th className=\"px-4 py-3 font-medium\">Date</th>\n <th className=\"px-4 py-3 font-medium\">Source</th>\n <th className=\"px-4 py-3 text-right font-medium\">Amount</th>\n <th className=\"px-4 py-3 font-medium\">Status</th>\n </tr>\n </thead>\n <tbody className=\"divide-y divide-border-seam\">\n {ledgerItems.map((entry) => (\n <tr key={entry.id} className=\"hover:bg-bg-sunken transition-colors\">\n <td className=\"whitespace-nowrap px-4 py-3 text-text-secondary\">\n {formatDate(entry.createdAt, { hour: undefined, minute: undefined })}\n </td>\n <td className=\"px-4 py-3\">\n <p className=\"font-medium text-text-primary\">\n {formatEnumLabel(entry.sourceCategory)}\n </p>\n {entry.description && (\n <p className=\"line-clamp-1 text-xs text-text-secondary\">\n {entry.description}\n </p>\n )}\n </td>\n <td className=\"whitespace-nowrap px-4 py-3 text-right font-medium tabular-nums text-text-primary\">\n {formatMoney(entry.amount, entry.currency)}\n </td>\n <td className=\"px-4 py-3\">\n <StatusBadge status={entry.status} />\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n )}\n\n {!ledgerQuery.isLoading && !ledgerQuery.isError && (\n <Pagination\n page={ledgerPage}\n hasMore={ledgerQuery.data?.hasMore ?? false}\n onPageChange={setLedgerPage}\n shownCount={ledgerItems.length}\n />\n )}\n </div>\n\n {/* Payout / withdrawal history */}\n <div className=\"mt-8\">\n <h2 className=\"mb-3 text-sm font-semibold text-text-primary\">Withdrawal history</h2>\n {payoutRequestsQuery.isLoading ? (\n <LoadingState label=\"Loading withdrawals…\" />\n ) : payoutRequestsQuery.isError ? (\n <ErrorState onRetry={() => void payoutRequestsQuery.refetch()} />\n ) : payoutItems.length === 0 ? (\n <EmptyState\n icon={<Coins className=\"h-12 w-12\" />}\n title=\"No withdrawals yet\"\n description=\"When you request a payout, each withdrawal and its status will be listed here.\"\n />\n ) : (\n <div className=\"overflow-x-auto rounded-lg border border-border-seam bg-bg-surface\">\n <table className=\"w-full min-w-[36rem] text-sm\">\n <thead>\n <tr className=\"border-b border-border-seam text-left text-xs text-text-secondary\">\n <th className=\"px-4 py-3 font-medium\">Requested</th>\n <th className=\"px-4 py-3 text-right font-medium\">Amount</th>\n <th className=\"px-4 py-3 font-medium\">Provider</th>\n <th className=\"px-4 py-3 font-medium\">Status</th>\n <th className=\"hidden px-4 py-3 font-medium md:table-cell\">Paid</th>\n </tr>\n </thead>\n <tbody className=\"divide-y divide-border-seam\">\n {payoutItems.map((req) => (\n <tr key={req.id} className=\"hover:bg-bg-sunken transition-colors\">\n <td className=\"whitespace-nowrap px-4 py-3 text-text-secondary\">\n {formatDate(req.createdAt, { hour: undefined, minute: undefined })}\n </td>\n <td className=\"whitespace-nowrap px-4 py-3 text-right font-medium tabular-nums text-text-primary\">\n {formatMoney(req.approvedAmount ?? req.requestedAmount, req.currency)}\n </td>\n <td className=\"px-4 py-3 text-text-secondary\">\n {req.provider ? formatEnumLabel(req.provider) : '—'}\n </td>\n <td className=\"px-4 py-3\">\n <StatusBadge status={req.status} />\n </td>\n <td className=\"hidden whitespace-nowrap px-4 py-3 text-text-secondary md:table-cell\">\n {req.paidAt\n ? formatDate(req.paidAt, { hour: undefined, minute: undefined })\n : '—'}\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n )}\n\n {!payoutRequestsQuery.isLoading && !payoutRequestsQuery.isError && (\n <Pagination\n page={payoutsPage}\n hasMore={payoutRequestsQuery.data?.hasMore ?? false}\n onPageChange={setPayoutsPage}\n shownCount={payoutItems.length}\n />\n )}\n </div>\n </PageLayout>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;AAmDA,IAAM,IAAe,IACf,IAAgB,IAEhB,KAA+C;CAAC;CAAa;CAAY;CAAQ;CAAW,EAE5F,IACJ,wMACI,IAAa;AAGnB,SAAS,EAAY,GAAgB,GAA0B;AAC7D,KAAI;AACF,SAAO,IAAI,KAAK,aAAa,KAAA,GAAW;GAAE,OAAO;GAAY;GAAU,CAAC,CAAC,OAAO,EAAO;SACjF;AACN,SAAO,GAAG,EAAO,QAAQ,EAAE,CAAC,GAAG;;;AAKnC,SAAS,EAAsB,GAAgC;CAC7D,IAAM,IAAQ,CAAC,EAAgB,EAAQ,KAAK,CAAC;AAI7C,QAHI,EAAQ,gBACV,EAAM,KAAK,OAAO,EAAQ,eAAe,EAEpC,EAAM,KAAK,MAAM;;AAG1B,IAAa,UAAwB;CACnC,IAAM,IAAc,IAAgB,EAE9B,IAAgB,IAAsB,EACtC,IAAW,QAAc,EAAc,QAAQ,EAAE,EAAE,CAAC,EAAc,KAAK,CAAC,EAGxE,KAAmB,QAAc;AACjC,QAAS,WAAW,EACxB,SAAQ,EAAS,MAAM,MAAM,EAAE,UAAU,IAAI,EAAS,IAAI;IACzD,CAAC,EAAS,CAAC,EACR,CAAC,IAAmB,MAAwB,EAAwB,KAAK,EACzE,IAAmB,MAAqB,IACxC,KAAgB,EAAS,MAAM,MAAM,EAAE,OAAO,EAAiB,EAE/D,CAAC,GAAc,MAAmB,EAAmC,GAAG,EACxE,CAAC,GAAY,KAAiB,EAAS,EAAE,EACzC,CAAC,GAAa,KAAkB,EAAS,EAAE,EAC3C,CAAC,IAAc,KAAmB,EAAS,GAAM,EACjD,CAAC,GAAmB,KAAwB,EAAS,GAAG,EACxD,CAAC,GAAgB,KAAqB,EAAS,GAAG,EAClD,CAAC,GAAe,KAAoB,EAAS,GAAG,EAChD,CAAC,GAAe,KAAoB,EAAwB,KAAK,EAEjE,IAAe,GAAqB,EAAiB,EACrD,IAAsB,GAAoB,EAAiB,EAC3D,IAAc,EAClB,GACA,IAAe,EAAE,QAAQ,GAAc,GAAG,KAAA,GAC1C,GACA,IAAa,EACd,EACK,IAAsB,GAC1B,GACA,GACA,IAAc,EACf,EAGK,IAAgB,EAAqB,GAAkB,EAAE,QAAQ,YAAY,EAAE,KAAK,EAAE,EACtF,IAAgB,IAAkB,EAElC,IAAU,EAAa,MACvB,IAAiB,EAAoB,QAAQ,EAAE,EAC/C,IAAuB,EAAe,MAAM,MAAM,EAAE,UAAU,IAAI,EAAe,MAAM,MAGvF,IAAW,IAAe,YAAY,EAAY,MAAM,MAAM,IAAI,YAAY,OAE9E,IAAkB,QAAc;EACpC,IAAM,IAAM,KAAK,KAAK;AAKtB,UAJkB,EAAc,MAAM,SAAS,EAAE,EAC9C,KAAK,OAAO;GAAE,KAAK,EAAE;GAAa,GAAG,IAAI,KAAK,EAAE,YAAY,CAAC,SAAS;GAAE,EAAE,CAC1E,QAAQ,MAAM,OAAO,SAAS,EAAE,EAAE,IAAI,EAAE,KAAK,EAAI,CACjD,MAAM,GAAG,MAAM,EAAE,IAAI,EAAE,EAAE,CACZ,IAAI,OAAO;IAC1B,CAAC,EAAc,KAAK,CAAC,EAElB,WAAqB;AAOzB,EANA,EAAiB,KAAK,EACtB,EAAqB,GAAsB,MAAM,GAAG,EACpD,EACE,KAAW,EAAQ,kBAAkB,IAAI,OAAO,EAAQ,gBAAgB,GAAG,GAC5E,EACD,EAAiB,GAAG,EACpB,EAAgB,GAAK;IAGjB,KAAiB,OAAO,MAAiB;AAG7C,MAFA,EAAE,gBAAgB,EAClB,EAAiB,KAAK,EAClB,CAAC,EAAkB;AACvB,MAAI,CAAC,GAAmB;AACtB,KAAiB,0BAA0B;AAC3C;;EAEF,IAAM,IAAS,OAAO,EAAe;AACrC,MAAI,CAAC,OAAO,SAAS,EAAO,IAAI,KAAU,GAAG;AAC3C,KAAiB,0CAA0C;AAC3D;;AAEF,MAAI,KAAW,IAAS,EAAQ,iBAAiB;AAC/C,KACE,0CAA0C,EAAY,EAAQ,iBAAiB,EAAS,CAAC,IAC1F;AACD;;AAEF,MAAI;AAgBF,GAfA,MAAM,EAAc,YAAY;IAC9B;IACA,iBAAiB;IACjB;IACA;IACA,OAAO,EAAc,MAAM,IAAI,KAAA;IAChC,CAAC,EAIG,EAAY,kBAAkB,EAAE,UAAU,CAAC,cAAc,mBAAmB,EAAE,CAAC,EAC/E,EAAY,kBAAkB,EACjC,UAAU;IAAC;IAAc;IAAmB;IAAiB,EAC9D,CAAC,EACF,EAAgB,GAAM,EACtB,EAAe,EAAE;WACV,GAAK;AACZ,KAAiB,aAAe,QAAQ,EAAI,UAAU,wBAAwB;;;AAMlF,KAAI,EAAc,UAChB,QACE,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;YAEZ,kBAAC,GAAD,EAAc,OAAM,iCAAkC,CAAA;EAC3C,CAAA;AAIjB,KAAI,EAAc,QAChB,QACE,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;YAEZ,kBAAC,GAAD,EAAY,eAAe,KAAK,EAAc,SAAS,EAAI,CAAA;EAChD,CAAA;AAIjB,KAAI,CAAC,EACH,QACE,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;EACZ,SAAQ;YAER,kBAAC,GAAD;GACE,MAAM,kBAAC,GAAD,EAAQ,WAAU,aAAc,CAAA;GACtC,OAAM;GACN,aAAY;GACZ,CAAA;EACS,CAAA;CAIjB,IAAM,IAAc,EAAY,MAAM,SAAS,EAAE,EAC3C,IAAc,EAAoB,MAAM,SAAS,EAAE,EACnD,KAAc,GAAQ,KAAW,EAAQ,kBAAkB,MAAM,EAAe,SAAS;AAE/F,QACE,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;EACZ,SAAQ;EACR,SACE,kBAAC,OAAD;GAAK,WAAU;aAAf,CACG,EAAS,SAAS,KACjB,kBAAC,UAAD;IACE,OAAO;IACP,WAAW,MAAM;AAGf,KAFA,GAAqB,EAAE,OAAO,MAAM,EACpC,EAAc,EAAE,EAChB,EAAe,EAAE;;IAEnB,cAAW;IACX,WAAU;cAET,EAAS,KAAK,MACb,kBAAC,UAAD;KAAmB,OAAO,EAAE;eACzB,EAAE,QAAQ,EAAE;KACN,EAFI,EAAE,GAEN,CACT;IACK,CAAA,EAEX,kBAAC,UAAD;IACE,MAAK;IACL,SAAS;IACT,UAAU,CAAC;IACX,WAAU;cAJZ,CAME,kBAAC,IAAD,EAAiB,WAAU,WAAY,CAAA,EAAA,WAEhC;MACL;;YAjCV;GAqCG,MACC,kBAAC,GAAD;IAAW,WAAU;IAAQ,WAAU;cAAvC,CACE,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,MAAD;MAAI,WAAU;gBAA0C;MAA+B,CAAA,EACvF,kBAAC,UAAD;MACE,MAAK;MACL,eAAe,EAAgB,GAAM;MACrC,WAAU;MACV,cAAW;gBAEX,kBAAC,IAAD,EAAG,WAAU,WAAY,CAAA;MAClB,CAAA,CACL;QACN,kBAAC,QAAD;KAAM,UAAU;KAAgB,WAAU;eAA1C;MACG,KACC,kBAAC,OAAD;OAAK,WAAU;iBACZ;OACG,CAAA;MAER,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;QAAO,SAAQ;QAAmB,WAAW;kBAAY;QAEjD,CAAA,EACR,kBAAC,UAAD;QACE,IAAG;QACH,OAAO;QACP,WAAW,MAAM,EAAqB,EAAE,OAAO,MAAM;QACrD,WAAW;QACX,UAAA;kBALF,CAOE,kBAAC,UAAD;SAAQ,OAAM;mBAAG;SAAyB,CAAA,EACzC,EAAe,KAAK,MACnB,kBAAC,UAAD;SAAmB,OAAO,EAAE;mBAA5B;UACG,EAAE;UAAM;UAAI,EAAsB,EAAE;UAC9B;WAFI,EAAE,GAEN,CACT,CACK;UACL,EAAA,CAAA,EACN,kBAAC,OAAD,EAAA,UAAA;QACE,kBAAC,SAAD;SAAO,SAAQ;SAAkB,WAAW;mBAA5C;UAAwD;UAC7C;UAAS;UACZ;;QACR,kBAAC,SAAD;SACE,IAAG;SACH,MAAK;SACL,KAAI;SACJ,MAAK;SACL,OAAO;SACP,WAAW,MAAM,EAAkB,EAAE,OAAO,MAAM;SAClD,aAAY;SACZ,WAAW;SACX,UAAA;SACA,CAAA;QACD,KACC,kBAAC,KAAD;SAAG,WAAU;mBAAb,CAAgD,eAClC,EAAY,EAAQ,iBAAiB,EAAS,CACxD;;QAEF,EAAA,CAAA,CACF;;MACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;OAAO,SAAQ;OAAiB,WAAW;iBAAY;OAE/C,CAAA,EACR,kBAAC,SAAD;OACE,IAAG;OACH,MAAK;OACL,OAAO;OACP,WAAW,MAAM,EAAiB,EAAE,OAAO,MAAM;OACjD,aAAY;OACZ,WAAW;OACX,CAAA,CACE,EAAA,CAAA;MACN,kBAAC,UAAD;OACE,MAAK;OACL,UAAU,EAAc;OACxB,WAAU;iBAET,EAAc,YAAY,gBAAgB;OACpC,CAAA;MACJ;OACG;;GAIb,EAAa,YACZ,kBAAC,GAAD,EAAc,OAAM,6BAA8B,CAAA,GAChD,EAAa,UACf,kBAAC,GAAD,EAAY,eAAe,KAAK,EAAa,SAAS,EAAI,CAAA,GACxD,IACF,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,GAAD;MACE,UAAA;MACA,MAAM,kBAAC,GAAD,EAAQ,WAAU,WAAY,CAAA;MACpC,OAAO,EAAY,EAAQ,iBAAiB,EAAS;MACrD,OAAM;MACN,CAAA;KACF,kBAAC,GAAD;MACE,MAAM,kBAAC,GAAD,EAAO,WAAU,WAAY,CAAA;MACnC,OAAO,EAAY,EAAQ,gBAAgB,EAAS;MACpD,OAAM;MACN,CAAA;KACF,kBAAC,GAAD;MACE,MAAM,kBAAC,IAAD,EAAY,WAAU,WAAY,CAAA;MACxC,OAAO,EAAY,EAAQ,YAAY,EAAS;MAChD,OAAM;MACN,CAAA;KACF,kBAAC,GAAD;MACE,MAAM,kBAAC,IAAD,EAAkB,WAAU,WAAY,CAAA;MAC9C,OAAO,EAAY,EAAQ,qBAAqB,EAAS;MACzD,OAAM;MACN,CAAA;KACE;QACJ;GAGJ,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,GAAD;KAAW,WAAU;KAAS,WAAU;eAAxC,CACE,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,IAAD,EAAU,WAAU,WAAY,CAAA,EAChC,kBAAC,MAAD;OAAI,WAAU;iBAA8C;OAAkB,CAAA,CAC1E;SACL,EAAoB,YACnB,kBAAC,KAAD;MAAG,WAAU;gBAAmC;MAAY,CAAA,GAC1D,IACF,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,OAAD;OAAK,WAAU;iBAAf;QACE,kBAAC,KAAD;SAAG,WAAU;mBACV,EAAqB;SACpB,CAAA;QACH,EAAqB,aACpB,kBAAC,QAAD;SAAM,WAAU;mBAAwE;SAEjF,CAAA;QAET,kBAAC,GAAD,EAAa,QAAQ,EAAqB,QAAU,CAAA;QAChD;UACN,kBAAC,KAAD;OAAG,WAAU;iBAAb;QACG,EAAsB,EAAqB;QAAC;QAAI,EAAqB;QACpE;SACA;UAEN,kBAAC,KAAD;MAAG,WAAU;gBAAb,CACE,kBAAC,IAAD,EAAM,WAAU,2BAA4B,CAAA,EAAA,2HAG1C;QAEI;QAEZ,kBAAC,GAAD;KAAW,WAAU;KAAS,WAAU;eAAxC,CACE,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,GAAD,EAAO,WAAU,WAAY,CAAA,EAC7B,kBAAC,MAAD;OAAI,WAAU;iBAA8C;OAAyB,CAAA,CACjF;SACL,EAAc,YACb,kBAAC,KAAD;MAAG,WAAU;gBAAmC;MAAY,CAAA,GAC1D,IACF,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,KAAD;OAAG,WAAU;iBACV,EAAW,GAAiB;QAAE,MAAM,KAAA;QAAW,QAAQ,KAAA;QAAW,CAAC;OAClE,CAAA,EACJ,kBAAC,KAAD;OAAG,WAAU;iBAAmC;OAE5C,CAAA,CACA;UAEN,kBAAC,KAAD;MAAG,WAAU;gBAAmC;MAE5C,CAAA,CAEI;OACR;;GAGN,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,MAAD;OAAI,WAAU;iBAA0C;OAAmB,CAAA,EAC3E,kBAAC,UAAD;OACE,OAAO;OACP,WAAW,MAAM;AAEf,QADA,GAAgB,EAAE,OAAO,MAAkC,EAC3D,EAAc,EAAE;;OAElB,cAAW;OACX,WAAU;iBAPZ,CASE,kBAAC,UAAD;QAAQ,OAAM;kBAAG;QAAmB,CAAA,EACnC,GAAsB,KAAK,MAC1B,kBAAC,UAAD;QAAgB,OAAO;kBACpB,EAAgB,EAAE;QACZ,EAFI,EAEJ,CACT,CACK;SACL;;KAEL,EAAY,YACX,kBAAC,GAAD,EAAc,OAAM,mBAAoB,CAAA,GACtC,EAAY,UACd,kBAAC,GAAD,EAAY,eAAe,KAAK,EAAY,SAAS,EAAI,CAAA,GACvD,EAAY,WAAW,IACzB,kBAAC,GAAD;MACE,MAAM,kBAAC,IAAD,EAAa,WAAU,aAAc,CAAA;MAC3C,OAAM;MACN,aACE,IACI,gDACA;MAEN,CAAA,GAEF,kBAAC,OAAD;MAAK,WAAU;gBACb,kBAAC,SAAD;OAAO,WAAU;iBAAjB,CACE,kBAAC,SAAD,EAAA,UACE,kBAAC,MAAD;QAAI,WAAU;kBAAd;SACE,kBAAC,MAAD;UAAI,WAAU;oBAAwB;UAAS,CAAA;SAC/C,kBAAC,MAAD;UAAI,WAAU;oBAAwB;UAAW,CAAA;SACjD,kBAAC,MAAD;UAAI,WAAU;oBAAmC;UAAW,CAAA;SAC5D,kBAAC,MAAD;UAAI,WAAU;oBAAwB;UAAW,CAAA;SAC9C;WACC,CAAA,EACR,kBAAC,SAAD;QAAO,WAAU;kBACd,EAAY,KAAK,MAChB,kBAAC,MAAD;SAAmB,WAAU;mBAA7B;UACE,kBAAC,MAAD;WAAI,WAAU;qBACX,EAAW,EAAM,WAAW;YAAE,MAAM,KAAA;YAAW,QAAQ,KAAA;YAAW,CAAC;WACjE,CAAA;UACL,kBAAC,MAAD;WAAI,WAAU;qBAAd,CACE,kBAAC,KAAD;YAAG,WAAU;sBACV,EAAgB,EAAM,eAAe;YACpC,CAAA,EACH,EAAM,eACL,kBAAC,KAAD;YAAG,WAAU;sBACV,EAAM;YACL,CAAA,CAEH;;UACL,kBAAC,MAAD;WAAI,WAAU;qBACX,EAAY,EAAM,QAAQ,EAAM,SAAS;WACvC,CAAA;UACL,kBAAC,MAAD;WAAI,WAAU;qBACZ,kBAAC,GAAD,EAAa,QAAQ,EAAM,QAAU,CAAA;WAClC,CAAA;UACF;WApBI,EAAM,GAoBV,CACL;QACI,CAAA,CACF;;MACJ,CAAA;KAGP,CAAC,EAAY,aAAa,CAAC,EAAY,WACtC,kBAAC,GAAD;MACE,MAAM;MACN,SAAS,EAAY,MAAM,WAAW;MACtC,cAAc;MACd,YAAY,EAAY;MACxB,CAAA;KAEA;;GAGN,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,MAAD;MAAI,WAAU;gBAA+C;MAAuB,CAAA;KACnF,EAAoB,YACnB,kBAAC,GAAD,EAAc,OAAM,wBAAyB,CAAA,GAC3C,EAAoB,UACtB,kBAAC,GAAD,EAAY,eAAe,KAAK,EAAoB,SAAS,EAAI,CAAA,GAC/D,EAAY,WAAW,IACzB,kBAAC,GAAD;MACE,MAAM,kBAAC,IAAD,EAAO,WAAU,aAAc,CAAA;MACrC,OAAM;MACN,aAAY;MACZ,CAAA,GAEF,kBAAC,OAAD;MAAK,WAAU;gBACb,kBAAC,SAAD;OAAO,WAAU;iBAAjB,CACE,kBAAC,SAAD,EAAA,UACE,kBAAC,MAAD;QAAI,WAAU;kBAAd;SACE,kBAAC,MAAD;UAAI,WAAU;oBAAwB;UAAc,CAAA;SACpD,kBAAC,MAAD;UAAI,WAAU;oBAAmC;UAAW,CAAA;SAC5D,kBAAC,MAAD;UAAI,WAAU;oBAAwB;UAAa,CAAA;SACnD,kBAAC,MAAD;UAAI,WAAU;oBAAwB;UAAW,CAAA;SACjD,kBAAC,MAAD;UAAI,WAAU;oBAA6C;UAAS,CAAA;SACjE;WACC,CAAA,EACR,kBAAC,SAAD;QAAO,WAAU;kBACd,EAAY,KAAK,MAChB,kBAAC,MAAD;SAAiB,WAAU;mBAA3B;UACE,kBAAC,MAAD;WAAI,WAAU;qBACX,EAAW,EAAI,WAAW;YAAE,MAAM,KAAA;YAAW,QAAQ,KAAA;YAAW,CAAC;WAC/D,CAAA;UACL,kBAAC,MAAD;WAAI,WAAU;qBACX,EAAY,EAAI,kBAAkB,EAAI,iBAAiB,EAAI,SAAS;WAClE,CAAA;UACL,kBAAC,MAAD;WAAI,WAAU;qBACX,EAAI,WAAW,EAAgB,EAAI,SAAS,GAAG;WAC7C,CAAA;UACL,kBAAC,MAAD;WAAI,WAAU;qBACZ,kBAAC,GAAD,EAAa,QAAQ,EAAI,QAAU,CAAA;WAChC,CAAA;UACL,kBAAC,MAAD;WAAI,WAAU;qBACX,EAAI,SACD,EAAW,EAAI,QAAQ;YAAE,MAAM,KAAA;YAAW,QAAQ,KAAA;YAAW,CAAC,GAC9D;WACD,CAAA;UACF;WAlBI,EAAI,GAkBR,CACL;QACI,CAAA,CACF;;MACJ,CAAA;KAGP,CAAC,EAAoB,aAAa,CAAC,EAAoB,WACtD,kBAAC,GAAD;MACE,MAAM;MACN,SAAS,EAAoB,MAAM,WAAW;MAC9C,cAAc;MACd,YAAY,EAAY;MACxB,CAAA;KAEA;;GACK"}
|