@fantastic.dev/better-stripe 0.19.0 → 0.20.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +22 -3
  3. package/dist/client/connect/transferReceipt.d.ts.map +1 -1
  4. package/dist/client/connect/transferReceipt.js +1 -14
  5. package/dist/client/connect/transferReceipt.js.map +1 -1
  6. package/dist/component/_generated/component.d.ts +297 -0
  7. package/dist/component/_generated/component.d.ts.map +1 -1
  8. package/dist/component/earnings/triggers.d.ts +134 -0
  9. package/dist/component/earnings/triggers.d.ts.map +1 -1
  10. package/dist/component/payoutRelease/allocation.d.ts +48 -0
  11. package/dist/component/payoutRelease/allocation.d.ts.map +1 -0
  12. package/dist/component/payoutRelease/allocation.js +98 -0
  13. package/dist/component/payoutRelease/allocation.js.map +1 -0
  14. package/dist/component/payoutRelease/helpers.d.ts +106 -0
  15. package/dist/component/payoutRelease/helpers.d.ts.map +1 -0
  16. package/dist/component/payoutRelease/helpers.js +119 -0
  17. package/dist/component/payoutRelease/helpers.js.map +1 -0
  18. package/dist/component/payoutRelease/mutations.d.ts +218 -0
  19. package/dist/component/payoutRelease/mutations.d.ts.map +1 -0
  20. package/dist/component/payoutRelease/mutations.js +254 -0
  21. package/dist/component/payoutRelease/mutations.js.map +1 -0
  22. package/dist/component/payoutRelease/queries.d.ts +84 -0
  23. package/dist/component/payoutRelease/queries.d.ts.map +1 -0
  24. package/dist/component/payoutRelease/queries.js +51 -0
  25. package/dist/component/payoutRelease/queries.js.map +1 -0
  26. package/dist/component/payoutRelease/schema.d.ts +289 -0
  27. package/dist/component/payoutRelease/schema.d.ts.map +1 -0
  28. package/dist/component/payoutRelease/schema.js +56 -0
  29. package/dist/component/payoutRelease/schema.js.map +1 -0
  30. package/dist/component/schema.d.ts +110 -0
  31. package/dist/component/schema.js +3 -0
  32. package/dist/component/schema.js.map +1 -1
  33. package/docs/accounts-v2-preview.md +39 -1
  34. package/docs/react-workflows.md +31 -0
  35. package/docs/settlement.md +31 -0
  36. package/package.json +1 -1
  37. package/src/client/connect/payoutAllocation.test.ts +292 -0
  38. package/src/client/connect/transferReceipt.ts +1 -14
  39. package/src/component/_generated/api.ts +8 -0
  40. package/src/component/_generated/component.ts +372 -0
  41. package/src/component/payout-release.test.ts +588 -0
  42. package/src/component/payoutRelease/allocation.ts +147 -0
  43. package/src/component/payoutRelease/helpers.ts +168 -0
  44. package/src/component/payoutRelease/mutations.ts +309 -0
  45. package/src/component/payoutRelease/queries.ts +56 -0
  46. package/src/component/payoutRelease/schema.ts +69 -0
  47. package/src/component/schema.ts +6 -0
@@ -0,0 +1,254 @@
1
+ import { v } from "convex/values";
2
+ import { mutation } from "../_generated/server.js";
3
+ import { identity, observation, claimDoc } from "./schema.js";
4
+ import { claimByKey, readyPolicy, checkSnapshot, sourceById, moveAllocations, validateIdentity, add, } from "./helpers.js";
5
+ import { planRecipientPayout } from "./allocation.js";
6
+ const held = v.object({
7
+ status: v.literal("held"),
8
+ reason: v.union(v.literal("below_threshold"), v.literal("insufficient_available"), v.literal("pending_claim")),
9
+ amount: v.literal(0),
10
+ matureUnpaid: v.optional(v.number()),
11
+ pendingCredits: v.optional(v.number()),
12
+ currency: v.string(),
13
+ providerMinimum: v.null(),
14
+ });
15
+ /** Trusted server package boundary only: provider observations are verified upstream. Not a Stripe executor. */
16
+ export const claim = mutation({
17
+ args: {
18
+ ...identity,
19
+ expectedRevision: v.number(),
20
+ currency: v.string(),
21
+ providerAvailable: v.number(),
22
+ independentLiabilities: v.number(),
23
+ observations: v.array(observation),
24
+ },
25
+ returns: v.union(claimDoc, held),
26
+ handler: async (ctx, args) => {
27
+ validateIdentity(args);
28
+ const existing = await claimByKey(ctx, args);
29
+ if (existing) {
30
+ if (existing.currency !== args.currency ||
31
+ existing.expectedRevision !== args.expectedRevision)
32
+ throw new Error("Payout claim identity cannot be reused.");
33
+ return existing;
34
+ }
35
+ const policy = await readyPolicy(ctx, args);
36
+ const minimum = policy.thresholds.find((value) => value.currency === args.currency);
37
+ if (!minimum)
38
+ throw new Error("Payout policy currency is not configured.");
39
+ const pending = await ctx.db
40
+ .query("payoutReleaseClaims")
41
+ .withIndex("by_account_status", (q) => q.eq("accountId", args.accountId).eq("status", "reserved"))
42
+ .first();
43
+ if (pending)
44
+ return {
45
+ status: "held",
46
+ reason: "pending_claim",
47
+ amount: 0,
48
+ currency: args.currency,
49
+ providerMinimum: null,
50
+ };
51
+ const rows = await checkSnapshot(ctx, args.accountId, args.observations, true);
52
+ const sources = [];
53
+ for (const observation of args.observations) {
54
+ const prior = await sourceById(ctx, observation.stripeTransferId);
55
+ if (prior &&
56
+ (prior.accountId !== args.accountId ||
57
+ prior.ownerKey !== args.ownerKey ||
58
+ prior.currency !== observation.currency))
59
+ throw new Error("Payout source allocation identity changed.");
60
+ sources.push({
61
+ ...observation,
62
+ role: rows.get(observation.stripeTransferId).role,
63
+ paidAmount: prior?.paidAmount ?? 0,
64
+ reservedAmount: prior?.reservedAmount ?? 0,
65
+ });
66
+ }
67
+ const plan = planRecipientPayout({
68
+ currency: args.currency,
69
+ threshold: minimum.amount,
70
+ providerAvailable: args.providerAvailable,
71
+ independentLiabilities: args.independentLiabilities,
72
+ sources,
73
+ });
74
+ if (plan.status === "held")
75
+ return plan;
76
+ for (const allocation of plan.allocations) {
77
+ const prior = await sourceById(ctx, allocation.stripeTransferId);
78
+ if (prior)
79
+ await ctx.db.patch("payoutSourceAllocations", prior._id, {
80
+ reservedAmount: add(prior.reservedAmount, allocation.amount),
81
+ });
82
+ else
83
+ await ctx.db.insert("payoutSourceAllocations", {
84
+ accountId: args.accountId,
85
+ ownerKey: args.ownerKey,
86
+ stripeTransferId: allocation.stripeTransferId,
87
+ currency: args.currency,
88
+ paidAmount: 0,
89
+ reservedAmount: allocation.amount,
90
+ });
91
+ }
92
+ const id = await ctx.db.insert("payoutReleaseClaims", {
93
+ accountId: args.accountId,
94
+ ownerKey: args.ownerKey,
95
+ operationKey: args.operationKey,
96
+ expectedRevision: args.expectedRevision,
97
+ currency: args.currency,
98
+ amount: plan.amount,
99
+ allocations: plan.allocations,
100
+ observations: args.observations,
101
+ status: "reserved",
102
+ });
103
+ return (await ctx.db.get("payoutReleaseClaims", id));
104
+ },
105
+ });
106
+ export const beginAttempt = mutation({
107
+ args: identity,
108
+ returns: claimDoc,
109
+ handler: async (ctx, args) => {
110
+ const claim = await claimByKey(ctx, args);
111
+ if (!claim || claim.status !== "reserved")
112
+ throw new Error("Payout claim is not reserved.");
113
+ if (claim.attemptedAt !== undefined)
114
+ return claim;
115
+ await readyPolicy(ctx, claim);
116
+ await checkSnapshot(ctx, claim.accountId, claim.observations, true);
117
+ await ctx.db.patch("payoutReleaseClaims", claim._id, {
118
+ attemptedAt: Date.now(),
119
+ });
120
+ return (await ctx.db.get("payoutReleaseClaims", claim._id));
121
+ },
122
+ });
123
+ export const cancelUnattempted = mutation({
124
+ args: identity,
125
+ returns: claimDoc,
126
+ handler: async (ctx, args) => {
127
+ const claim = await claimByKey(ctx, args);
128
+ if (!claim ||
129
+ claim.attemptedAt !== undefined ||
130
+ (claim.status !== "reserved" && claim.status !== "canceled"))
131
+ throw new Error("An attempted payout claim cannot be canceled.");
132
+ if (claim.status === "canceled")
133
+ return claim;
134
+ await moveAllocations(ctx, claim, "release");
135
+ await ctx.db.patch("payoutReleaseClaims", claim._id, {
136
+ status: "canceled",
137
+ });
138
+ return (await ctx.db.get("payoutReleaseClaims", claim._id));
139
+ },
140
+ });
141
+ export const recordOutcome = mutation({
142
+ args: {
143
+ ...identity,
144
+ stripePayoutId: v.string(),
145
+ amount: v.number(),
146
+ currency: v.string(),
147
+ providerStatus: v.union(v.literal("pending"), v.literal("in_transit"), v.literal("paid"), v.literal("failed"), v.literal("canceled")),
148
+ returnTransactionId: v.optional(v.string()),
149
+ },
150
+ returns: claimDoc,
151
+ handler: async (ctx, args) => {
152
+ const claim = await claimByKey(ctx, args);
153
+ if (!claim ||
154
+ claim.attemptedAt === undefined ||
155
+ claim.status === "canceled" ||
156
+ claim.status === "rejected")
157
+ throw new Error("Payout receipt has no attempted claim.");
158
+ if (!/^po_\w+$/.test(args.stripePayoutId) ||
159
+ args.stripePayoutId.trim() !== args.stripePayoutId ||
160
+ args.currency !== claim.currency ||
161
+ args.amount !== claim.amount ||
162
+ (claim.stripePayoutId !== undefined &&
163
+ claim.stripePayoutId !== args.stripePayoutId))
164
+ throw new Error("Payout receipt identity or amount does not match.");
165
+ const adopted = await ctx.db
166
+ .query("payoutReleaseClaims")
167
+ .withIndex("by_provider_payout", (q) => q.eq("stripePayoutId", args.stripePayoutId))
168
+ .unique();
169
+ if (adopted && adopted._id !== claim._id)
170
+ throw new Error("Payout receipt identity is already allocated.");
171
+ if (args.returnTransactionId !== undefined &&
172
+ (!/^txn_\w+$/.test(args.returnTransactionId) ||
173
+ args.returnTransactionId.trim() !== args.returnTransactionId))
174
+ throw new Error("Invalid payout return receipt identity.");
175
+ const returned = (args.providerStatus === "failed" ||
176
+ args.providerStatus === "canceled") &&
177
+ args.returnTransactionId !== undefined;
178
+ if (returned) {
179
+ const adoptedReturn = await ctx.db
180
+ .query("payoutReleaseClaims")
181
+ .withIndex("by_return_receipt", (q) => q.eq("returnTransactionId", args.returnTransactionId))
182
+ .unique();
183
+ if (adoptedReturn && adoptedReturn._id !== claim._id)
184
+ throw new Error("Payout return receipt is already allocated.");
185
+ }
186
+ if (claim.status === "returned") {
187
+ if (returned && args.returnTransactionId !== claim.returnTransactionId)
188
+ throw new Error("Payout return receipt identity changed.");
189
+ return claim;
190
+ }
191
+ if (returned) {
192
+ await moveAllocations(ctx, claim, claim.status === "paid" ? "return" : "release");
193
+ await ctx.db.patch("payoutReleaseClaims", claim._id, {
194
+ status: "returned",
195
+ stripePayoutId: args.stripePayoutId,
196
+ returnTransactionId: args.returnTransactionId,
197
+ });
198
+ }
199
+ else if (args.providerStatus === "paid" && claim.status !== "paid") {
200
+ await moveAllocations(ctx, claim, "pay");
201
+ await ctx.db.patch("payoutReleaseClaims", claim._id, {
202
+ status: "paid",
203
+ stripePayoutId: args.stripePayoutId,
204
+ });
205
+ }
206
+ else if (claim.status !== "paid") {
207
+ await ctx.db.patch("payoutReleaseClaims", claim._id, {
208
+ status: "submitted",
209
+ stripePayoutId: args.stripePayoutId,
210
+ });
211
+ }
212
+ return (await ctx.db.get("payoutReleaseClaims", claim._id));
213
+ },
214
+ });
215
+ /** Only a verified, no-object rejection within the original idempotency window. */
216
+ export const recordRejection = mutation({
217
+ args: {
218
+ ...identity,
219
+ requestId: v.string(),
220
+ code: v.union(v.literal("balance_insufficient"), v.literal("amount_too_small")),
221
+ },
222
+ returns: claimDoc,
223
+ handler: async (ctx, args) => {
224
+ const claim = await claimByKey(ctx, args);
225
+ if (!claim ||
226
+ !/^req_\w+$/.test(args.requestId) ||
227
+ args.requestId.trim() !== args.requestId)
228
+ throw new Error("Invalid payout rejection receipt.");
229
+ if (claim.status === "rejected") {
230
+ if (claim.rejection?.requestId !== args.requestId ||
231
+ claim.rejection.code !== args.code)
232
+ throw new Error("Payout rejection receipt identity changed.");
233
+ return claim;
234
+ }
235
+ if (claim.status !== "reserved" ||
236
+ claim.stripePayoutId ||
237
+ claim.attemptedAt === undefined ||
238
+ Date.now() - claim.attemptedAt >= 23 * 60 * 60 * 1000)
239
+ throw new Error("An accepted or uncertain expired payout attempt cannot be released as a rejection.");
240
+ const adoptedRejection = await ctx.db
241
+ .query("payoutReleaseClaims")
242
+ .withIndex("by_rejection_request", (q) => q.eq("rejection.requestId", args.requestId))
243
+ .unique();
244
+ if (adoptedRejection && adoptedRejection._id !== claim._id)
245
+ throw new Error("Payout rejection receipt is already allocated.");
246
+ await moveAllocations(ctx, claim, "release");
247
+ await ctx.db.patch("payoutReleaseClaims", claim._id, {
248
+ status: "rejected",
249
+ rejection: { requestId: args.requestId, code: args.code },
250
+ });
251
+ return (await ctx.db.get("payoutReleaseClaims", claim._id));
252
+ },
253
+ });
254
+ //# sourceMappingURL=mutations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mutations.js","sourceRoot":"","sources":["../../../src/component/payoutRelease/mutations.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,84 @@
1
+ export declare const get: import("convex/server").RegisteredQuery<"public", {
2
+ accountId: string;
3
+ operationKey: string;
4
+ ownerKey: string;
5
+ }, Promise<{
6
+ _creationTime: number;
7
+ _id: import("convex/values").GenericId<"payoutReleaseClaims">;
8
+ accountId: string;
9
+ allocations: {
10
+ amount: number;
11
+ role?: "affiliate" | "other" | "store" | undefined;
12
+ stripeTransferId: string;
13
+ }[];
14
+ amount: number;
15
+ attemptedAt?: number | undefined;
16
+ currency: string;
17
+ expectedRevision: number;
18
+ observations: {
19
+ currency: string;
20
+ ledgerFingerprint: string;
21
+ matureNet: number;
22
+ observedAt: number;
23
+ pendingCredits: number;
24
+ stripeTransferId: string;
25
+ transactionIds: string[];
26
+ }[];
27
+ operationKey: string;
28
+ ownerKey: string;
29
+ rejection?: {
30
+ code: "amount_too_small" | "balance_insufficient";
31
+ requestId: string;
32
+ } | undefined;
33
+ returnTransactionId?: string | undefined;
34
+ status: "canceled" | "paid" | "rejected" | "reserved" | "returned" | "submitted";
35
+ stripePayoutId?: string | undefined;
36
+ } | null>>;
37
+ export declare const pending: import("convex/server").RegisteredQuery<"public", {
38
+ accountId: string;
39
+ ownerKey: string;
40
+ paginationOpts: {
41
+ id?: number;
42
+ endCursor?: string | null;
43
+ maximumRowsRead?: number;
44
+ maximumBytesRead?: number;
45
+ numItems: number;
46
+ cursor: string | null;
47
+ };
48
+ }, Promise<{
49
+ page: {
50
+ _creationTime: number;
51
+ _id: import("convex/values").GenericId<"payoutReleaseClaims">;
52
+ accountId: string;
53
+ allocations: {
54
+ amount: number;
55
+ role?: "affiliate" | "other" | "store" | undefined;
56
+ stripeTransferId: string;
57
+ }[];
58
+ amount: number;
59
+ attemptedAt?: number | undefined;
60
+ currency: string;
61
+ expectedRevision: number;
62
+ observations: {
63
+ currency: string;
64
+ ledgerFingerprint: string;
65
+ matureNet: number;
66
+ observedAt: number;
67
+ pendingCredits: number;
68
+ stripeTransferId: string;
69
+ transactionIds: string[];
70
+ }[];
71
+ operationKey: string;
72
+ ownerKey: string;
73
+ rejection?: {
74
+ code: "amount_too_small" | "balance_insufficient";
75
+ requestId: string;
76
+ } | undefined;
77
+ returnTransactionId?: string | undefined;
78
+ status: "canceled" | "paid" | "rejected" | "reserved" | "returned" | "submitted";
79
+ stripePayoutId?: string | undefined;
80
+ }[];
81
+ continueCursor: string;
82
+ isDone: boolean;
83
+ }>>;
84
+ //# sourceMappingURL=queries.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queries.d.ts","sourceRoot":"","sources":["../../../src/component/payoutRelease/queries.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UAiBd,CAAC;AACH,eAAO,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BlB,CAAC"}
@@ -0,0 +1,51 @@
1
+ import { paginationOptsValidator } from "convex/server";
2
+ import { v } from "convex/values";
3
+ import { query } from "../_generated/server.js";
4
+ import { identity, claimDoc } from "./schema.js";
5
+ import { validateIdentity } from "./helpers.js";
6
+ import { readPolicy } from "../payoutPolicy/helpers.js";
7
+ export const get = query({
8
+ args: identity,
9
+ returns: v.union(claimDoc, v.null()),
10
+ handler: async (ctx, args) => {
11
+ validateIdentity(args);
12
+ await readPolicy(ctx, args);
13
+ const claim = await ctx.db
14
+ .query("payoutReleaseClaims")
15
+ .withIndex("by_operation", (q) => q.eq("operationKey", args.operationKey))
16
+ .unique();
17
+ if (claim &&
18
+ (claim.accountId !== args.accountId || claim.ownerKey !== args.ownerKey))
19
+ throw new Error("Payout claim identity does not match.");
20
+ return claim;
21
+ },
22
+ });
23
+ export const pending = query({
24
+ args: {
25
+ accountId: v.string(),
26
+ ownerKey: v.string(),
27
+ paginationOpts: paginationOptsValidator,
28
+ },
29
+ returns: v.object({
30
+ page: v.array(claimDoc),
31
+ continueCursor: v.string(),
32
+ isDone: v.boolean(),
33
+ }),
34
+ handler: async (ctx, args) => {
35
+ await readPolicy(ctx, args);
36
+ if (!Number.isInteger(args.paginationOpts.numItems) ||
37
+ args.paginationOpts.numItems < 1 ||
38
+ args.paginationOpts.numItems > 100)
39
+ throw new Error("Invalid payout claim page.");
40
+ const result = await ctx.db
41
+ .query("payoutReleaseClaims")
42
+ .withIndex("by_account_status", (q) => q.eq("accountId", args.accountId).eq("status", "reserved"))
43
+ .paginate(args.paginationOpts);
44
+ return {
45
+ page: result.page,
46
+ continueCursor: result.continueCursor,
47
+ isDone: result.isDone,
48
+ };
49
+ },
50
+ });
51
+ //# sourceMappingURL=queries.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queries.js","sourceRoot":"","sources":["../../../src/component/payoutRelease/queries.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AACxD,OAAO,EAAE,CAAC,EAAE,MAAM,eAAe,CAAC;AAClC,OAAO,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AACxD,MAAM,CAAC,MAAM,GAAG,GAAG,KAAK,CAAC;IACvB,IAAI,EAAE,QAAQ;IACd,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IACpC,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;QAC3B,gBAAgB,CAAC,IAAI,CAAC,CAAC;QACvB,MAAM,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAC5B,MAAM,KAAK,GAAG,MAAM,GAAG,CAAC,EAAE;aACvB,KAAK,CAAC,qBAAqB,CAAC;aAC5B,SAAS,CAAC,cAAc,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,cAAc,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;aACzE,MAAM,EAAE,CAAC;QACZ,IACE,KAAK;YACL,CAAC,KAAK,CAAC,SAAS,KAAK,IAAI,CAAC,SAAS,IAAI,KAAK,CAAC,QAAQ,KAAK,IAAI,CAAC,QAAQ,CAAC;YAExE,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;QAC3D,OAAO,KAAK,CAAC;IACf,CAAC;CACF,CAAC,CAAC;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,KAAK,CAAC;IAC3B,IAAI,EAAE;QACJ,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;QACrB,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE;QACpB,cAAc,EAAE,uBAAuB;KACxC;IACD,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC;QAChB,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC;QACvB,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE;QAC1B,MAAM,EAAE,CAAC,CAAC,OAAO,EAAE;KACpB,CAAC;IACF,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;QAC3B,MAAM,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAC5B,IACE,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC;YAC/C,IAAI,CAAC,cAAc,CAAC,QAAQ,GAAG,CAAC;YAChC,IAAI,CAAC,cAAc,CAAC,QAAQ,GAAG,GAAG;YAElC,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;QAChD,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,EAAE;aACxB,KAAK,CAAC,qBAAqB,CAAC;aAC5B,SAAS,CAAC,mBAAmB,EAAE,CAAC,CAAC,EAAE,EAAE,CACpC,CAAC,CAAC,EAAE,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,QAAQ,EAAE,UAAU,CAAC,CAC3D;aACA,QAAQ,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QACjC,OAAO;YACL,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,cAAc,EAAE,MAAM,CAAC,cAAc;YACrC,MAAM,EAAE,MAAM,CAAC,MAAM;SACtB,CAAC;IACJ,CAAC;CACF,CAAC,CAAC"}