@truststate/sdk 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +230 -0
- package/dist/client.d.ts +96 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +346 -0
- package/dist/client.js.map +1 -0
- package/dist/errors.d.ts +9 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +17 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +22 -0
- package/dist/index.js.map +1 -0
- package/dist/middleware.d.ts +93 -0
- package/dist/middleware.d.ts.map +1 -0
- package/dist/middleware.js +129 -0
- package/dist/middleware.js.map +1 -0
- package/dist/types.d.ts +121 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -0
- package/package.json +45 -0
- package/src/client.ts +448 -0
- package/src/errors.ts +15 -0
- package/src/index.ts +23 -0
- package/src/middleware.ts +224 -0
- package/src/types.ts +122 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 MyreneBot
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
# TrustState Node.js / TypeScript SDK
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@truststate/sdk)
|
|
4
|
+
[](https://www.typescriptlang.org/)
|
|
5
|
+
[](LICENSE)
|
|
6
|
+
|
|
7
|
+
TypeScript/JavaScript SDK for the [TrustState](https://truststate.apps.trustchainlabs.com) compliance API — validate, audit, and enforce compliance rules on any entity or data record. Built for financial services, AI governance, and regulated industries.
|
|
8
|
+
|
|
9
|
+
## Install
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install @truststate/sdk
|
|
13
|
+
# or
|
|
14
|
+
yarn add @truststate/sdk
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Requires Node.js 18+ (uses native `fetch` and `crypto.randomUUID()`).
|
|
18
|
+
|
|
19
|
+
## Quickstart
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
import { TrustStateClient } from "@truststate/sdk";
|
|
23
|
+
|
|
24
|
+
const client = new TrustStateClient({ apiKey: "ts_your_api_key" });
|
|
25
|
+
|
|
26
|
+
const result = await client.check("SukukBond", {
|
|
27
|
+
id: "BOND-001",
|
|
28
|
+
issuerId: "ISS-001",
|
|
29
|
+
currency: "MYR",
|
|
30
|
+
faceValue: 5_000_000,
|
|
31
|
+
maturityDate: "2030-06-01",
|
|
32
|
+
status: "DRAFT",
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
if (result.passed) {
|
|
36
|
+
console.log("✅ Passed — record ID:", result.recordId);
|
|
37
|
+
} else {
|
|
38
|
+
console.log("❌ Failed —", result.failReason, `(step ${result.failedStep})`);
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Batch Writes
|
|
43
|
+
|
|
44
|
+
Submit multiple records in a single API call. Useful for feed-based pipelines.
|
|
45
|
+
|
|
46
|
+
```typescript
|
|
47
|
+
const result = await client.checkBatch(
|
|
48
|
+
[
|
|
49
|
+
{ entityType: "SukukBond", data: { id: "BOND-001", ... } },
|
|
50
|
+
{ entityType: "SukukBond", data: { id: "BOND-002", ... } },
|
|
51
|
+
{ entityType: "SukukBond", data: { id: "BOND-003", ... } },
|
|
52
|
+
],
|
|
53
|
+
{
|
|
54
|
+
feedLabel: "core-banking-feed", // echoed on every item result
|
|
55
|
+
}
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
console.log(`Accepted: ${result.accepted}/${result.total}`);
|
|
59
|
+
result.results.forEach((item) => {
|
|
60
|
+
console.log(` ${item.entityId}: ${item.passed ? "✅" : "❌"} ${item.feedLabel}`);
|
|
61
|
+
});
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## BYOP Evidence (Oracle Data)
|
|
65
|
+
|
|
66
|
+
Attach oracle evidence to compliance checks — FX rates, KYC status, credit scores, sanctions screening.
|
|
67
|
+
|
|
68
|
+
```typescript
|
|
69
|
+
// Fetch evidence from registered oracle providers
|
|
70
|
+
const fx = await client.fetchFxRate("MYR", "USD");
|
|
71
|
+
const kyc = await client.fetchKycStatus("actor-jasim");
|
|
72
|
+
const score = await client.fetchCreditScore("actor-jasim");
|
|
73
|
+
|
|
74
|
+
// Submit with evidence attached
|
|
75
|
+
const result = await client.checkWithEvidence(
|
|
76
|
+
"SukukBond",
|
|
77
|
+
{ id: "BOND-001", issuerId: "ISS-001", currency: "MYR", faceValue: 5_000_000 },
|
|
78
|
+
[fx, kyc, score],
|
|
79
|
+
);
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Mock Mode
|
|
83
|
+
|
|
84
|
+
Test without making any API calls. Useful for unit tests and local development.
|
|
85
|
+
|
|
86
|
+
```typescript
|
|
87
|
+
const client = new TrustStateClient({
|
|
88
|
+
apiKey: "any",
|
|
89
|
+
mock: true,
|
|
90
|
+
mockPassRate: 0.8, // 80% of checks will pass
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
const result = await client.check("SukukBond", { id: "TEST-001", ... });
|
|
94
|
+
console.log(result.mock); // true
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## Express Middleware
|
|
98
|
+
|
|
99
|
+
Automatically validate incoming request bodies against TrustState policies.
|
|
100
|
+
|
|
101
|
+
```typescript
|
|
102
|
+
import express from "express";
|
|
103
|
+
import { TrustStateMiddleware } from "@truststate/sdk";
|
|
104
|
+
|
|
105
|
+
const app = express();
|
|
106
|
+
|
|
107
|
+
app.use(
|
|
108
|
+
TrustStateMiddleware({
|
|
109
|
+
apiKey: "ts_your_api_key",
|
|
110
|
+
entityType: "AgentResponse",
|
|
111
|
+
extractData: (req) => req.body,
|
|
112
|
+
})
|
|
113
|
+
);
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## Configuration
|
|
117
|
+
|
|
118
|
+
| Option | Type | Default | Description |
|
|
119
|
+
|---|---|---|---|
|
|
120
|
+
| `apiKey` | `string` | required | Your TrustState API key |
|
|
121
|
+
| `baseUrl` | `string` | production URL | Override the API base URL |
|
|
122
|
+
| `defaultSchemaVersion` | `string` | auto-resolved | Schema version (auto-resolved by server if omitted) |
|
|
123
|
+
| `defaultActorId` | `string` | `""` | Actor ID for the audit trail |
|
|
124
|
+
| `mock` | `boolean` | `false` | Enable mock mode (no HTTP calls) |
|
|
125
|
+
| `mockPassRate` | `number` | `1.0` | Pass probability in mock mode (0.0–1.0) |
|
|
126
|
+
| `timeoutMs` | `number` | `30000` | HTTP timeout in milliseconds |
|
|
127
|
+
|
|
128
|
+
## API Reference
|
|
129
|
+
|
|
130
|
+
### `check(entityType, data, options?)`
|
|
131
|
+
|
|
132
|
+
Submit a single record for compliance checking.
|
|
133
|
+
|
|
134
|
+
```typescript
|
|
135
|
+
const result = await client.check("SukukBond", data, {
|
|
136
|
+
action: "upsert",
|
|
137
|
+
entityId: "BOND-001",
|
|
138
|
+
schemaVersion: "1.0",
|
|
139
|
+
actorId: "core-banking-feed",
|
|
140
|
+
});
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Returns: `Promise<ComplianceResult>`
|
|
144
|
+
|
|
145
|
+
### `checkBatch(items, options?)`
|
|
146
|
+
|
|
147
|
+
Submit up to 500 records in a single call.
|
|
148
|
+
|
|
149
|
+
```typescript
|
|
150
|
+
const result = await client.checkBatch(items, {
|
|
151
|
+
feedLabel: "core-banking-feed",
|
|
152
|
+
defaultActorId: "core-banking-feed",
|
|
153
|
+
});
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
Returns: `Promise<BatchResult>`
|
|
157
|
+
|
|
158
|
+
### `checkWithEvidence(entityType, data, evidence, options?)`
|
|
159
|
+
|
|
160
|
+
Submit a record with oracle evidence attached.
|
|
161
|
+
|
|
162
|
+
Returns: `Promise<ComplianceResult>`
|
|
163
|
+
|
|
164
|
+
### `fetchFxRate(from, to, options?)`
|
|
165
|
+
### `fetchKycStatus(subjectId, options?)`
|
|
166
|
+
### `fetchCreditScore(subjectId, options?)`
|
|
167
|
+
### `fetchSanctions(subjectId, options?)`
|
|
168
|
+
|
|
169
|
+
Fetch oracle evidence items from registered providers.
|
|
170
|
+
|
|
171
|
+
Returns: `Promise<EvidenceItem>`
|
|
172
|
+
|
|
173
|
+
### `verify(recordId, bearerToken)`
|
|
174
|
+
|
|
175
|
+
Retrieve an immutable compliance record from the ledger.
|
|
176
|
+
|
|
177
|
+
Returns: `Promise<Record<string, unknown>>`
|
|
178
|
+
|
|
179
|
+
## Types
|
|
180
|
+
|
|
181
|
+
### `ComplianceResult`
|
|
182
|
+
|
|
183
|
+
```typescript
|
|
184
|
+
interface ComplianceResult {
|
|
185
|
+
passed: boolean;
|
|
186
|
+
recordId?: string; // present when passed=true
|
|
187
|
+
requestId: string;
|
|
188
|
+
entityId: string;
|
|
189
|
+
failReason?: string; // present when passed=false
|
|
190
|
+
failedStep?: number; // 8=schema validation, 9=policy check
|
|
191
|
+
feedLabel?: string | null;
|
|
192
|
+
mock: boolean;
|
|
193
|
+
}
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### `BatchResult`
|
|
197
|
+
|
|
198
|
+
```typescript
|
|
199
|
+
interface BatchResult {
|
|
200
|
+
batchId: string;
|
|
201
|
+
total: number;
|
|
202
|
+
accepted: number;
|
|
203
|
+
rejected: number;
|
|
204
|
+
results: ComplianceResult[];
|
|
205
|
+
feedLabel?: string | null;
|
|
206
|
+
mock: boolean;
|
|
207
|
+
}
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
### `CheckItem`
|
|
211
|
+
|
|
212
|
+
```typescript
|
|
213
|
+
interface CheckItem {
|
|
214
|
+
entityType: string;
|
|
215
|
+
data: Record<string, unknown>;
|
|
216
|
+
action?: string; // default "upsert"
|
|
217
|
+
entityId?: string; // auto-generated if omitted
|
|
218
|
+
schemaVersion?: string; // auto-resolved if omitted
|
|
219
|
+
actorId?: string;
|
|
220
|
+
}
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
## Requirements
|
|
224
|
+
|
|
225
|
+
- Node.js 18+
|
|
226
|
+
- No external runtime dependencies (uses native `fetch`, `crypto`)
|
|
227
|
+
|
|
228
|
+
## License
|
|
229
|
+
|
|
230
|
+
MIT © Trustchain Labs
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TrustStateClient — async HTTP client for the TrustState compliance API.
|
|
3
|
+
*
|
|
4
|
+
* Uses native fetch (Node 18+) and crypto.randomUUID(). Zero runtime dependencies.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```typescript
|
|
8
|
+
* import { TrustStateClient } from "@truststate/sdk";
|
|
9
|
+
*
|
|
10
|
+
* const client = new TrustStateClient({ apiKey: "your-key" });
|
|
11
|
+
* const result = await client.check("AgentResponse", { text: "Hello!", score: 0.95 });
|
|
12
|
+
* console.log(result.passed, result.recordId);
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
15
|
+
import type { BatchResult, CheckItem, ComplianceResult, EvidenceItem, TrustStateClientOptions } from "./types.js";
|
|
16
|
+
export declare class TrustStateClient {
|
|
17
|
+
private readonly apiKey;
|
|
18
|
+
private readonly baseUrl;
|
|
19
|
+
private readonly defaultSchemaVersion;
|
|
20
|
+
private readonly defaultActorId;
|
|
21
|
+
private readonly mock;
|
|
22
|
+
private readonly mockPassRate;
|
|
23
|
+
private readonly timeoutMs;
|
|
24
|
+
constructor(options: TrustStateClientOptions);
|
|
25
|
+
/**
|
|
26
|
+
* Submit a single record for compliance checking.
|
|
27
|
+
*
|
|
28
|
+
* Internally wraps the record in a one-item batch call (POST /v1/write/batch).
|
|
29
|
+
*
|
|
30
|
+
* @param entityType - Entity category (e.g. "AgentResponse").
|
|
31
|
+
* @param data - The record payload to validate.
|
|
32
|
+
* @param options - Optional overrides for action, entityId, schemaVersion, actorId.
|
|
33
|
+
* @returns ComplianceResult with pass/fail status and, if passed, a recordId.
|
|
34
|
+
* @throws TrustStateError on HTTP 4xx/5xx.
|
|
35
|
+
*/
|
|
36
|
+
check(entityType: string, data: Record<string, unknown>, options?: {
|
|
37
|
+
action?: string;
|
|
38
|
+
entityId?: string;
|
|
39
|
+
schemaVersion?: string;
|
|
40
|
+
actorId?: string;
|
|
41
|
+
}): Promise<ComplianceResult>;
|
|
42
|
+
/**
|
|
43
|
+
* Submit multiple records for compliance checking in a single API call.
|
|
44
|
+
*
|
|
45
|
+
* @param items - Array of CheckItem objects.
|
|
46
|
+
* @param options - Optional default schemaVersion and actorId for items that omit them.
|
|
47
|
+
* @returns BatchResult with per-item results and aggregate counts.
|
|
48
|
+
* @throws TrustStateError on HTTP 4xx/5xx.
|
|
49
|
+
*/
|
|
50
|
+
checkBatch(items: CheckItem[], options?: {
|
|
51
|
+
defaultSchemaVersion?: string;
|
|
52
|
+
defaultActorId?: string;
|
|
53
|
+
/** Label identifying this feed/source — echoed back on every item result. */
|
|
54
|
+
feedLabel?: string;
|
|
55
|
+
}): Promise<BatchResult>;
|
|
56
|
+
/**
|
|
57
|
+
* Retrieve an immutable compliance record from the ledger.
|
|
58
|
+
*
|
|
59
|
+
* @param recordId - The record ID returned by a previous check() that passed.
|
|
60
|
+
* @param bearerToken - A valid Bearer token for the TrustState API.
|
|
61
|
+
* @returns The full record object from the API.
|
|
62
|
+
* @throws TrustStateError on HTTP 4xx/5xx.
|
|
63
|
+
*/
|
|
64
|
+
/** Fetch an FX rate oracle evidence item.
|
|
65
|
+
* @example
|
|
66
|
+
* const fx = await client.fetchFxRate("MYR", "USD");
|
|
67
|
+
* const result = await client.checkWithEvidence("SukukBond", data, [fx]);
|
|
68
|
+
*/
|
|
69
|
+
fetchFxRate(fromCurrency: string, toCurrency: string, providerId?: string, maxAgeSeconds?: number): Promise<EvidenceItem>;
|
|
70
|
+
/** Fetch a KYC status oracle evidence item. */
|
|
71
|
+
fetchKycStatus(subjectId: string, providerId?: string, maxAgeSeconds?: number): Promise<EvidenceItem>;
|
|
72
|
+
/** Fetch a credit score oracle evidence item. */
|
|
73
|
+
fetchCreditScore(subjectId: string, providerId?: string, maxAgeSeconds?: number): Promise<EvidenceItem>;
|
|
74
|
+
/** Fetch a sanctions screening oracle evidence item. */
|
|
75
|
+
fetchSanctions(subjectId: string, providerId?: string, maxAgeSeconds?: number): Promise<EvidenceItem>;
|
|
76
|
+
/** Submit a compliance check with oracle evidence attached.
|
|
77
|
+
* @example
|
|
78
|
+
* const fx = await client.fetchFxRate("MYR", "USD");
|
|
79
|
+
* const result = await client.checkWithEvidence("SukukBond", payload, [fx]);
|
|
80
|
+
*/
|
|
81
|
+
checkWithEvidence(entityType: string, data: Record<string, unknown>, evidence: EvidenceItem[], options?: {
|
|
82
|
+
action?: string;
|
|
83
|
+
entityId?: string;
|
|
84
|
+
schemaVersion?: string;
|
|
85
|
+
actorId?: string;
|
|
86
|
+
}): Promise<ComplianceResult>;
|
|
87
|
+
private makeEvidenceItem;
|
|
88
|
+
private parseEvidenceResponse;
|
|
89
|
+
verify(recordId: string, bearerToken: string): Promise<unknown>;
|
|
90
|
+
private get;
|
|
91
|
+
private post;
|
|
92
|
+
private parseBatchResponse;
|
|
93
|
+
private mockSingleResult;
|
|
94
|
+
private mockBatchResult;
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,KAAK,EACV,WAAW,EACX,SAAS,EACT,gBAAgB,EAChB,YAAY,EACZ,uBAAuB,EACxB,MAAM,YAAY,CAAC;AAIpB,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAS;IAC9C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAU;IAC/B,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;gBAEvB,OAAO,EAAE,uBAAuB;IAc5C;;;;;;;;;;OAUG;IACG,KAAK,CACT,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,OAAO,GAAE;QACP,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,OAAO,CAAC,EAAE,MAAM,CAAC;KACb,GACL,OAAO,CAAC,gBAAgB,CAAC;IA2B5B;;;;;;;OAOG;IACG,UAAU,CACd,KAAK,EAAE,SAAS,EAAE,EAClB,OAAO,GAAE;QACP,oBAAoB,CAAC,EAAE,MAAM,CAAC;QAC9B,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,6EAA6E;QAC7E,SAAS,CAAC,EAAE,MAAM,CAAC;KACf,GACL,OAAO,CAAC,WAAW,CAAC;IA+BvB;;;;;;;OAOG;IAKH;;;;OAIG;IACG,WAAW,CACf,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,EAClB,UAAU,SAAe,EACzB,aAAa,SAAM,GAClB,OAAO,CAAC,YAAY,CAAC;IAUxB,+CAA+C;IACzC,cAAc,CAClB,SAAS,EAAE,MAAM,EACjB,UAAU,SAAe,EACzB,aAAa,SAAQ,GACpB,OAAO,CAAC,YAAY,CAAC;IASxB,iDAAiD;IAC3C,gBAAgB,CACpB,SAAS,EAAE,MAAM,EACjB,UAAU,SAAkB,EAC5B,aAAa,SAAQ,GACpB,OAAO,CAAC,YAAY,CAAC;IASxB,wDAAwD;IAClD,cAAc,CAClB,SAAS,EAAE,MAAM,EACjB,UAAU,SAAoB,EAC9B,aAAa,SAAO,GACnB,OAAO,CAAC,YAAY,CAAC;IASxB;;;;OAIG;IACG,iBAAiB,CACrB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,QAAQ,EAAE,YAAY,EAAE,EACxB,OAAO,GAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,aAAa,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAO,GAC7F,OAAO,CAAC,gBAAgB,CAAC;IAkB5B,OAAO,CAAC,gBAAgB;IAqBxB,OAAO,CAAC,qBAAqB;IAsBvB,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;YAiCvD,GAAG;YAuBH,IAAI;IAoClB,OAAO,CAAC,kBAAkB;IAkC1B,OAAO,CAAC,gBAAgB;IAaxB,OAAO,CAAC,eAAe;CAoBxB"}
|