@agentkarma/sdk 0.1.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 +216 -0
- package/dist/client.d.ts +64 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +323 -0
- package/dist/client.js.map +1 -0
- package/dist/errors.d.ts +64 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +78 -0
- package/dist/errors.js.map +1 -0
- package/dist/feedback.d.ts +31 -0
- package/dist/feedback.d.ts.map +1 -0
- package/dist/feedback.js +35 -0
- package/dist/feedback.js.map +1 -0
- package/dist/index.d.ts +28 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- package/dist/policy.d.ts +105 -0
- package/dist/policy.d.ts.map +1 -0
- package/dist/policy.js +150 -0
- package/dist/policy.js.map +1 -0
- package/dist/types.d.ts +347 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +9 -0
- package/dist/types.js.map +1 -0
- package/package.json +57 -0
- package/src/client.ts +519 -0
- package/src/errors.ts +87 -0
- package/src/feedback.ts +51 -0
- package/src/index.ts +84 -0
- package/src/policy.ts +286 -0
- package/src/types.ts +406 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Kerem Noras
|
|
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,216 @@
|
|
|
1
|
+
# @agentkarma/sdk
|
|
2
|
+
|
|
3
|
+
TypeScript SDK for [AgentKarma](https://agentkarma.io) — the reputation layer for autonomous on-chain agents.
|
|
4
|
+
|
|
5
|
+
Add a `check_trust_before_execute` step to any agent flow in under 10 minutes.
|
|
6
|
+
|
|
7
|
+
- Framework-agnostic (Node 18+, Bun, Deno, browsers, edge runtimes)
|
|
8
|
+
- Zero runtime dependencies
|
|
9
|
+
- Typed responses for the public REST API
|
|
10
|
+
- Local trust-policy evaluator with explainable allow/deny decisions
|
|
11
|
+
- Never proxies, signs, or executes transactions on your behalf
|
|
12
|
+
|
|
13
|
+
## Install
|
|
14
|
+
|
|
15
|
+
```sh
|
|
16
|
+
npm install @agentkarma/sdk
|
|
17
|
+
# or
|
|
18
|
+
bun add @agentkarma/sdk
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Quick start — Solana karma lookup
|
|
22
|
+
|
|
23
|
+
```ts
|
|
24
|
+
import { createAgentKarmaClient } from '@agentkarma/sdk';
|
|
25
|
+
|
|
26
|
+
const ak = createAgentKarmaClient();
|
|
27
|
+
const snap = await ak.getKarma('AgentTradingBotWalletAddress…');
|
|
28
|
+
|
|
29
|
+
console.log(snap.provider?.score); // 0–100
|
|
30
|
+
console.log(snap.provider?.confidenceBadge); // 'receipt-backed' | 'behavior-inferred' | 'declared'
|
|
31
|
+
console.log(snap.autonomy.label); // 'agent-like' | 'mixed' | 'human-like' | null
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Quick start — Celo ERC-8004 lookup
|
|
35
|
+
|
|
36
|
+
```ts
|
|
37
|
+
import { createAgentKarmaClient } from '@agentkarma/sdk';
|
|
38
|
+
|
|
39
|
+
const ak = createAgentKarmaClient();
|
|
40
|
+
const agent = await ak.getCeloAgent(9058);
|
|
41
|
+
|
|
42
|
+
console.log(agent.owner); // 0x…
|
|
43
|
+
console.log(agent.registration?.name); // declared name from the agent registration JSON
|
|
44
|
+
console.log(agent.reputation?.average); // mean of unrevoked feedback values
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Trust-gated execution
|
|
48
|
+
|
|
49
|
+
The `evaluateTrust` helper is a pure function over a snapshot. No network. No side effects. Always returns `{ allowed, reasons, observed }`.
|
|
50
|
+
|
|
51
|
+
```ts
|
|
52
|
+
import { createAgentKarmaClient, evaluateTrust } from '@agentkarma/sdk';
|
|
53
|
+
|
|
54
|
+
const ak = createAgentKarmaClient();
|
|
55
|
+
|
|
56
|
+
async function shouldExecute(agentWallet: string) {
|
|
57
|
+
const snap = await ak.getKarma(agentWallet);
|
|
58
|
+
|
|
59
|
+
const decision = evaluateTrust(snap, {
|
|
60
|
+
face: 'provider',
|
|
61
|
+
minScore: 60,
|
|
62
|
+
requireReceiptBacked: true, // require Tier 1 signal present
|
|
63
|
+
acceptedConfidenceBadges: ['receipt-backed', 'behavior-inferred'],
|
|
64
|
+
minTxCount: 5,
|
|
65
|
+
rejectAutonomyLabels: ['agent-like'], // example: human-operated only
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
if (!decision.allowed) {
|
|
69
|
+
console.warn('rejected:', decision.reasons);
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
return true;
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Partner integration pattern
|
|
77
|
+
|
|
78
|
+
AgentKarma is non-routing. The SDK answers questions about reputation; it does not execute service calls or payments on your behalf. A partner (e.g. a service marketplace, x402 facilitator, agent orchestrator) preflights AgentKarma before performing its own action:
|
|
79
|
+
|
|
80
|
+
```ts
|
|
81
|
+
import { createAgentKarmaClient, evaluateTrust, AgentKarmaError } from '@agentkarma/sdk';
|
|
82
|
+
|
|
83
|
+
const ak = createAgentKarmaClient();
|
|
84
|
+
|
|
85
|
+
async function payAgentForService(agentWallet: string, amount: number) {
|
|
86
|
+
let snap;
|
|
87
|
+
try {
|
|
88
|
+
snap = await ak.getKarma(agentWallet);
|
|
89
|
+
} catch (err) {
|
|
90
|
+
// Hard fail-open or fail-closed? Your call. Fail-closed example:
|
|
91
|
+
if (err instanceof AgentKarmaError) {
|
|
92
|
+
throw new Error('Trust check failed: ' + err.message);
|
|
93
|
+
}
|
|
94
|
+
throw err;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const decision = evaluateTrust(snap, {
|
|
98
|
+
minScore: 70,
|
|
99
|
+
requireReceiptBacked: true,
|
|
100
|
+
minTxCount: 10,
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
if (!decision.allowed) {
|
|
104
|
+
throw new Error(`Agent ${agentWallet} did not pass trust check: ${decision.reasons.join('; ')}`);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Your own payment / service call goes here. AgentKarma never proxies it.
|
|
108
|
+
return await yourServiceCall(agentWallet, amount);
|
|
109
|
+
}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## Submitting consumer feedback (Solana)
|
|
113
|
+
|
|
114
|
+
Feedback submission is wallet-agnostic: the SDK builds the message, you sign it externally, the SDK posts the signature.
|
|
115
|
+
|
|
116
|
+
```ts
|
|
117
|
+
import { createAgentKarmaClient, buildFeedbackMessage } from '@agentkarma/sdk';
|
|
118
|
+
|
|
119
|
+
const ak = createAgentKarmaClient();
|
|
120
|
+
|
|
121
|
+
// 1. Build the canonical message
|
|
122
|
+
const { message, timestamp } = buildFeedbackMessage({
|
|
123
|
+
rating: 'delivered',
|
|
124
|
+
txSignature: 'YourSolanaTxSignature',
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
// 2. Sign with your wallet (any Solana wallet adapter, web3.js, etc.)
|
|
128
|
+
const signature = await yourWallet.signMessage(new TextEncoder().encode(message));
|
|
129
|
+
const signatureBase58 = base58Encode(signature);
|
|
130
|
+
|
|
131
|
+
// 3. Submit
|
|
132
|
+
await ak.submitFeedback({
|
|
133
|
+
agentWallet: 'AgentWalletAddress…',
|
|
134
|
+
rating: 'delivered',
|
|
135
|
+
txSignature: 'YourSolanaTxSignature',
|
|
136
|
+
signature: signatureBase58,
|
|
137
|
+
message,
|
|
138
|
+
});
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
The server enforces a 5-minute freshness window on the embedded timestamp.
|
|
142
|
+
|
|
143
|
+
## Configuration
|
|
144
|
+
|
|
145
|
+
```ts
|
|
146
|
+
const ak = createAgentKarmaClient({
|
|
147
|
+
baseUrl: 'https://agentkarma.io', // default
|
|
148
|
+
timeout: 10_000, // default ms
|
|
149
|
+
headers: { 'X-Partner': 'YourApp' },
|
|
150
|
+
userAgent: 'YourApp/1.0',
|
|
151
|
+
fetch: customFetch, // optional override
|
|
152
|
+
});
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
Each method accepts per-call options:
|
|
156
|
+
|
|
157
|
+
```ts
|
|
158
|
+
await ak.getKarma(wallet, {
|
|
159
|
+
face: 'provider', // 'provider' | 'consumer' | 'both' (default)
|
|
160
|
+
signal: abortController.signal, // request-level abort
|
|
161
|
+
timeout: 3000, // overrides client default for this call
|
|
162
|
+
headers: { 'X-Request-Id': 'abc' },
|
|
163
|
+
});
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
## Errors
|
|
167
|
+
|
|
168
|
+
Every error is an `AgentKarmaError` subclass:
|
|
169
|
+
|
|
170
|
+
| Class | When |
|
|
171
|
+
|---|---|
|
|
172
|
+
| `AgentKarmaValidationError` | Local argument check failed |
|
|
173
|
+
| `AgentKarmaNotFoundError` | Server returned 404 |
|
|
174
|
+
| `AgentKarmaRateLimitError` | Server returned 429 (with `retryAfter` in seconds) |
|
|
175
|
+
| `AgentKarmaTimeoutError` | Request deadline exceeded |
|
|
176
|
+
| `AgentKarmaNetworkError` | `fetch()` threw before getting a response |
|
|
177
|
+
| `AgentKarmaMalformedResponseError` | 2xx response body didn't match expected shape |
|
|
178
|
+
| `AgentKarmaServerError` | Other non-2xx response |
|
|
179
|
+
|
|
180
|
+
```ts
|
|
181
|
+
import { AgentKarmaError } from '@agentkarma/sdk';
|
|
182
|
+
try {
|
|
183
|
+
await ak.getKarma(wallet);
|
|
184
|
+
} catch (err) {
|
|
185
|
+
if (err instanceof AgentKarmaError) {
|
|
186
|
+
console.error(`status=${err.status} response=`, err.response);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
## Public methods
|
|
192
|
+
|
|
193
|
+
| Method | Endpoint |
|
|
194
|
+
|---|---|
|
|
195
|
+
| `getKarma(wallet, { face?, … })` | `GET /api/v2/score/{wallet}?face={face}` |
|
|
196
|
+
| `getProviderKarma(wallet)` | shortcut for provider face only |
|
|
197
|
+
| `getConsumerKarma(wallet)` | shortcut for consumer face only |
|
|
198
|
+
| `getCeloAgent(agentId)` | `GET /api/v2/celo/{agentId}` |
|
|
199
|
+
| `searchAgents(query, { limit? })` | `GET /api/search?q={query}` |
|
|
200
|
+
| `getAgentHistory(wallet, { limit?, offset? })` | `GET /api/agent/{wallet}/history` |
|
|
201
|
+
| `getFeedbackSummary(wallet)` | `GET /api/feedback?agent={wallet}` |
|
|
202
|
+
| `submitFeedback(input)` | `POST /api/feedback` |
|
|
203
|
+
|
|
204
|
+
## Non-routing guarantee
|
|
205
|
+
|
|
206
|
+
AgentKarma is a reputation primitive. This SDK is read-only by design. It never:
|
|
207
|
+
- proxies API calls or x402 payments
|
|
208
|
+
- signs transactions on your behalf
|
|
209
|
+
- holds private keys
|
|
210
|
+
- ratelimits or queues your traffic
|
|
211
|
+
|
|
212
|
+
You always make your own service calls. AgentKarma just answers the trust question.
|
|
213
|
+
|
|
214
|
+
## License
|
|
215
|
+
|
|
216
|
+
MIT
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AgentKarma typed HTTP client.
|
|
3
|
+
*
|
|
4
|
+
* Framework-agnostic. Works in Node 18+, Bun, Deno, browsers, edge runtimes —
|
|
5
|
+
* anywhere global `fetch` is available (or you provide one).
|
|
6
|
+
*/
|
|
7
|
+
import { AgentKarmaError } from './errors.js';
|
|
8
|
+
import type { AgentHistoryResponse, BondBlock, CeloAgentSnapshot, Chain, ClientConfig, FeedbackSubmission, FeedbackSubmissionResponse, FeedbackSummary, KarmaFace, KarmaFaceData, KarmaSnapshot, RequestOptions, SearchResponse, SuccessionView, SuretyView } from './types.js';
|
|
9
|
+
export interface AgentKarmaClient {
|
|
10
|
+
readonly baseUrl: string;
|
|
11
|
+
/**
|
|
12
|
+
* GET /api/v2/score/{wallet}?face={face} — full karma snapshot.
|
|
13
|
+
*
|
|
14
|
+
* `chain` is OPTIONAL and defaults to `'solana'` for back-compat. Pass it for
|
|
15
|
+
* celo/arc/stellar wallets so the SDK applies the right address validation
|
|
16
|
+
* (Solana base58 only applies to Solana). The server resolves the wallet's
|
|
17
|
+
* real chain from the address; we NEVER auto-detect an EVM chain client-side.
|
|
18
|
+
*/
|
|
19
|
+
getKarma(wallet: string, opts?: {
|
|
20
|
+
face?: KarmaFace | 'both';
|
|
21
|
+
chain?: Chain;
|
|
22
|
+
} & RequestOptions): Promise<KarmaSnapshot>;
|
|
23
|
+
/** Shorthand for `getKarma(wallet, { face: 'provider' })`. Returns just the provider face. */
|
|
24
|
+
getProviderKarma(wallet: string, opts?: RequestOptions): Promise<KarmaFaceData>;
|
|
25
|
+
/** Shorthand for `getKarma(wallet, { face: 'consumer' })`. Returns just the consumer face. */
|
|
26
|
+
getConsumerKarma(wallet: string, opts?: RequestOptions): Promise<KarmaFaceData | null>;
|
|
27
|
+
/** GET /api/v2/celo/{agentId} — ERC-8004 IdentityRegistry + ReputationRegistry snapshot. */
|
|
28
|
+
getCeloAgent(agentId: number, opts?: RequestOptions): Promise<CeloAgentSnapshot>;
|
|
29
|
+
/** GET /api/search?q={query} — substring search over indexed wallets. */
|
|
30
|
+
searchAgents(query: string, opts?: {
|
|
31
|
+
limit?: number;
|
|
32
|
+
} & RequestOptions): Promise<SearchResponse>;
|
|
33
|
+
/** GET /api/agent/{wallet}/history — paginated x402 history with feedback ratings. */
|
|
34
|
+
getAgentHistory(wallet: string, opts?: {
|
|
35
|
+
limit?: number;
|
|
36
|
+
offset?: number;
|
|
37
|
+
} & RequestOptions): Promise<AgentHistoryResponse>;
|
|
38
|
+
/** GET /api/feedback?agent={wallet} — aggregate delivered/failed counts. */
|
|
39
|
+
getFeedbackSummary(wallet: string, opts?: RequestOptions): Promise<FeedbackSummary>;
|
|
40
|
+
/**
|
|
41
|
+
* GET /api/v2/succession/{chain}/{wallet} — declared Dead Man's Switch plan
|
|
42
|
+
* + AK's OBSERVED heartbeat liveness. `chain` is explicit (spans all chains);
|
|
43
|
+
* Solana wallets are shape-checked, others passed through. Throws
|
|
44
|
+
* AgentKarmaNotFoundError (404) when the agent declared no succession plan.
|
|
45
|
+
*/
|
|
46
|
+
getSuccessionStatus(chain: Chain, wallet: string, opts?: RequestOptions): Promise<SuccessionView>;
|
|
47
|
+
/**
|
|
48
|
+
* GET /api/v2/bond/{chain}/{wallet} → `.bonds` — bonds taken out ON this
|
|
49
|
+
* agent (open vs resolved, totalBondedUsdc, hasDemo). `chain` is explicit.
|
|
50
|
+
* Returns an empty block (no throw) when the agent has no bonds.
|
|
51
|
+
*/
|
|
52
|
+
getBondStatus(chain: Chain, wallet: string, opts?: RequestOptions): Promise<BondBlock>;
|
|
53
|
+
/**
|
|
54
|
+
* GET /api/v2/bond/{chain}/{wallet} → `.surety` — this wallet's ORTHOGONAL
|
|
55
|
+
* Surety Karma from underwriting OTHER agents' bonds. `chain` is explicit.
|
|
56
|
+
* Returns null when the wallet has never underwritten.
|
|
57
|
+
*/
|
|
58
|
+
getSuretyKarma(chain: Chain, wallet: string, opts?: RequestOptions): Promise<SuretyView | null>;
|
|
59
|
+
/** POST /api/feedback — submit a wallet-signed consumer rating (Solana-only today). */
|
|
60
|
+
submitFeedback(input: FeedbackSubmission, opts?: RequestOptions): Promise<FeedbackSubmissionResponse>;
|
|
61
|
+
}
|
|
62
|
+
export declare function createAgentKarmaClient(config?: ClientConfig): AgentKarmaClient;
|
|
63
|
+
export { AgentKarmaError };
|
|
64
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACL,eAAe,EAQhB,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EACV,oBAAoB,EACpB,SAAS,EAET,iBAAiB,EACjB,KAAK,EACL,YAAY,EACZ,kBAAkB,EAClB,0BAA0B,EAC1B,eAAe,EAEf,SAAS,EACT,aAAa,EACb,aAAa,EACb,cAAc,EACd,cAAc,EAEd,cAAc,EACd,UAAU,EACX,MAAM,YAAY,CAAC;AAqMpB,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAEzB;;;;;;;OAOG;IACH,QAAQ,CACN,MAAM,EAAE,MAAM,EACd,IAAI,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,KAAK,CAAA;KAAE,GAAG,cAAc,GACnE,OAAO,CAAC,aAAa,CAAC,CAAC;IAE1B,8FAA8F;IAC9F,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;IAEhF,8FAA8F;IAC9F,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAAC;IAEvF,4FAA4F;IAC5F,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAEjF,yEAAyE;IACzE,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;IAEjG,sFAAsF;IACtF,eAAe,CACb,MAAM,EAAE,MAAM,EACd,IAAI,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,cAAc,GAC1D,OAAO,CAAC,oBAAoB,CAAC,CAAC;IAEjC,4EAA4E;IAC5E,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;IAEpF;;;;;OAKG;IACH,mBAAmB,CACjB,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,MAAM,EACd,IAAI,CAAC,EAAE,cAAc,GACpB,OAAO,CAAC,cAAc,CAAC,CAAC;IAE3B;;;;OAIG;IACH,aAAa,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IAEvF;;;;OAIG;IACH,cAAc,CACZ,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,MAAM,EACd,IAAI,CAAC,EAAE,cAAc,GACpB,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;IAE9B,uFAAuF;IACvF,cAAc,CAAC,KAAK,EAAE,kBAAkB,EAAE,IAAI,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,0BAA0B,CAAC,CAAC;CACvG;AAED,wBAAgB,sBAAsB,CAAC,MAAM,CAAC,EAAE,YAAY,GAAG,gBAAgB,CA8L9E;AAwBD,OAAO,EAAE,eAAe,EAAE,CAAC"}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AgentKarma typed HTTP client.
|
|
3
|
+
*
|
|
4
|
+
* Framework-agnostic. Works in Node 18+, Bun, Deno, browsers, edge runtimes —
|
|
5
|
+
* anywhere global `fetch` is available (or you provide one).
|
|
6
|
+
*/
|
|
7
|
+
import { AgentKarmaError, AgentKarmaMalformedResponseError, AgentKarmaNetworkError, AgentKarmaNotFoundError, AgentKarmaRateLimitError, AgentKarmaServerError, AgentKarmaTimeoutError, AgentKarmaValidationError, } from './errors.js';
|
|
8
|
+
const SDK_VERSION = '0.1.0';
|
|
9
|
+
const DEFAULT_BASE_URL = 'https://agentkarma.io';
|
|
10
|
+
const DEFAULT_TIMEOUT_MS = 10_000;
|
|
11
|
+
const SOLANA_ADDRESS_RE = /^[1-9A-HJ-NP-Za-km-z]{32,44}$/;
|
|
12
|
+
const SUPPORTED_CHAINS = ['solana', 'celo', 'stellar', 'arc'];
|
|
13
|
+
function normalizeConfig(input) {
|
|
14
|
+
const baseUrl = (input?.baseUrl ?? DEFAULT_BASE_URL).replace(/\/+$/, '');
|
|
15
|
+
const userAgent = input?.userAgent ?? `@agentkarma/sdk/${SDK_VERSION}`;
|
|
16
|
+
return {
|
|
17
|
+
baseUrl,
|
|
18
|
+
fetchImpl: input?.fetch ?? globalThis.fetch,
|
|
19
|
+
timeout: input?.timeout ?? DEFAULT_TIMEOUT_MS,
|
|
20
|
+
headers: {
|
|
21
|
+
'User-Agent': userAgent,
|
|
22
|
+
Accept: 'application/json',
|
|
23
|
+
...(input?.headers ?? {}),
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
function buildSignal(configTimeout, opts) {
|
|
28
|
+
const timeoutMs = opts?.timeout ?? configTimeout;
|
|
29
|
+
const timeoutController = new AbortController();
|
|
30
|
+
const timeoutId = setTimeout(() => timeoutController.abort(), timeoutMs);
|
|
31
|
+
// Compose caller's signal + timeout signal. AbortSignal.any() is available
|
|
32
|
+
// in modern Node/Bun/browsers; fall back to a manual relay otherwise.
|
|
33
|
+
let composed;
|
|
34
|
+
if (opts?.signal) {
|
|
35
|
+
if (typeof AbortSignal !== 'undefined' && typeof AbortSignal.any === 'function') {
|
|
36
|
+
composed = AbortSignal.any([
|
|
37
|
+
opts.signal,
|
|
38
|
+
timeoutController.signal,
|
|
39
|
+
]);
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
const relayController = new AbortController();
|
|
43
|
+
const relay = () => relayController.abort();
|
|
44
|
+
opts.signal.addEventListener('abort', relay, { once: true });
|
|
45
|
+
timeoutController.signal.addEventListener('abort', relay, { once: true });
|
|
46
|
+
composed = relayController.signal;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
composed = timeoutController.signal;
|
|
51
|
+
}
|
|
52
|
+
return {
|
|
53
|
+
signal: composed,
|
|
54
|
+
timeoutSignal: timeoutController.signal,
|
|
55
|
+
timeoutMs,
|
|
56
|
+
cleanup: () => clearTimeout(timeoutId),
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
async function readBodySafe(res) {
|
|
60
|
+
const ct = res.headers.get('content-type') ?? '';
|
|
61
|
+
try {
|
|
62
|
+
if (ct.includes('application/json'))
|
|
63
|
+
return await res.json();
|
|
64
|
+
return await res.text();
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
return undefined;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
function assertSolanaWallet(wallet) {
|
|
71
|
+
if (!wallet || typeof wallet !== 'string') {
|
|
72
|
+
throw new AgentKarmaValidationError('wallet must be a non-empty string');
|
|
73
|
+
}
|
|
74
|
+
if (!SOLANA_ADDRESS_RE.test(wallet)) {
|
|
75
|
+
throw new AgentKarmaValidationError('wallet does not look like a Solana address (expected base58, 32-44 chars)');
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
function assertAgentId(agentId) {
|
|
79
|
+
if (!Number.isInteger(agentId) || agentId <= 0) {
|
|
80
|
+
throw new AgentKarmaValidationError('agentId must be a positive integer');
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
function assertChain(chain) {
|
|
84
|
+
if (typeof chain !== 'string' || !SUPPORTED_CHAINS.includes(chain)) {
|
|
85
|
+
throw new AgentKarmaValidationError(`chain must be one of ${SUPPORTED_CHAINS.join(', ')}`);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Validate a wallet for a chain-aware lookup. DELIBERATELY does NOT apply the
|
|
90
|
+
* Solana base58 shape to EVM/Stellar chains — bonds and successions span chains
|
|
91
|
+
* whose addresses are not base58 Solana keys. We never auto-detect the chain
|
|
92
|
+
* from the address (the chain is always passed explicitly). Solana keeps its
|
|
93
|
+
* strict shape; other chains only require a non-empty string and let the server
|
|
94
|
+
* be the authority (it keys by the composite (chain,address)).
|
|
95
|
+
*/
|
|
96
|
+
function assertWalletForChain(wallet, chain) {
|
|
97
|
+
if (!wallet || typeof wallet !== 'string') {
|
|
98
|
+
throw new AgentKarmaValidationError('wallet must be a non-empty string');
|
|
99
|
+
}
|
|
100
|
+
if (chain === 'solana') {
|
|
101
|
+
assertSolanaWallet(wallet);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
async function request(cfg, path, init, opts) {
|
|
105
|
+
const url = `${cfg.baseUrl}${path}`;
|
|
106
|
+
const { signal, timeoutSignal, timeoutMs, cleanup } = buildSignal(cfg.timeout, opts);
|
|
107
|
+
let res;
|
|
108
|
+
try {
|
|
109
|
+
res = await cfg.fetchImpl(url, {
|
|
110
|
+
...init,
|
|
111
|
+
signal,
|
|
112
|
+
headers: { ...cfg.headers, ...(init.headers ?? {}), ...(opts?.headers ?? {}) },
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
catch (err) {
|
|
116
|
+
cleanup();
|
|
117
|
+
// The timeout's own controller having fired is the most reliable signal
|
|
118
|
+
// that we exceeded the deadline — works regardless of which runtime's
|
|
119
|
+
// AbortError shape was thrown by fetch (Bun vs Node vs browser).
|
|
120
|
+
if (timeoutSignal.aborted) {
|
|
121
|
+
throw new AgentKarmaTimeoutError(timeoutMs);
|
|
122
|
+
}
|
|
123
|
+
if (err instanceof Error && (err.name === 'AbortError' || err.name === 'TimeoutError')) {
|
|
124
|
+
throw new AgentKarmaTimeoutError(timeoutMs);
|
|
125
|
+
}
|
|
126
|
+
throw new AgentKarmaNetworkError(err instanceof Error ? err.message : String(err), err);
|
|
127
|
+
}
|
|
128
|
+
cleanup();
|
|
129
|
+
if (res.status === 429) {
|
|
130
|
+
const retryAfter = Number(res.headers.get('retry-after') ?? '0');
|
|
131
|
+
const body = await readBodySafe(res);
|
|
132
|
+
throw new AgentKarmaRateLimitError('AgentKarma rate limit exceeded', { response: body, retryAfter: Number.isFinite(retryAfter) && retryAfter > 0 ? retryAfter : undefined });
|
|
133
|
+
}
|
|
134
|
+
if (res.status === 404) {
|
|
135
|
+
const body = await readBodySafe(res);
|
|
136
|
+
const msg = typeof body === 'object' && body && 'error' in body
|
|
137
|
+
? String(body.error)
|
|
138
|
+
: `Not found at ${path}`;
|
|
139
|
+
throw new AgentKarmaNotFoundError(msg, { response: body });
|
|
140
|
+
}
|
|
141
|
+
if (!res.ok) {
|
|
142
|
+
const body = await readBodySafe(res);
|
|
143
|
+
const msg = typeof body === 'object' && body && 'error' in body
|
|
144
|
+
? String(body.error)
|
|
145
|
+
: `AgentKarma server returned ${res.status}`;
|
|
146
|
+
throw new AgentKarmaServerError(msg, { status: res.status, response: body });
|
|
147
|
+
}
|
|
148
|
+
let parsed;
|
|
149
|
+
try {
|
|
150
|
+
parsed = await res.json();
|
|
151
|
+
}
|
|
152
|
+
catch (err) {
|
|
153
|
+
throw new AgentKarmaMalformedResponseError('Response body is not valid JSON', { cause: err });
|
|
154
|
+
}
|
|
155
|
+
return parsed;
|
|
156
|
+
}
|
|
157
|
+
export function createAgentKarmaClient(config) {
|
|
158
|
+
const cfg = normalizeConfig(config);
|
|
159
|
+
return {
|
|
160
|
+
baseUrl: cfg.baseUrl,
|
|
161
|
+
async getKarma(wallet, opts = {}) {
|
|
162
|
+
// Chain-aware: default 'solana' (back-compat). assertWalletForChain applies
|
|
163
|
+
// the strict base58 shape only for Solana; other chains pass through to the
|
|
164
|
+
// server. We do NOT auto-detect an EVM chain from the address.
|
|
165
|
+
const chain = opts.chain ?? 'solana';
|
|
166
|
+
assertChain(chain);
|
|
167
|
+
assertWalletForChain(wallet, chain);
|
|
168
|
+
const face = opts.face ?? 'both';
|
|
169
|
+
if (face !== 'both' && face !== 'provider' && face !== 'consumer') {
|
|
170
|
+
throw new AgentKarmaValidationError(`face must be 'provider' | 'consumer' | 'both'`);
|
|
171
|
+
}
|
|
172
|
+
const path = `/api/v2/score/${encodeURIComponent(wallet)}?face=${face}`;
|
|
173
|
+
const snap = await request(cfg, path, { method: 'GET' }, opts);
|
|
174
|
+
validateKarmaSnapshot(snap);
|
|
175
|
+
return snap;
|
|
176
|
+
},
|
|
177
|
+
async getProviderKarma(wallet, opts) {
|
|
178
|
+
const snap = await this.getKarma(wallet, { ...opts, face: 'provider' });
|
|
179
|
+
if (!snap.provider) {
|
|
180
|
+
throw new AgentKarmaMalformedResponseError('Server omitted provider face from response', { response: snap });
|
|
181
|
+
}
|
|
182
|
+
return snap.provider;
|
|
183
|
+
},
|
|
184
|
+
async getConsumerKarma(wallet, opts) {
|
|
185
|
+
const snap = await this.getKarma(wallet, { ...opts, face: 'consumer' });
|
|
186
|
+
// Consumer face is allowed to be absent (the wallet may have no consumer
|
|
187
|
+
// signal). Surface null rather than throw — caller decides.
|
|
188
|
+
return snap.consumer ?? null;
|
|
189
|
+
},
|
|
190
|
+
async getCeloAgent(agentId, opts) {
|
|
191
|
+
assertAgentId(agentId);
|
|
192
|
+
const path = `/api/v2/celo/${agentId}`;
|
|
193
|
+
const snap = await request(cfg, path, { method: 'GET' }, opts);
|
|
194
|
+
if (snap.chain !== 'celo' || typeof snap.owner !== 'string') {
|
|
195
|
+
throw new AgentKarmaMalformedResponseError('Celo agent response missing required fields', { response: snap });
|
|
196
|
+
}
|
|
197
|
+
return snap;
|
|
198
|
+
},
|
|
199
|
+
async searchAgents(query, opts = {}) {
|
|
200
|
+
if (typeof query !== 'string' || query.trim().length < 3) {
|
|
201
|
+
throw new AgentKarmaValidationError('query must be a string of at least 3 characters');
|
|
202
|
+
}
|
|
203
|
+
const params = new URLSearchParams({ q: query.trim() });
|
|
204
|
+
if (opts.limit != null)
|
|
205
|
+
params.set('limit', String(opts.limit));
|
|
206
|
+
const path = `/api/search?${params.toString()}`;
|
|
207
|
+
const res = await request(cfg, path, { method: 'GET' }, opts);
|
|
208
|
+
if (!res || !Array.isArray(res.results)) {
|
|
209
|
+
throw new AgentKarmaMalformedResponseError('Search response missing results array', { response: res });
|
|
210
|
+
}
|
|
211
|
+
return res;
|
|
212
|
+
},
|
|
213
|
+
async getAgentHistory(wallet, opts = {}) {
|
|
214
|
+
assertSolanaWallet(wallet);
|
|
215
|
+
const params = new URLSearchParams();
|
|
216
|
+
if (opts.limit != null)
|
|
217
|
+
params.set('limit', String(opts.limit));
|
|
218
|
+
if (opts.offset != null)
|
|
219
|
+
params.set('offset', String(opts.offset));
|
|
220
|
+
const qs = params.toString();
|
|
221
|
+
const path = `/api/agent/${encodeURIComponent(wallet)}/history${qs ? `?${qs}` : ''}`;
|
|
222
|
+
const res = await request(cfg, path, { method: 'GET' }, opts);
|
|
223
|
+
if (!res || !Array.isArray(res.transactions)) {
|
|
224
|
+
throw new AgentKarmaMalformedResponseError('History response missing transactions array', { response: res });
|
|
225
|
+
}
|
|
226
|
+
return res;
|
|
227
|
+
},
|
|
228
|
+
async getFeedbackSummary(wallet, opts) {
|
|
229
|
+
assertSolanaWallet(wallet);
|
|
230
|
+
const path = `/api/feedback?agent=${encodeURIComponent(wallet)}`;
|
|
231
|
+
const res = await request(cfg, path, { method: 'GET' }, opts);
|
|
232
|
+
if (typeof res !== 'object' ||
|
|
233
|
+
res === null ||
|
|
234
|
+
typeof res.total !== 'number') {
|
|
235
|
+
throw new AgentKarmaMalformedResponseError('Feedback summary response shape unexpected', { response: res });
|
|
236
|
+
}
|
|
237
|
+
return res;
|
|
238
|
+
},
|
|
239
|
+
async getSuccessionStatus(chain, wallet, opts) {
|
|
240
|
+
assertChain(chain);
|
|
241
|
+
assertWalletForChain(wallet, chain);
|
|
242
|
+
const path = `/api/v2/succession/${chain}/${encodeURIComponent(wallet)}`;
|
|
243
|
+
const raw = await request(cfg, path, { method: 'GET' }, opts);
|
|
244
|
+
const res = raw;
|
|
245
|
+
const s = res?.succession;
|
|
246
|
+
if (!s || typeof s !== 'object') {
|
|
247
|
+
throw new AgentKarmaMalformedResponseError('Succession response missing succession block', { response: raw });
|
|
248
|
+
}
|
|
249
|
+
if (typeof s.status !== 'string' || typeof s.intervalSeconds !== 'number') {
|
|
250
|
+
throw new AgentKarmaMalformedResponseError('Succession view missing required fields (status, intervalSeconds)', { response: raw });
|
|
251
|
+
}
|
|
252
|
+
return s;
|
|
253
|
+
},
|
|
254
|
+
async getBondStatus(chain, wallet, opts) {
|
|
255
|
+
assertChain(chain);
|
|
256
|
+
assertWalletForChain(wallet, chain);
|
|
257
|
+
const path = `/api/v2/bond/${chain}/${encodeURIComponent(wallet)}`;
|
|
258
|
+
const raw = await request(cfg, path, { method: 'GET' }, opts);
|
|
259
|
+
const res = raw;
|
|
260
|
+
const block = res?.bonds;
|
|
261
|
+
if (!block ||
|
|
262
|
+
typeof block !== 'object' ||
|
|
263
|
+
!Array.isArray(block.open) ||
|
|
264
|
+
!Array.isArray(block.resolved) ||
|
|
265
|
+
typeof block.totalBondedUsdc !== 'number') {
|
|
266
|
+
throw new AgentKarmaMalformedResponseError('Bond response missing bonds block', { response: raw });
|
|
267
|
+
}
|
|
268
|
+
return block;
|
|
269
|
+
},
|
|
270
|
+
async getSuretyKarma(chain, wallet, opts) {
|
|
271
|
+
assertChain(chain);
|
|
272
|
+
assertWalletForChain(wallet, chain);
|
|
273
|
+
const path = `/api/v2/bond/${chain}/${encodeURIComponent(wallet)}`;
|
|
274
|
+
const res = await request(cfg, path, { method: 'GET' }, opts);
|
|
275
|
+
// Surety is allowed to be absent (the wallet may never have underwritten).
|
|
276
|
+
// Surface null rather than throw — caller decides.
|
|
277
|
+
return res?.surety ?? null;
|
|
278
|
+
},
|
|
279
|
+
async submitFeedback(input, opts) {
|
|
280
|
+
if (!input || typeof input !== 'object') {
|
|
281
|
+
throw new AgentKarmaValidationError('feedback submission must be an object');
|
|
282
|
+
}
|
|
283
|
+
if (!input.agentWallet || !input.txSignature || !input.signature || !input.message) {
|
|
284
|
+
throw new AgentKarmaValidationError('feedback submission requires agentWallet, txSignature, signature, message');
|
|
285
|
+
}
|
|
286
|
+
if (input.rating !== 'delivered' && input.rating !== 'failed') {
|
|
287
|
+
throw new AgentKarmaValidationError(`rating must be 'delivered' or 'failed'`);
|
|
288
|
+
}
|
|
289
|
+
const res = await request(cfg, '/api/feedback', {
|
|
290
|
+
method: 'POST',
|
|
291
|
+
body: JSON.stringify(input),
|
|
292
|
+
headers: { 'Content-Type': 'application/json' },
|
|
293
|
+
}, opts);
|
|
294
|
+
if (res?.success !== true) {
|
|
295
|
+
throw new AgentKarmaMalformedResponseError('Feedback submission response missing success flag', { response: res });
|
|
296
|
+
}
|
|
297
|
+
return res;
|
|
298
|
+
},
|
|
299
|
+
};
|
|
300
|
+
}
|
|
301
|
+
/**
|
|
302
|
+
* Lightweight runtime validation. We only assert presence of the load-bearing
|
|
303
|
+
* fields — the rest stays opaque so the server can evolve safely.
|
|
304
|
+
*/
|
|
305
|
+
function validateKarmaSnapshot(snap) {
|
|
306
|
+
if (!snap || typeof snap !== 'object') {
|
|
307
|
+
throw new AgentKarmaMalformedResponseError('Karma snapshot is not an object', { response: snap });
|
|
308
|
+
}
|
|
309
|
+
const s = snap;
|
|
310
|
+
if (typeof s.address !== 'string') {
|
|
311
|
+
throw new AgentKarmaMalformedResponseError('Karma snapshot missing address', { response: snap });
|
|
312
|
+
}
|
|
313
|
+
if (typeof s.face !== 'string') {
|
|
314
|
+
throw new AgentKarmaMalformedResponseError('Karma snapshot missing face', { response: snap });
|
|
315
|
+
}
|
|
316
|
+
if (typeof s.autonomy !== 'object' || s.autonomy === null) {
|
|
317
|
+
throw new AgentKarmaMalformedResponseError('Karma snapshot missing autonomy block', { response: snap });
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
// Re-export the top-level error class so consumers can write a single
|
|
321
|
+
// instanceof check without importing the errors module separately.
|
|
322
|
+
export { AgentKarmaError };
|
|
323
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACL,eAAe,EACf,gCAAgC,EAChC,sBAAsB,EACtB,uBAAuB,EACvB,wBAAwB,EACxB,qBAAqB,EACrB,sBAAsB,EACtB,yBAAyB,GAC1B,MAAM,aAAa,CAAC;AAsBrB,MAAM,WAAW,GAAG,OAAO,CAAC;AAC5B,MAAM,gBAAgB,GAAG,uBAAuB,CAAC;AACjD,MAAM,kBAAkB,GAAG,MAAM,CAAC;AAElC,MAAM,iBAAiB,GAAG,+BAA+B,CAAC;AAC1D,MAAM,gBAAgB,GAAqB,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;AAShF,SAAS,eAAe,CAAC,KAAoB;IAC3C,MAAM,OAAO,GAAG,CAAC,KAAK,EAAE,OAAO,IAAI,gBAAgB,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACzE,MAAM,SAAS,GAAG,KAAK,EAAE,SAAS,IAAI,mBAAmB,WAAW,EAAE,CAAC;IACvE,OAAO;QACL,OAAO;QACP,SAAS,EAAE,KAAK,EAAE,KAAK,IAAI,UAAU,CAAC,KAAK;QAC3C,OAAO,EAAE,KAAK,EAAE,OAAO,IAAI,kBAAkB;QAC7C,OAAO,EAAE;YACP,YAAY,EAAE,SAAS;YACvB,MAAM,EAAE,kBAAkB;YAC1B,GAAG,CAAC,KAAK,EAAE,OAAO,IAAI,EAAE,CAAC;SAC1B;KACF,CAAC;AACJ,CAAC;AAED,SAAS,WAAW,CAClB,aAAqB,EACrB,IAAgC;IAOhC,MAAM,SAAS,GAAG,IAAI,EAAE,OAAO,IAAI,aAAa,CAAC;IACjD,MAAM,iBAAiB,GAAG,IAAI,eAAe,EAAE,CAAC;IAChD,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,iBAAiB,CAAC,KAAK,EAAE,EAAE,SAAS,CAAC,CAAC;IAEzE,2EAA2E;IAC3E,sEAAsE;IACtE,IAAI,QAAqB,CAAC;IAC1B,IAAI,IAAI,EAAE,MAAM,EAAE,CAAC;QACjB,IAAI,OAAO,WAAW,KAAK,WAAW,IAAI,OAAQ,WAA4C,CAAC,GAAG,KAAK,UAAU,EAAE,CAAC;YAClH,QAAQ,GAAI,WAA2E,CAAC,GAAG,CAAC;gBAC1F,IAAI,CAAC,MAAM;gBACX,iBAAiB,CAAC,MAAM;aACzB,CAAC,CAAC;QACL,CAAC;aAAM,CAAC;YACN,MAAM,eAAe,GAAG,IAAI,eAAe,EAAE,CAAC;YAC9C,MAAM,KAAK,GAAG,GAAG,EAAE,CAAC,eAAe,CAAC,KAAK,EAAE,CAAC;YAC5C,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;YAC7D,iBAAiB,CAAC,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;YAC1E,QAAQ,GAAG,eAAe,CAAC,MAAM,CAAC;QACpC,CAAC;IACH,CAAC;SAAM,CAAC;QACN,QAAQ,GAAG,iBAAiB,CAAC,MAAM,CAAC;IACtC,CAAC;IAED,OAAO;QACL,MAAM,EAAE,QAAQ;QAChB,aAAa,EAAE,iBAAiB,CAAC,MAAM;QACvC,SAAS;QACT,OAAO,EAAE,GAAG,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC;KACvC,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,YAAY,CAAC,GAAa;IACvC,MAAM,EAAE,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC;IACjD,IAAI,CAAC;QACH,IAAI,EAAE,CAAC,QAAQ,CAAC,kBAAkB,CAAC;YAAE,OAAO,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;QAC7D,OAAO,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;IAC1B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED,SAAS,kBAAkB,CAAC,MAAc;IACxC,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC1C,MAAM,IAAI,yBAAyB,CAAC,mCAAmC,CAAC,CAAC;IAC3E,CAAC;IACD,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QACpC,MAAM,IAAI,yBAAyB,CACjC,2EAA2E,CAC5E,CAAC;IACJ,CAAC;AACH,CAAC;AAED,SAAS,aAAa,CAAC,OAAe;IACpC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,OAAO,IAAI,CAAC,EAAE,CAAC;QAC/C,MAAM,IAAI,yBAAyB,CAAC,oCAAoC,CAAC,CAAC;IAC5E,CAAC;AACH,CAAC;AAED,SAAS,WAAW,CAAC,KAAc;IACjC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,KAAc,CAAC,EAAE,CAAC;QAC5E,MAAM,IAAI,yBAAyB,CACjC,wBAAwB,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CACtD,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,oBAAoB,CAAC,MAAc,EAAE,KAAY;IACxD,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC1C,MAAM,IAAI,yBAAyB,CAAC,mCAAmC,CAAC,CAAC;IAC3E,CAAC;IACD,IAAI,KAAK,KAAK,QAAQ,EAAE,CAAC;QACvB,kBAAkB,CAAC,MAAM,CAAC,CAAC;IAC7B,CAAC;AACH,CAAC;AAED,KAAK,UAAU,OAAO,CACpB,GAAmB,EACnB,IAAY,EACZ,IAAiB,EACjB,IAAgC;IAEhC,MAAM,GAAG,GAAG,GAAG,GAAG,CAAC,OAAO,GAAG,IAAI,EAAE,CAAC;IACpC,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,WAAW,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IAErF,IAAI,GAAa,CAAC;IAClB,IAAI,CAAC;QACH,GAAG,GAAG,MAAM,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE;YAC7B,GAAG,IAAI;YACP,MAAM;YACN,OAAO,EAAE,EAAE,GAAG,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC,EAAE,GAAG,CAAC,IAAI,EAAE,OAAO,IAAI,EAAE,CAAC,EAAE;SAC/E,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,EAAE,CAAC;QACV,wEAAwE;QACxE,sEAAsE;QACtE,iEAAiE;QACjE,IAAI,aAAa,CAAC,OAAO,EAAE,CAAC;YAC1B,MAAM,IAAI,sBAAsB,CAAC,SAAS,CAAC,CAAC;QAC9C,CAAC;QACD,IAAI,GAAG,YAAY,KAAK,IAAI,CAAC,GAAG,CAAC,IAAI,KAAK,YAAY,IAAI,GAAG,CAAC,IAAI,KAAK,cAAc,CAAC,EAAE,CAAC;YACvF,MAAM,IAAI,sBAAsB,CAAC,SAAS,CAAC,CAAC;QAC9C,CAAC;QACD,MAAM,IAAI,sBAAsB,CAC9B,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAChD,GAAG,CACJ,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,CAAC;IAEV,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;QACvB,MAAM,UAAU,GAAG,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,IAAI,GAAG,CAAC,CAAC;QACjE,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC,GAAG,CAAC,CAAC;QACrC,MAAM,IAAI,wBAAwB,CAChC,gCAAgC,EAChC,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,EAAE,CACvG,CAAC;IACJ,CAAC;IAED,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;QACvB,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC,GAAG,CAAC,CAAC;QACrC,MAAM,GAAG,GAAG,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,IAAI,OAAO,IAAI,IAAI;YAC7D,CAAC,CAAC,MAAM,CAAE,IAA2B,CAAC,KAAK,CAAC;YAC5C,CAAC,CAAC,gBAAgB,IAAI,EAAE,CAAC;QAC3B,MAAM,IAAI,uBAAuB,CAAC,GAAG,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7D,CAAC;IAED,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACZ,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC,GAAG,CAAC,CAAC;QACrC,MAAM,GAAG,GAAG,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,IAAI,OAAO,IAAI,IAAI;YAC7D,CAAC,CAAC,MAAM,CAAE,IAA2B,CAAC,KAAK,CAAC;YAC5C,CAAC,CAAC,8BAA8B,GAAG,CAAC,MAAM,EAAE,CAAC;QAC/C,MAAM,IAAI,qBAAqB,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;IAC/E,CAAC;IAED,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;IAC5B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,gCAAgC,CACxC,iCAAiC,EACjC,EAAE,KAAK,EAAE,GAAG,EAAE,CACf,CAAC;IACJ,CAAC;IACD,OAAO,MAAW,CAAC;AACrB,CAAC;AA2ED,MAAM,UAAU,sBAAsB,CAAC,MAAqB;IAC1D,MAAM,GAAG,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC;IAEpC,OAAO;QACL,OAAO,EAAE,GAAG,CAAC,OAAO;QAEpB,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,IAAI,GAAG,EAAE;YAC9B,4EAA4E;YAC5E,4EAA4E;YAC5E,+DAA+D;YAC/D,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,QAAQ,CAAC;YACrC,WAAW,CAAC,KAAK,CAAC,CAAC;YACnB,oBAAoB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;YACpC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,MAAM,CAAC;YACjC,IAAI,IAAI,KAAK,MAAM,IAAI,IAAI,KAAK,UAAU,IAAI,IAAI,KAAK,UAAU,EAAE,CAAC;gBAClE,MAAM,IAAI,yBAAyB,CAAC,+CAA+C,CAAC,CAAC;YACvF,CAAC;YACD,MAAM,IAAI,GAAG,iBAAiB,kBAAkB,CAAC,MAAM,CAAC,SAAS,IAAI,EAAE,CAAC;YACxE,MAAM,IAAI,GAAG,MAAM,OAAO,CAAgB,GAAG,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,IAAI,CAAC,CAAC;YAC9E,qBAAqB,CAAC,IAAI,CAAC,CAAC;YAC5B,OAAO,IAAI,CAAC;QACd,CAAC;QAED,KAAK,CAAC,gBAAgB,CAAC,MAAM,EAAE,IAAI;YACjC,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC;YACxE,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACnB,MAAM,IAAI,gCAAgC,CACxC,4CAA4C,EAC5C,EAAE,QAAQ,EAAE,IAAI,EAAE,CACnB,CAAC;YACJ,CAAC;YACD,OAAO,IAAI,CAAC,QAAQ,CAAC;QACvB,CAAC;QAED,KAAK,CAAC,gBAAgB,CAAC,MAAM,EAAE,IAAI;YACjC,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC;YACxE,yEAAyE;YACzE,4DAA4D;YAC5D,OAAO,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC;QAC/B,CAAC;QAED,KAAK,CAAC,YAAY,CAAC,OAAO,EAAE,IAAI;YAC9B,aAAa,CAAC,OAAO,CAAC,CAAC;YACvB,MAAM,IAAI,GAAG,gBAAgB,OAAO,EAAE,CAAC;YACvC,MAAM,IAAI,GAAG,MAAM,OAAO,CAAoB,GAAG,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,IAAI,CAAC,CAAC;YAClF,IAAI,IAAI,CAAC,KAAK,KAAK,MAAM,IAAI,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;gBAC5D,MAAM,IAAI,gCAAgC,CACxC,6CAA6C,EAC7C,EAAE,QAAQ,EAAE,IAAI,EAAE,CACnB,CAAC;YACJ,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;QAED,KAAK,CAAC,YAAY,CAAC,KAAK,EAAE,IAAI,GAAG,EAAE;YACjC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACzD,MAAM,IAAI,yBAAyB,CAAC,iDAAiD,CAAC,CAAC;YACzF,CAAC;YACD,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,EAAE,CAAC,EAAE,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YACxD,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI;gBAAE,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;YAChE,MAAM,IAAI,GAAG,eAAe,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC;YAChD,MAAM,GAAG,GAAG,MAAM,OAAO,CAAiB,GAAG,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,IAAI,CAAC,CAAC;YAC9E,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;gBACxC,MAAM,IAAI,gCAAgC,CACxC,uCAAuC,EACvC,EAAE,QAAQ,EAAE,GAAG,EAAE,CAClB,CAAC;YACJ,CAAC;YACD,OAAO,GAAG,CAAC;QACb,CAAC;QAED,KAAK,CAAC,eAAe,CAAC,MAAM,EAAE,IAAI,GAAG,EAAE;YACrC,kBAAkB,CAAC,MAAM,CAAC,CAAC;YAC3B,MAAM,MAAM,GAAG,IAAI,eAAe,EAAE,CAAC;YACrC,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI;gBAAE,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;YAChE,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI;gBAAE,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;YACnE,MAAM,EAAE,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC;YAC7B,MAAM,IAAI,GAAG,cAAc,kBAAkB,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;YACrF,MAAM,GAAG,GAAG,MAAM,OAAO,CAAuB,GAAG,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,IAAI,CAAC,CAAC;YACpF,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC;gBAC7C,MAAM,IAAI,gCAAgC,CACxC,6CAA6C,EAC7C,EAAE,QAAQ,EAAE,GAAG,EAAE,CAClB,CAAC;YACJ,CAAC;YACD,OAAO,GAAG,CAAC;QACb,CAAC;QAED,KAAK,CAAC,kBAAkB,CAAC,MAAM,EAAE,IAAI;YACnC,kBAAkB,CAAC,MAAM,CAAC,CAAC;YAC3B,MAAM,IAAI,GAAG,uBAAuB,kBAAkB,CAAC,MAAM,CAAC,EAAE,CAAC;YACjE,MAAM,GAAG,GAAG,MAAM,OAAO,CAAkB,GAAG,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,IAAI,CAAC,CAAC;YAC/E,IACE,OAAO,GAAG,KAAK,QAAQ;gBACvB,GAAG,KAAK,IAAI;gBACZ,OAAQ,GAAuB,CAAC,KAAK,KAAK,QAAQ,EAClD,CAAC;gBACD,MAAM,IAAI,gCAAgC,CACxC,4CAA4C,EAC5C,EAAE,QAAQ,EAAE,GAAG,EAAE,CAClB,CAAC;YACJ,CAAC;YACD,OAAO,GAAG,CAAC;QACb,CAAC;QAED,KAAK,CAAC,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI;YAC3C,WAAW,CAAC,KAAK,CAAC,CAAC;YACnB,oBAAoB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;YACpC,MAAM,IAAI,GAAG,sBAAsB,KAAK,IAAI,kBAAkB,CAAC,MAAM,CAAC,EAAE,CAAC;YACzE,MAAM,GAAG,GAAG,MAAM,OAAO,CAAU,GAAG,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,IAAI,CAAC,CAAC;YACvE,MAAM,GAAG,GAAG,GAAyC,CAAC;YACtD,MAAM,CAAC,GAAG,GAAG,EAAE,UAAiD,CAAC;YACjE,IAAI,CAAC,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ,EAAE,CAAC;gBAChC,MAAM,IAAI,gCAAgC,CACxC,8CAA8C,EAC9C,EAAE,QAAQ,EAAE,GAAG,EAAE,CAClB,CAAC;YACJ,CAAC;YACD,IAAI,OAAO,CAAC,CAAC,MAAM,KAAK,QAAQ,IAAI,OAAO,CAAC,CAAC,eAAe,KAAK,QAAQ,EAAE,CAAC;gBAC1E,MAAM,IAAI,gCAAgC,CACxC,mEAAmE,EACnE,EAAE,QAAQ,EAAE,GAAG,EAAE,CAClB,CAAC;YACJ,CAAC;YACD,OAAO,CAA8B,CAAC;QACxC,CAAC;QAED,KAAK,CAAC,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI;YACrC,WAAW,CAAC,KAAK,CAAC,CAAC;YACnB,oBAAoB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;YACpC,MAAM,IAAI,GAAG,gBAAgB,KAAK,IAAI,kBAAkB,CAAC,MAAM,CAAC,EAAE,CAAC;YACnE,MAAM,GAAG,GAAG,MAAM,OAAO,CAAU,GAAG,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,IAAI,CAAC,CAAC;YACvE,MAAM,GAAG,GAAG,GAAmC,CAAC;YAChD,MAAM,KAAK,GAAG,GAAG,EAAE,KAA4C,CAAC;YAChE,IACE,CAAC,KAAK;gBACN,OAAO,KAAK,KAAK,QAAQ;gBACzB,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC;gBAC1B,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC;gBAC9B,OAAO,KAAK,CAAC,eAAe,KAAK,QAAQ,EACzC,CAAC;gBACD,MAAM,IAAI,gCAAgC,CACxC,mCAAmC,EACnC,EAAE,QAAQ,EAAE,GAAG,EAAE,CAClB,CAAC;YACJ,CAAC;YACD,OAAO,KAA6B,CAAC;QACvC,CAAC;QAED,KAAK,CAAC,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI;YACtC,WAAW,CAAC,KAAK,CAAC,CAAC;YACnB,oBAAoB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;YACpC,MAAM,IAAI,GAAG,gBAAgB,KAAK,IAAI,kBAAkB,CAAC,MAAM,CAAC,EAAE,CAAC;YACnE,MAAM,GAAG,GAAG,MAAM,OAAO,CAAe,GAAG,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,IAAI,CAAC,CAAC;YAC5E,2EAA2E;YAC3E,mDAAmD;YACnD,OAAO,GAAG,EAAE,MAAM,IAAI,IAAI,CAAC;QAC7B,CAAC;QAED,KAAK,CAAC,cAAc,CAAC,KAAK,EAAE,IAAI;YAC9B,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;gBACxC,MAAM,IAAI,yBAAyB,CAAC,uCAAuC,CAAC,CAAC;YAC/E,CAAC;YACD,IAAI,CAAC,KAAK,CAAC,WAAW,IAAI,CAAC,KAAK,CAAC,WAAW,IAAI,CAAC,KAAK,CAAC,SAAS,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;gBACnF,MAAM,IAAI,yBAAyB,CACjC,2EAA2E,CAC5E,CAAC;YACJ,CAAC;YACD,IAAI,KAAK,CAAC,MAAM,KAAK,WAAW,IAAI,KAAK,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;gBAC9D,MAAM,IAAI,yBAAyB,CAAC,wCAAwC,CAAC,CAAC;YAChF,CAAC;YACD,MAAM,GAAG,GAAG,MAAM,OAAO,CACvB,GAAG,EACH,eAAe,EACf;gBACE,MAAM,EAAE,MAAM;gBACd,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC;gBAC3B,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;aAChD,EACD,IAAI,CACL,CAAC;YACF,IAAI,GAAG,EAAE,OAAO,KAAK,IAAI,EAAE,CAAC;gBAC1B,MAAM,IAAI,gCAAgC,CACxC,mDAAmD,EACnD,EAAE,QAAQ,EAAE,GAAG,EAAE,CAClB,CAAC;YACJ,CAAC;YACD,OAAO,GAAG,CAAC;QACb,CAAC;KACF,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,SAAS,qBAAqB,CAAC,IAAa;IAC1C,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QACtC,MAAM,IAAI,gCAAgC,CAAC,iCAAiC,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;IACpG,CAAC;IACD,MAAM,CAAC,GAAG,IAA+B,CAAC;IAC1C,IAAI,OAAO,CAAC,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;QAClC,MAAM,IAAI,gCAAgC,CAAC,gCAAgC,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;IACnG,CAAC;IACD,IAAI,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC/B,MAAM,IAAI,gCAAgC,CAAC,6BAA6B,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;IAChG,CAAC;IACD,IAAI,OAAO,CAAC,CAAC,QAAQ,KAAK,QAAQ,IAAI,CAAC,CAAC,QAAQ,KAAK,IAAI,EAAE,CAAC;QAC1D,MAAM,IAAI,gCAAgC,CAAC,uCAAuC,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;IAC1G,CAAC;AACH,CAAC;AAED,sEAAsE;AACtE,mEAAmE;AACnE,OAAO,EAAE,eAAe,EAAE,CAAC"}
|