@openora/core 0.4.1-canary.93 → 0.4.1-canary.95
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/.tsbuildinfo +1 -1
- package/dist/audit/plugin.d.ts.map +1 -1
- package/dist/audit/plugin.js +13 -0
- package/dist/audit/plugin.js.map +1 -1
- package/dist/contracts/adapters/audit.d.ts +1 -1
- package/dist/contracts/adapters/audit.d.ts.map +1 -1
- package/dist/contracts/adapters/audit.js.map +1 -1
- package/dist/contracts/schemas/events.d.ts +5 -0
- package/dist/contracts/schemas/events.d.ts.map +1 -1
- package/dist/contracts/schemas/events.js +9 -0
- package/dist/contracts/schemas/events.js.map +1 -1
- package/dist/testing/mock.d.ts +6 -1
- package/dist/testing/mock.d.ts.map +1 -1
- package/dist/testing/mock.js +9 -0
- package/dist/testing/mock.js.map +1 -1
- package/dist/wallet/__tests__/custody-sweep-gate.test.d.ts +2 -0
- package/dist/wallet/__tests__/custody-sweep-gate.test.d.ts.map +1 -0
- package/dist/wallet/__tests__/custody-sweep-gate.test.js +70 -0
- package/dist/wallet/__tests__/custody-sweep-gate.test.js.map +1 -0
- package/dist/wallet/__tests__/custody-sweep.service.int.test.d.ts +2 -0
- package/dist/wallet/__tests__/custody-sweep.service.int.test.d.ts.map +1 -0
- package/dist/wallet/__tests__/custody-sweep.service.int.test.js +246 -0
- package/dist/wallet/__tests__/custody-sweep.service.int.test.js.map +1 -0
- package/dist/wallet/__tests__/reconciliation-diff.test.d.ts +2 -0
- package/dist/wallet/__tests__/reconciliation-diff.test.d.ts.map +1 -0
- package/dist/wallet/__tests__/reconciliation-diff.test.js +49 -0
- package/dist/wallet/__tests__/reconciliation-diff.test.js.map +1 -0
- package/dist/wallet/__tests__/reconciliation.service.int.test.d.ts +2 -0
- package/dist/wallet/__tests__/reconciliation.service.int.test.d.ts.map +1 -0
- package/dist/wallet/__tests__/reconciliation.service.int.test.js +395 -0
- package/dist/wallet/__tests__/reconciliation.service.int.test.js.map +1 -0
- package/dist/wallet/__tests__/wallet-asset.router.int.test.js +12 -2
- package/dist/wallet/__tests__/wallet-asset.router.int.test.js.map +1 -1
- package/dist/wallet/__tests__/wallet-auto-rule.router.int.test.js +12 -2
- package/dist/wallet/__tests__/wallet-auto-rule.router.int.test.js.map +1 -1
- package/dist/wallet/__tests__/wallet-auto-withdrawal-config.router.int.test.js +12 -2
- package/dist/wallet/__tests__/wallet-auto-withdrawal-config.router.int.test.js.map +1 -1
- package/dist/wallet/__tests__/wallet-custody-routes.router.test.d.ts +2 -0
- package/dist/wallet/__tests__/wallet-custody-routes.router.test.d.ts.map +1 -0
- package/dist/wallet/__tests__/wallet-custody-routes.router.test.js +128 -0
- package/dist/wallet/__tests__/wallet-custody-routes.router.test.js.map +1 -0
- package/dist/wallet/__tests__/wallet-webhook.router.int.test.js +32 -4
- package/dist/wallet/__tests__/wallet-webhook.router.int.test.js.map +1 -1
- package/dist/wallet/__tests__/wallet.router.int.test.js +12 -2
- package/dist/wallet/__tests__/wallet.router.int.test.js.map +1 -1
- package/dist/wallet/__tests__/wallet.service.int.test.js +34 -11
- package/dist/wallet/__tests__/wallet.service.int.test.js.map +1 -1
- package/dist/wallet/contract/index.d.ts.map +1 -1
- package/dist/wallet/contract/index.js +8 -8
- package/dist/wallet/contract/index.js.map +1 -1
- package/dist/wallet/plugin.d.ts.map +1 -1
- package/dist/wallet/plugin.js +91 -17
- package/dist/wallet/plugin.js.map +1 -1
- package/dist/wallet/router/index.d.ts +19 -2
- package/dist/wallet/router/index.d.ts.map +1 -1
- package/dist/wallet/router/index.js +32 -17
- package/dist/wallet/router/index.js.map +1 -1
- package/dist/wallet/service/custody-sweep.service.d.ts +77 -0
- package/dist/wallet/service/custody-sweep.service.d.ts.map +1 -0
- package/dist/wallet/service/custody-sweep.service.js +354 -0
- package/dist/wallet/service/custody-sweep.service.js.map +1 -0
- package/dist/wallet/service/reconciliation-finding.service.d.ts +39 -0
- package/dist/wallet/service/reconciliation-finding.service.d.ts.map +1 -0
- package/dist/wallet/service/reconciliation-finding.service.js +36 -0
- package/dist/wallet/service/reconciliation-finding.service.js.map +1 -0
- package/dist/wallet/service/reconciliation.service.d.ts +112 -0
- package/dist/wallet/service/reconciliation.service.d.ts.map +1 -0
- package/dist/wallet/service/reconciliation.service.js +509 -0
- package/dist/wallet/service/reconciliation.service.js.map +1 -0
- package/dist/wallet/service/wallet.service.d.ts +7 -2
- package/dist/wallet/service/wallet.service.d.ts.map +1 -1
- package/dist/wallet/service/wallet.service.js +45 -3
- package/dist/wallet/service/wallet.service.js.map +1 -1
- package/package.json +1 -1
- package/dist/wallet/__tests__/wallet-custody-stubs.router.test.d.ts +0 -2
- package/dist/wallet/__tests__/wallet-custody-stubs.router.test.d.ts.map +0 -1
- package/dist/wallet/__tests__/wallet-custody-stubs.router.test.js +0 -80
- package/dist/wallet/__tests__/wallet-custody-stubs.router.test.js.map +0 -1
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { DrizzleDb, DrizzleTx } from '@openora/core/server';
|
|
2
|
+
import type { WalletReconciliationFindingKind } from '@openora/core/contracts';
|
|
3
|
+
/**
|
|
4
|
+
* Sentinel `runId` for a finding produced OUTSIDE any reconciliation job cycle - the
|
|
5
|
+
* live webhook path (`WalletService.creditDepositByAddress`) hits an unattributable
|
|
6
|
+
* deposit in real time, not on a poll. `runId` is NOT NULL on the table, so this fixed
|
|
7
|
+
* zero-uuid documents "no job run owns this row", mirroring the audit plugin's
|
|
8
|
+
* SYSTEM_ACTOR sentinel for "no admin acted here".
|
|
9
|
+
*/
|
|
10
|
+
export declare const LIVE_WEBHOOK_RUN_ID = "00000000-0000-0000-0000-000000000000";
|
|
11
|
+
export type ReconciliationFindingInput = {
|
|
12
|
+
runId: string;
|
|
13
|
+
providerName: string;
|
|
14
|
+
kind: WalletReconciliationFindingKind;
|
|
15
|
+
currency?: string | null;
|
|
16
|
+
network?: string | null;
|
|
17
|
+
amount?: string | null;
|
|
18
|
+
address?: string | null;
|
|
19
|
+
tag?: string | null;
|
|
20
|
+
txHash?: string | null;
|
|
21
|
+
/**
|
|
22
|
+
* The dedup key: a partial unique index on (kind, externalId) makes a duplicate
|
|
23
|
+
* insert for the same underlying vendor event or job re-run a silent no-op. Pass a
|
|
24
|
+
* stable stand-in (eg the source row's own id) when no vendor externalId exists, so
|
|
25
|
+
* a finding with no natural external reference still dedupes across re-runs.
|
|
26
|
+
*/
|
|
27
|
+
externalId?: string | null;
|
|
28
|
+
transactionId?: string | null;
|
|
29
|
+
detail?: string | null;
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* The single write path for a reconciliation finding - never a raw `insert` scattered
|
|
33
|
+
* across WalletService and ReconciliationService (both import this, neither imports the
|
|
34
|
+
* other, so there is no cycle). A finding is a report, never a credit instruction (see
|
|
35
|
+
* the schema's own comment): this never touches a balance or a transaction row, only
|
|
36
|
+
* records that something needs a human look.
|
|
37
|
+
*/
|
|
38
|
+
export declare function recordReconciliationFinding(db: DrizzleDb | DrizzleTx, input: ReconciliationFindingInput): Promise<void>;
|
|
39
|
+
//# sourceMappingURL=reconciliation-finding.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reconciliation-finding.service.d.ts","sourceRoot":"","sources":["../../../src/wallet/service/reconciliation-finding.service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjE,OAAO,KAAK,EAAE,+BAA+B,EAAE,MAAM,yBAAyB,CAAC;AAG/E;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,yCAAyC,CAAC;AAE1E,MAAM,MAAM,0BAA0B,GAAG;IACvC,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,+BAA+B,CAAC;IACtC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB;;;;;OAKG;IACH,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB,CAAC;AAEF;;;;;;GAMG;AACH,wBAAsB,2BAA2B,CAC/C,EAAE,EAAE,SAAS,GAAG,SAAS,EACzB,KAAK,EAAE,0BAA0B,GAChC,OAAO,CAAC,IAAI,CAAC,CAkBf"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { walletReconciliationFinding } from '../schema/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Sentinel `runId` for a finding produced OUTSIDE any reconciliation job cycle - the
|
|
4
|
+
* live webhook path (`WalletService.creditDepositByAddress`) hits an unattributable
|
|
5
|
+
* deposit in real time, not on a poll. `runId` is NOT NULL on the table, so this fixed
|
|
6
|
+
* zero-uuid documents "no job run owns this row", mirroring the audit plugin's
|
|
7
|
+
* SYSTEM_ACTOR sentinel for "no admin acted here".
|
|
8
|
+
*/
|
|
9
|
+
export const LIVE_WEBHOOK_RUN_ID = '00000000-0000-0000-0000-000000000000';
|
|
10
|
+
/**
|
|
11
|
+
* The single write path for a reconciliation finding - never a raw `insert` scattered
|
|
12
|
+
* across WalletService and ReconciliationService (both import this, neither imports the
|
|
13
|
+
* other, so there is no cycle). A finding is a report, never a credit instruction (see
|
|
14
|
+
* the schema's own comment): this never touches a balance or a transaction row, only
|
|
15
|
+
* records that something needs a human look.
|
|
16
|
+
*/
|
|
17
|
+
export async function recordReconciliationFinding(db, input) {
|
|
18
|
+
await db
|
|
19
|
+
.insert(walletReconciliationFinding)
|
|
20
|
+
.values({
|
|
21
|
+
runId: input.runId,
|
|
22
|
+
providerName: input.providerName,
|
|
23
|
+
kind: input.kind,
|
|
24
|
+
currency: input.currency ?? null,
|
|
25
|
+
network: input.network ?? null,
|
|
26
|
+
amount: input.amount ?? null,
|
|
27
|
+
address: input.address ?? null,
|
|
28
|
+
tag: input.tag ?? null,
|
|
29
|
+
txHash: input.txHash ?? null,
|
|
30
|
+
externalId: input.externalId ?? null,
|
|
31
|
+
transactionId: input.transactionId ?? null,
|
|
32
|
+
detail: input.detail ?? null,
|
|
33
|
+
})
|
|
34
|
+
.onConflictDoNothing();
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=reconciliation-finding.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reconciliation-finding.service.js","sourceRoot":"","sources":["../../../src/wallet/service/reconciliation-finding.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,2BAA2B,EAAE,MAAM,oBAAoB,CAAC;AAEjE;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,sCAAsC,CAAC;AAuB1E;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,2BAA2B,CAC/C,EAAyB,EACzB,KAAiC;IAEjC,MAAM,EAAE;SACL,MAAM,CAAC,2BAA2B,CAAC;SACnC,MAAM,CAAC;QACN,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,YAAY,EAAE,KAAK,CAAC,YAAY;QAChC,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,QAAQ,EAAE,KAAK,CAAC,QAAQ,IAAI,IAAI;QAChC,OAAO,EAAE,KAAK,CAAC,OAAO,IAAI,IAAI;QAC9B,MAAM,EAAE,KAAK,CAAC,MAAM,IAAI,IAAI;QAC5B,OAAO,EAAE,KAAK,CAAC,OAAO,IAAI,IAAI;QAC9B,GAAG,EAAE,KAAK,CAAC,GAAG,IAAI,IAAI;QACtB,MAAM,EAAE,KAAK,CAAC,MAAM,IAAI,IAAI;QAC5B,UAAU,EAAE,KAAK,CAAC,UAAU,IAAI,IAAI;QACpC,aAAa,EAAE,KAAK,CAAC,aAAa,IAAI,IAAI;QAC1C,MAAM,EAAE,KAAK,CAAC,MAAM,IAAI,IAAI;KAC7B,CAAC;SACD,mBAAmB,EAAE,CAAC;AAC3B,CAAC"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { type DrizzleService, type EventBus } from '@openora/core/server';
|
|
2
|
+
import { type AuditWritePort, type ClientMeta, type PaymentProviderRegistry, type PaymentWebhookEvent, type PlatformConfig, type User } from '@openora/core/contracts';
|
|
3
|
+
import { type WalletJobRun, type WalletReconciliationFinding as WalletReconciliationFindingRow, type WalletTransaction } from '../schema/index.js';
|
|
4
|
+
import type { ListReconciliationFindingsInput, ReconciliationResolution, WalletReconciliationFinding as WalletReconciliationFindingDto } from '../contract/index.js';
|
|
5
|
+
import type { WalletService } from './wallet.service.js';
|
|
6
|
+
export declare const ReconciliationFindingNotFoundError: new (id: string) => Error;
|
|
7
|
+
export declare const ReconciliationCreditTransactionNotFoundError: new (id: string) => Error;
|
|
8
|
+
export declare const ReconciliationCreditMismatchError: new () => Error;
|
|
9
|
+
type LedgerMatch = Pick<WalletTransaction, 'id' | 'currency' | 'amount' | 'network'>;
|
|
10
|
+
/**
|
|
11
|
+
* Pure diff of one vendor deposit event against its (maybe absent) ledger row - the
|
|
12
|
+
* whole decision reconciliation makes for a deposit, extracted so it is unit-testable
|
|
13
|
+
* without a database. Never routes through moneyToNumber (see money.md): an exact
|
|
14
|
+
* decimal compare, not a float one.
|
|
15
|
+
*/
|
|
16
|
+
export declare function diffDeposit(event: Extract<PaymentWebhookEvent, {
|
|
17
|
+
kind: 'deposit';
|
|
18
|
+
}>, tx: LedgerMatch | undefined): 'missing_deposit' | 'currency_mismatch' | 'amount_mismatch' | null;
|
|
19
|
+
export type ReconciliationServiceDeps = {
|
|
20
|
+
drizzle: DrizzleService;
|
|
21
|
+
events: EventBus;
|
|
22
|
+
wallet: WalletService;
|
|
23
|
+
paymentProviders: PaymentProviderRegistry;
|
|
24
|
+
audit: AuditWritePort;
|
|
25
|
+
platformConfig?: PlatformConfig;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Owns the reconciliation job cycle (claim -> per-provider diff -> stuck-withdrawal /
|
|
29
|
+
* stuck-sweep sweep -> finish + audit + alert) and the admin surface over its findings
|
|
30
|
+
* (list/resolve). Never credits or moves money itself - every finding is a report; the
|
|
31
|
+
* only paths that touch a balance are `WalletService.reconcileWithdrawalStatus` (already
|
|
32
|
+
* idempotent) and the pre-existing manual-adjustment path a `credited` resolution merely
|
|
33
|
+
* references.
|
|
34
|
+
*/
|
|
35
|
+
export declare class ReconciliationService {
|
|
36
|
+
private readonly drizzle;
|
|
37
|
+
private readonly events;
|
|
38
|
+
private readonly wallet;
|
|
39
|
+
private readonly paymentProviders;
|
|
40
|
+
private readonly audit;
|
|
41
|
+
private readonly platformConfig?;
|
|
42
|
+
constructor({ drizzle, events, wallet, paymentProviders, audit, platformConfig, }: ReconciliationServiceDeps);
|
|
43
|
+
listFindings(filter: ListReconciliationFindingsInput): Promise<{
|
|
44
|
+
items: {
|
|
45
|
+
id: string;
|
|
46
|
+
runId: string;
|
|
47
|
+
providerName: string;
|
|
48
|
+
kind: "missing_deposit" | "unattributed_deposit" | "amount_mismatch" | "currency_mismatch" | "status_mismatch" | "unknown_at_provider" | "unconfigured_asset" | "stuck_sweep";
|
|
49
|
+
currency: string | null;
|
|
50
|
+
network: string | null;
|
|
51
|
+
amount: string | null;
|
|
52
|
+
address: string | null;
|
|
53
|
+
tag: string | null;
|
|
54
|
+
txHash: string | null;
|
|
55
|
+
externalId: string | null;
|
|
56
|
+
transactionId: string | null;
|
|
57
|
+
detail: string | null;
|
|
58
|
+
status: "open" | "resolved";
|
|
59
|
+
resolvedBy: string | null;
|
|
60
|
+
resolvedAt: string | null;
|
|
61
|
+
resolutionNote: string | null;
|
|
62
|
+
createdAt: string;
|
|
63
|
+
}[];
|
|
64
|
+
total: number;
|
|
65
|
+
page: number;
|
|
66
|
+
limit: number;
|
|
67
|
+
}>;
|
|
68
|
+
/**
|
|
69
|
+
* Conditional `UPDATE ... WHERE status = 'open'` is the whole double-resolve guard -
|
|
70
|
+
* a second resolve of an already-resolved finding matches zero rows and returns the
|
|
71
|
+
* row unchanged, with no second audit entry. `credited` requires the referenced
|
|
72
|
+
* transaction to already exist (the manual-adjustment path creates it - this never
|
|
73
|
+
* credits anything itself) and match the finding's currency/amount exactly.
|
|
74
|
+
*/
|
|
75
|
+
resolveFinding(adminId: User['id'], id: WalletReconciliationFindingRow['id'], resolution: ReconciliationResolution, meta?: ClientMeta): Promise<WalletReconciliationFindingDto>;
|
|
76
|
+
/**
|
|
77
|
+
* The window is anchored to the last completed run, not to the wall clock. BullMQ
|
|
78
|
+
* repeatable jobs are delayed jobs: a tick missed while no worker was running is
|
|
79
|
+
* skipped, never backfilled. Against a fixed `now - lookbackHours` window that means
|
|
80
|
+
* any outage longer than `lookbackHours` leaves a span nothing ever reconciles and
|
|
81
|
+
* nothing ever reports - the worst possible failure mode for a compensating control.
|
|
82
|
+
* Catching up is capped, and a capped window is reported rather than passed over.
|
|
83
|
+
*/
|
|
84
|
+
private resolveWindow;
|
|
85
|
+
/**
|
|
86
|
+
* Claim -> per-provider deposit/withdrawal diff -> stuck-withdrawal / stuck-sweep
|
|
87
|
+
* sweep -> finish + one audit entry + an alert past threshold. Returns null without
|
|
88
|
+
* doing any work when another cycle already owns the claim - the caller (cron tick or
|
|
89
|
+
* the on-demand route's worker) treats that as a normal, expected outcome.
|
|
90
|
+
*/
|
|
91
|
+
runCycle(runId?: WalletJobRun['runId']): Promise<{
|
|
92
|
+
runId: WalletJobRun['runId'];
|
|
93
|
+
} | null>;
|
|
94
|
+
private reconcileProvider;
|
|
95
|
+
private sweptExternalIds;
|
|
96
|
+
private reconcileDeposits;
|
|
97
|
+
private batchLookupByProviderRefId;
|
|
98
|
+
private reconcileStuckWithdrawals;
|
|
99
|
+
private reconcileStuckSweeps;
|
|
100
|
+
private countOpenFindings;
|
|
101
|
+
/**
|
|
102
|
+
* The claim IS the insert - a partial unique index on (jobName) WHERE finishedAt IS
|
|
103
|
+
* NULL makes a conflicting insert the concurrency guard. A stale in-flight run (older
|
|
104
|
+
* than the configured staleness window - presumed crashed) is marked `abandoned` and its slot freed
|
|
105
|
+
* for this call to retry the claim once.
|
|
106
|
+
*/
|
|
107
|
+
private claimRun;
|
|
108
|
+
private retryClaim;
|
|
109
|
+
private finishRun;
|
|
110
|
+
}
|
|
111
|
+
export {};
|
|
112
|
+
//# sourceMappingURL=reconciliation.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reconciliation.service.d.ts","sourceRoot":"","sources":["../../../src/wallet/service/reconciliation.service.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,QAAQ,EAQd,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,UAAU,EACf,KAAK,uBAAuB,EAC5B,KAAK,mBAAmB,EACxB,KAAK,cAAc,EACnB,KAAK,IAAI,EAEV,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAKL,KAAK,YAAY,EACjB,KAAK,2BAA2B,IAAI,8BAA8B,EAClE,KAAK,iBAAiB,EACvB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EACV,+BAA+B,EAC/B,wBAAwB,EACxB,2BAA2B,IAAI,8BAA8B,EAC9D,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAKzD,eAAO,MAAM,kCAAkC,2BAA6C,CAAC;AAE7F,eAAO,MAAM,4CAA4C,2BAExD,CAAC;AAEF,eAAO,MAAM,iCAAiC,iBAG7C,CAAC;AAEF,KAAK,WAAW,GAAG,IAAI,CAAC,iBAAiB,EAAE,IAAI,GAAG,UAAU,GAAG,QAAQ,GAAG,SAAS,CAAC,CAAC;AAErF;;;;;GAKG;AACH,wBAAgB,WAAW,CACzB,KAAK,EAAE,OAAO,CAAC,mBAAmB,EAAE;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,CAAC,EACxD,EAAE,EAAE,WAAW,GAAG,SAAS,GAC1B,iBAAiB,GAAG,mBAAmB,GAAG,iBAAiB,GAAG,IAAI,CAWpE;AAmCD,MAAM,MAAM,yBAAyB,GAAG;IACtC,OAAO,EAAE,cAAc,CAAC;IACxB,MAAM,EAAE,QAAQ,CAAC;IACjB,MAAM,EAAE,aAAa,CAAC;IACtB,gBAAgB,EAAE,uBAAuB,CAAC;IAC1C,KAAK,EAAE,cAAc,CAAC;IACtB,cAAc,CAAC,EAAE,cAAc,CAAC;CACjC,CAAC;AAEF;;;;;;;GAOG;AACH,qBAAa,qBAAqB;IAChC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAiB;IACzC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAW;IAClC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;IACvC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAA0B;IAC3D,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAiB;IACvC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAiB;gBAErC,EACV,OAAO,EACP,MAAM,EACN,MAAM,EACN,gBAAgB,EAChB,KAAK,EACL,cAAc,GACf,EAAE,yBAAyB;IAStB,YAAY,CAAC,MAAM,EAAE,+BAA+B;;;;;;;;;;;;;;;;;;;;;;;;;IAiC1D;;;;;;OAMG;IACG,cAAc,CAClB,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,EACnB,EAAE,EAAE,8BAA8B,CAAC,IAAI,CAAC,EACxC,UAAU,EAAE,wBAAwB,EACpC,IAAI,CAAC,EAAE,UAAU,GAChB,OAAO,CAAC,8BAA8B,CAAC;IAkF1C;;;;;;;OAOG;YACW,aAAa;IAyB3B;;;;;OAKG;IACG,QAAQ,CACZ,KAAK,GAAE,YAAY,CAAC,OAAO,CAAgB,GAC1C,OAAO,CAAC;QAAE,KAAK,EAAE,YAAY,CAAC,OAAO,CAAC,CAAA;KAAE,GAAG,IAAI,CAAC;YAqFrC,iBAAiB;YA2CjB,gBAAgB;YAahB,iBAAiB;YAgDjB,0BAA0B;YAoB1B,yBAAyB;YAmEzB,oBAAoB;YAsCpB,iBAAiB;IAQ/B;;;;;OAKG;YACW,QAAQ;YAkCR,UAAU;YAaV,SAAS;CAUxB"}
|