@tangle-network/blueprint-ui 0.1.2 → 0.3.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.
@@ -0,0 +1,411 @@
1
+ // EIP-1193 provider implementation that proxies wallet calls to the parent
2
+ // dapp via window.postMessage. The iframe doesn't talk to a wallet directly
3
+ // — it inherits the parent's connected account + chain, and forwards signing
4
+ // requests through the existing tangle.app.* protocol.
5
+ //
6
+ // This is the lowest layer of the parent-bridge stack. Wagmi sees this as a
7
+ // regular Ethereum provider and routes `eth_accounts`, `eth_chainId`,
8
+ // `personal_sign`, `eth_sendTransaction`, `wallet_switchEthereumChain`, etc.
9
+ // through it.
10
+
11
+ import type { Address, Hex } from 'viem';
12
+
13
+ import {
14
+ makeCorrelationId,
15
+ NO_WALLET_ADDRESS,
16
+ TANGLE_IFRAME_PROTOCOL_VERSION,
17
+ type ParentMessage,
18
+ } from './parentBridgeProtocol';
19
+
20
+ type EventName = 'accountsChanged' | 'chainChanged' | 'connect' | 'disconnect' | 'message';
21
+ type Listener = (...args: unknown[]) => void;
22
+
23
+ type PendingRequest<T> = {
24
+ resolve: (value: T) => void;
25
+ reject: (reason: Error) => void;
26
+ expectedKind: ParentMessage['kind'];
27
+ };
28
+
29
+ export type ParentBridgeOptions = {
30
+ /**
31
+ * Origin of the parent dapp that hosts this iframe. The provider posts to
32
+ * `window.parent` with this exact origin and rejects inbound messages from
33
+ * any other origin. Pass `'*'` only in development; production must pin to
34
+ * the real parent (`https://cloud.tangle.tools` or its develop equivalent).
35
+ */
36
+ parentOrigin: string;
37
+ /**
38
+ * Stable identifier for this iframe app. The parent includes this in the
39
+ * handshake ack so dev tooling can correlate logs across the two windows.
40
+ */
41
+ appId: string;
42
+ /**
43
+ * Optional ms timeout for each bridged request. Defaults to 60 seconds —
44
+ * long enough for a user to read + approve a signing prompt in the parent.
45
+ */
46
+ requestTimeoutMs?: number;
47
+ };
48
+
49
+ const DEFAULT_REQUEST_TIMEOUT_MS = 60_000;
50
+
51
+ /**
52
+ * Detect iframe execution context. When this returns `false` the bridge
53
+ * connector should not be installed and the host app should fall back to its
54
+ * normal wallet config (ConnectKit + injected/walletConnect).
55
+ *
56
+ * `window.parent !== window` is the most reliable signal that works across
57
+ * sandbox-iframe contexts where direct property access to parent throws.
58
+ */
59
+ export function isRunningInIframe(): boolean {
60
+ if (typeof window === 'undefined') return false;
61
+ try {
62
+ return window.parent !== undefined && window.parent !== window;
63
+ } catch {
64
+ // Cross-origin read of `window.parent` shouldn't throw, but be defensive.
65
+ return true;
66
+ }
67
+ }
68
+
69
+ /**
70
+ * EIP-1193 provider backed by the Tangle Cloud iframe protocol. One instance
71
+ * lives per iframe app; the wagmi connector owns the singleton.
72
+ */
73
+ export class ParentBridgeProvider {
74
+ private listeners = new Map<EventName, Set<Listener>>();
75
+ private pending = new Map<string, PendingRequest<unknown>>();
76
+ private cachedAccount: Address | null = null;
77
+ private cachedChainId: number | null = null;
78
+ private handshakeAcked = false;
79
+ private handshakeWaiters: Array<() => void> = [];
80
+ private installed = false;
81
+
82
+ constructor(private readonly options: ParentBridgeOptions) {}
83
+
84
+ /**
85
+ * Wire up the global message listener and send the initial handshake.
86
+ * Idempotent — safe to call repeatedly during reconnect attempts.
87
+ */
88
+ install(): void {
89
+ if (this.installed || typeof window === 'undefined') return;
90
+ this.installed = true;
91
+ window.addEventListener('message', this.handleParentMessage);
92
+ this.postToParent({
93
+ kind: 'tangle.app.handshake',
94
+ appId: this.options.appId,
95
+ version: TANGLE_IFRAME_PROTOCOL_VERSION,
96
+ });
97
+ }
98
+
99
+ uninstall(): void {
100
+ if (!this.installed || typeof window === 'undefined') return;
101
+ this.installed = false;
102
+ window.removeEventListener('message', this.handleParentMessage);
103
+ // Reject every pending request so callers don't hang forever.
104
+ for (const [, pending] of this.pending) {
105
+ pending.reject(new Error('Parent bridge uninstalled'));
106
+ }
107
+ this.pending.clear();
108
+ }
109
+
110
+ // ── EIP-1193 surface ────────────────────────────────────────────────────
111
+
112
+ async request(req: { method: string; params?: unknown[] }): Promise<unknown> {
113
+ const method = req.method;
114
+ const params = (req.params ?? []) as unknown[];
115
+ switch (method) {
116
+ case 'eth_chainId': {
117
+ await this.ensureBootstrapped();
118
+ return this.cachedChainId !== null ? `0x${this.cachedChainId.toString(16)}` : '0x0';
119
+ }
120
+ case 'eth_accounts':
121
+ case 'eth_requestAccounts': {
122
+ await this.ensureBootstrapped();
123
+ return this.cachedAccount !== null ? [this.cachedAccount] : [];
124
+ }
125
+ case 'personal_sign': {
126
+ const [message, _signer] = params as [string, Address];
127
+ return this.requestSignMessage(message);
128
+ }
129
+ case 'eth_signTypedData_v4': {
130
+ // The current protocol doesn't carry typed-data — surface a clear
131
+ // error rather than silently producing a personal_sign. Publishers
132
+ // that need typed-data signing should upgrade the protocol.
133
+ throw bridgeError(
134
+ 4200,
135
+ 'eth_signTypedData_v4 is not supported by the parent-bridge protocol yet.',
136
+ );
137
+ }
138
+ case 'eth_sendTransaction': {
139
+ const [tx] = params as [
140
+ { to?: Address; data?: Hex; value?: Hex | string; chainId?: Hex | number },
141
+ ];
142
+ if (!tx?.to || !tx.data) {
143
+ throw bridgeError(-32602, 'eth_sendTransaction requires `to` and `data`.');
144
+ }
145
+ return this.requestSignTransaction(tx);
146
+ }
147
+ case 'wallet_switchEthereumChain': {
148
+ const [{ chainId }] = params as [{ chainId: Hex }];
149
+ const numeric = Number.parseInt(chainId, 16);
150
+ if (!Number.isFinite(numeric) || numeric <= 0) {
151
+ throw bridgeError(-32602, `Invalid chainId: ${chainId}`);
152
+ }
153
+ await this.requestSwitchChain(numeric);
154
+ return null;
155
+ }
156
+ case 'wallet_addEthereumChain': {
157
+ // The parent owns the chain registry; iframes can't add chains the
158
+ // dapp doesn't already know about.
159
+ throw bridgeError(
160
+ 4200,
161
+ 'wallet_addEthereumChain is not supported through the parent bridge.',
162
+ );
163
+ }
164
+ default:
165
+ throw bridgeError(4200, `Method ${method} not supported by parent bridge.`);
166
+ }
167
+ }
168
+
169
+ on(event: EventName, listener: Listener): void {
170
+ const set = this.listeners.get(event) ?? new Set();
171
+ set.add(listener);
172
+ this.listeners.set(event, set);
173
+ }
174
+
175
+ removeListener(event: EventName, listener: Listener): void {
176
+ this.listeners.get(event)?.delete(listener);
177
+ }
178
+
179
+ // ── Internal: dispatch + book-keeping ───────────────────────────────────
180
+
181
+ private postToParent(message: object): void {
182
+ if (typeof window === 'undefined') return;
183
+ try {
184
+ window.parent.postMessage(message, this.options.parentOrigin);
185
+ } catch {
186
+ // Cross-origin / sandboxed; parent.postMessage shouldn't actually throw
187
+ // but be defensive against future browser changes.
188
+ }
189
+ }
190
+
191
+ private handleParentMessage = (event: MessageEvent): void => {
192
+ // Origin gate first; never parse untrusted payloads.
193
+ if (event.origin !== this.options.parentOrigin) return;
194
+ const data = event.data;
195
+ if (typeof data !== 'object' || data === null) return;
196
+ const message = data as ParentMessage;
197
+ switch (message.kind) {
198
+ case 'tangle.app.handshakeAck':
199
+ this.handshakeAcked = true;
200
+ for (const resolve of this.handshakeWaiters) resolve();
201
+ this.handshakeWaiters = [];
202
+ // After ack, ask for the current account so cached state reflects
203
+ // reality before any consumer queries. Fire-and-forget — explicit
204
+ // calls (`eth_accounts`, etc.) await their own request.
205
+ this.sendReadAccount().catch(() => {
206
+ // The first read commonly races with bridge teardown in tests
207
+ // and isn't user-facing; swallow rather than producing unhandled
208
+ // rejections. Subsequent `eth_accounts` calls retry on demand.
209
+ });
210
+ return;
211
+ case 'tangle.app.readAccountResult':
212
+ this.resolvePending(message);
213
+ if (message.ok) {
214
+ this.updateAccount(
215
+ message.data.account === NO_WALLET_ADDRESS
216
+ ? null
217
+ : message.data.account,
218
+ );
219
+ this.updateChainId(message.data.chainId);
220
+ }
221
+ return;
222
+ case 'tangle.app.switchChainResult':
223
+ this.resolvePending(message);
224
+ if (message.ok) this.updateChainId(message.data.chainId);
225
+ return;
226
+ case 'tangle.app.signMessageResult':
227
+ case 'tangle.app.signTransactionResult':
228
+ this.resolvePending(message);
229
+ return;
230
+ case 'tangle.app.accountChanged':
231
+ this.updateAccount(message.account);
232
+ return;
233
+ case 'tangle.app.chainChanged':
234
+ this.updateChainId(message.chainId);
235
+ return;
236
+ }
237
+ };
238
+
239
+ private sendReadAccount(): Promise<{ account: Address; chainId: number }> {
240
+ return this.dispatch({
241
+ kind: 'tangle.app.readAccount',
242
+ expectedKind: 'tangle.app.readAccountResult',
243
+ }) as Promise<{ account: Address; chainId: number }>;
244
+ }
245
+
246
+ private requestSignMessage(message: string): Promise<Hex> {
247
+ const chainId = this.cachedChainId ?? 1;
248
+ return this.dispatch({
249
+ kind: 'tangle.app.signMessage',
250
+ expectedKind: 'tangle.app.signMessageResult',
251
+ payload: { chainId, message },
252
+ }).then((data) => (data as { signature: Hex }).signature);
253
+ }
254
+
255
+ private requestSignTransaction(tx: {
256
+ to?: Address;
257
+ data?: Hex;
258
+ value?: Hex | string;
259
+ }): Promise<Hex> {
260
+ const chainId = this.cachedChainId ?? 1;
261
+ const value =
262
+ typeof tx.value === 'string' && tx.value.startsWith('0x')
263
+ ? BigInt(tx.value).toString(10)
264
+ : typeof tx.value === 'string'
265
+ ? tx.value
266
+ : undefined;
267
+ return this.dispatch({
268
+ kind: 'tangle.app.signTransaction',
269
+ expectedKind: 'tangle.app.signTransactionResult',
270
+ payload: {
271
+ chainId,
272
+ to: tx.to as Address,
273
+ data: tx.data as Hex,
274
+ ...(value !== undefined ? { value } : {}),
275
+ },
276
+ }).then((data) => (data as { txHash: Hex }).txHash);
277
+ }
278
+
279
+ private requestSwitchChain(chainId: number): Promise<number> {
280
+ return this.dispatch({
281
+ kind: 'tangle.app.switchChain',
282
+ expectedKind: 'tangle.app.switchChainResult',
283
+ payload: { chainId },
284
+ }).then((data) => (data as { chainId: number }).chainId);
285
+ }
286
+
287
+ private async dispatch(req: {
288
+ kind: 'tangle.app.readAccount' | 'tangle.app.switchChain' | 'tangle.app.signMessage' | 'tangle.app.signTransaction';
289
+ expectedKind: ParentMessage['kind'];
290
+ payload?: Record<string, unknown>;
291
+ }): Promise<unknown> {
292
+ await this.ensureBootstrapped();
293
+ const correlationId = makeCorrelationId(req.kind);
294
+ const timeout = this.options.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;
295
+ return new Promise<unknown>((resolve, reject) => {
296
+ const timer = window.setTimeout(() => {
297
+ this.pending.delete(correlationId);
298
+ reject(bridgeError(4900, `Parent did not respond to ${req.kind} within ${timeout}ms`));
299
+ }, timeout);
300
+ this.pending.set(correlationId, {
301
+ resolve: (v) => {
302
+ window.clearTimeout(timer);
303
+ resolve(v);
304
+ },
305
+ reject: (e) => {
306
+ window.clearTimeout(timer);
307
+ reject(e);
308
+ },
309
+ expectedKind: req.expectedKind,
310
+ });
311
+ this.postToParent({
312
+ kind: req.kind,
313
+ correlationId,
314
+ ...(req.payload ?? {}),
315
+ });
316
+ });
317
+ }
318
+
319
+ private resolvePending(message: Extract<ParentMessage, { correlationId: string }>): void {
320
+ const entry = this.pending.get(message.correlationId);
321
+ if (!entry) return;
322
+ this.pending.delete(message.correlationId);
323
+ if (entry.expectedKind !== message.kind) {
324
+ entry.reject(
325
+ bridgeError(
326
+ -32000,
327
+ `Parent replied with ${message.kind} but ${entry.expectedKind} was expected`,
328
+ ),
329
+ );
330
+ return;
331
+ }
332
+ if (message.ok) {
333
+ entry.resolve(message.data);
334
+ } else {
335
+ entry.reject(bridgeError(4001, message.error));
336
+ }
337
+ }
338
+
339
+ private async ensureBootstrapped(): Promise<void> {
340
+ if (this.handshakeAcked) return;
341
+ this.install();
342
+ await new Promise<void>((resolve) => {
343
+ this.handshakeWaiters.push(resolve);
344
+ // Re-send handshake every 500ms while we wait — covers a parent that
345
+ // mounted after the iframe and missed the initial post.
346
+ const retry = window.setInterval(() => {
347
+ if (this.handshakeAcked) {
348
+ window.clearInterval(retry);
349
+ return;
350
+ }
351
+ this.postToParent({
352
+ kind: 'tangle.app.handshake',
353
+ appId: this.options.appId,
354
+ version: TANGLE_IFRAME_PROTOCOL_VERSION,
355
+ });
356
+ }, 500);
357
+ // Safety stop — handshake won't be re-attempted indefinitely.
358
+ window.setTimeout(() => window.clearInterval(retry), 10_000);
359
+ });
360
+ }
361
+
362
+ private updateAccount(next: Address | null): void {
363
+ if (this.cachedAccount === next) return;
364
+ const prev = this.cachedAccount;
365
+ this.cachedAccount = next;
366
+ if (next === null && prev !== null) {
367
+ this.emit('disconnect');
368
+ this.emit('accountsChanged', []);
369
+ } else if (next !== null) {
370
+ this.emit('accountsChanged', [next]);
371
+ if (prev === null) {
372
+ this.emit('connect', { chainId: this.cachedChainId ?? 0 });
373
+ }
374
+ }
375
+ }
376
+
377
+ private updateChainId(next: number): void {
378
+ if (this.cachedChainId === next) return;
379
+ this.cachedChainId = next;
380
+ this.emit('chainChanged', `0x${next.toString(16)}`);
381
+ }
382
+
383
+ private emit(event: EventName, ...args: unknown[]): void {
384
+ const set = this.listeners.get(event);
385
+ if (!set) return;
386
+ for (const listener of [...set]) {
387
+ try {
388
+ listener(...args);
389
+ } catch {
390
+ // Listener bugs shouldn't break the bridge.
391
+ }
392
+ }
393
+ }
394
+
395
+ // ── Test seams ──────────────────────────────────────────────────────────
396
+
397
+ /** Visible for tests + the connector's `getAccounts()` shortcut. */
398
+ getCachedAccount(): Address | null {
399
+ return this.cachedAccount;
400
+ }
401
+ /** Visible for tests + the connector's `getChainId()` shortcut. */
402
+ getCachedChainId(): number | null {
403
+ return this.cachedChainId;
404
+ }
405
+ }
406
+
407
+ function bridgeError(code: number, message: string): Error {
408
+ const err = new Error(message) as Error & { code?: number };
409
+ err.code = code;
410
+ return err;
411
+ }
package/tsconfig.json CHANGED
@@ -17,5 +17,5 @@
17
17
  "~/*": ["./src/*"]
18
18
  }
19
19
  },
20
- "include": ["src"]
20
+ "include": ["src", "vitest.config.ts"]
21
21
  }
@@ -1,39 +0,0 @@
1
- import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import * as React from 'react';
3
- import * as class_variance_authority_types from 'class-variance-authority/types';
4
- import { VariantProps } from 'class-variance-authority';
5
-
6
- declare const buttonVariants: (props?: ({
7
- variant?: "default" | "link" | "success" | "secondary" | "destructive" | "outline" | "ghost" | null | undefined;
8
- size?: "default" | "sm" | "lg" | "icon" | "icon-sm" | null | undefined;
9
- } & class_variance_authority_types.ClassProp) | undefined) => string;
10
- declare function Button({ className, variant, size, asChild, ...props }: React.ComponentProps<'button'> & VariantProps<typeof buttonVariants> & {
11
- asChild?: boolean;
12
- }): react_jsx_runtime.JSX.Element;
13
-
14
- type Action = {
15
- label: string;
16
- href?: string;
17
- onClick?: () => void;
18
- variant?: React.ComponentProps<typeof Button>['variant'];
19
- disabled?: boolean;
20
- };
21
- type BlueprintHostHeroProps = {
22
- title: string;
23
- tagline?: string;
24
- description?: string;
25
- badges?: string[];
26
- actions?: Action[];
27
- children?: React.ReactNode;
28
- className?: string;
29
- };
30
- declare function BlueprintHostHero({ title, tagline, description, badges, actions, children, className, }: BlueprintHostHeroProps): react_jsx_runtime.JSX.Element;
31
-
32
- type BlueprintHostPanelProps = {
33
- title: string;
34
- children: React.ReactNode;
35
- className?: string;
36
- };
37
- declare function BlueprintHostPanel({ title, children, className, }: BlueprintHostPanelProps): react_jsx_runtime.JSX.Element;
38
-
39
- export { BlueprintHostHero as B, type BlueprintHostHeroProps as a, BlueprintHostPanel as b, type BlueprintHostPanelProps as c, Button as d, buttonVariants as e };
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/utils/resolveOperatorRpc.ts","../src/contracts/chains.ts","../src/utils/env.ts","../src/stores/persistedAtom.ts","../src/stores/txHistory.ts","../src/stores/infra.ts","../src/stores/theme.ts","../src/contracts/abi.ts","../src/contracts/publicClient.ts","../src/contracts/generic-encoder.ts","../src/hooks/useJobForm.ts","../src/hooks/useQuotes.ts","../src/hooks/useJobPrice.ts","../src/hooks/useSubmitJob.ts","../src/hooks/useThemeValue.ts"],"sourcesContent":["/** Rewrite operator RPC hostname for browser reachability. */\nexport function resolveOperatorRpc(raw: string): string {\n if (typeof window === 'undefined') return raw;\n const withProto = raw.includes('://') ? raw : `http://${raw}`;\n try {\n const url = new URL(withProto);\n const pageHost = window.location.hostname;\n const isNonRoutable =\n url.hostname.endsWith('.local') ||\n !url.hostname.includes('.') ||\n url.hostname === '127.0.0.1' ||\n url.hostname === 'localhost';\n if (isNonRoutable && pageHost !== url.hostname) {\n url.hostname = pageHost;\n }\n return url.toString().replace(/\\/$/, '');\n } catch {\n return withProto;\n }\n}\n","import { defineChain } from 'viem';\nimport { mainnet } from 'viem/chains';\nimport type { Address, Chain } from 'viem';\nimport { getEnvVar, isDevEnv } from '../utils/env';\n\n/**\n * Resolve RPC URL for the current environment.\n * Handles local dev (hostname swap), Vite dev proxy, and remote access.\n */\nexport function resolveRpcUrl(envUrl?: string): string {\n const configured = envUrl ?? getEnvVar('VITE_RPC_URL') ?? 'http://localhost:8545';\n if (typeof window === 'undefined') return configured;\n try {\n const rpc = new URL(configured);\n const isLocalRpc = rpc.hostname === '127.0.0.1' || rpc.hostname === 'localhost';\n const pageHost = window.location.hostname;\n const isLocalPage = pageHost === '127.0.0.1' || pageHost === 'localhost';\n // Dev-mode proxy for LAN access to local RPC\n if (isLocalRpc && !isLocalPage && isDevEnv()) {\n return `${window.location.origin}/rpc-proxy`;\n }\n // Non-dev LAN access: swap hostname\n if (isLocalRpc && !isLocalPage) {\n rpc.hostname = pageHost;\n return rpc.toString().replace(/\\/$/, '');\n }\n } catch {\n // malformed\n }\n return configured;\n}\n\nexport const rpcUrl = resolveRpcUrl();\n\nexport interface LocalChainOptions {\n chainId?: number;\n rpcUrl?: string;\n}\n\nexport function createTangleLocalChain(options: LocalChainOptions = {}) {\n const chainId = options.chainId ?? Number(getEnvVar('VITE_CHAIN_ID') ?? 31337);\n const localRpcUrl = resolveRpcUrl(options.rpcUrl);\n\n return defineChain({\n id: chainId,\n name: 'Tangle Local',\n nativeCurrency: { name: 'Ether', symbol: 'ETH', decimals: 18 },\n rpcUrls: { default: { http: [localRpcUrl] } },\n blockExplorers: { default: { name: 'Explorer', url: '' } },\n contracts: { multicall3: { address: '0xcA11bde05977b3631167028862bE2a173976CA11' } },\n });\n}\n\nexport const tangleLocal = createTangleLocalChain();\n\nexport const tangleTestnet = defineChain({\n id: 3799,\n name: 'Tangle Testnet',\n nativeCurrency: { name: 'Tangle', symbol: 'tTNT', decimals: 18 },\n rpcUrls: {\n default: {\n http: ['https://testnet-rpc.tangle.tools'],\n webSocket: ['wss://testnet-rpc.tangle.tools'],\n },\n },\n blockExplorers: { default: { name: 'Tangle Explorer', url: 'https://testnet-explorer.tangle.tools' } },\n contracts: { multicall3: { address: '0xcA11bde05977b3631167028862bE2a173976CA11' } },\n});\n\nexport const tangleMainnet = defineChain({\n id: 5845,\n name: 'Tangle',\n nativeCurrency: { name: 'Tangle', symbol: 'TNT', decimals: 18 },\n rpcUrls: {\n default: {\n http: ['https://rpc.tangle.tools'],\n webSocket: ['wss://rpc.tangle.tools'],\n },\n },\n blockExplorers: { default: { name: 'Tangle Explorer', url: 'https://explorer.tangle.tools' } },\n contracts: { multicall3: { address: '0xcA11bde05977b3631167028862bE2a173976CA11' } },\n});\n\n/** Minimum required contract addresses for Tangle core hooks. */\nexport interface CoreAddresses {\n jobs: Address;\n services: Address;\n [key: string]: Address;\n}\n\nexport interface NetworkConfig<T extends CoreAddresses = CoreAddresses> {\n chain: Chain;\n rpcUrl: string;\n label: string;\n shortLabel: string;\n addresses: T;\n}\n\nlet _networks: Record<number, NetworkConfig<any>> = {};\n\n/** Register networks with app-specific address shapes at startup. */\nexport function configureNetworks<T extends CoreAddresses>(\n nets: Record<number, NetworkConfig<T>>,\n) {\n _networks = nets;\n}\n\nexport function getNetworks<T extends CoreAddresses = CoreAddresses>(): Record<number, NetworkConfig<T>> {\n return _networks as Record<number, NetworkConfig<T>>;\n}\n\nexport { mainnet };\nexport const allTangleChains = [tangleLocal, tangleTestnet, tangleMainnet] as const;\n","type ImportMetaEnvLike = {\n DEV?: boolean;\n VITE_RPC_URL?: string;\n VITE_CHAIN_ID?: string;\n VITE_BLUEPRINT_ID?: string;\n VITE_SERVICE_ID?: string;\n VITE_SERVICE_IDS?: string;\n VITE_OPERATOR_API_URL?: string;\n};\n\nfunction readImportMetaEnv(): ImportMetaEnvLike {\n return ((import.meta as ImportMeta & { env?: ImportMetaEnvLike }).env ?? {});\n}\n\nexport function getEnvVar(key: keyof ImportMetaEnvLike): string | undefined {\n const value = readImportMetaEnv()[key];\n return typeof value === 'string' ? value : undefined;\n}\n\nexport function isDevEnv(): boolean {\n return Boolean(readImportMetaEnv().DEV);\n}\n","import { atom, type WritableAtom } from 'nanostores';\n\n/**\n * JSON serializer that handles bigint values (converts to `{__bigint: \"123\"}`).\n * Needed because TrackedTx.blockNumber and gasUsed are bigints.\n */\nexport function serializeWithBigInt(value: unknown): string {\n return JSON.stringify(value, (_key, v) =>\n typeof v === 'bigint' ? { __bigint: v.toString() } : v,\n );\n}\n\n/** Deserialize JSON produced by `serializeWithBigInt`. */\nexport function deserializeWithBigInt<T>(raw: string): T {\n return JSON.parse(raw, (_key, v) => {\n if (v && typeof v === 'object' && '__bigint' in v && typeof v.__bigint === 'string') {\n return BigInt(v.__bigint);\n }\n return v;\n }) as T;\n}\n\ninterface PersistedAtomOpts<T> {\n /** localStorage key */\n key: string;\n /** Default value when nothing is stored */\n initial: T;\n /** Custom serializer (defaults to JSON.stringify) */\n serialize?: (value: T) => string;\n /** Custom deserializer (defaults to JSON.parse) */\n deserialize?: (raw: string) => T;\n}\n\n/**\n * A nanostores atom backed by localStorage.\n * Restores on init, persists on every `.set()`.\n * SSR-safe: falls back to `initial` when `window` is unavailable.\n */\nexport function persistedAtom<T>(opts: PersistedAtomOpts<T>): WritableAtom<T> {\n const { key, initial, serialize = JSON.stringify, deserialize = JSON.parse } = opts;\n\n let restored = initial;\n if (typeof window !== 'undefined') {\n try {\n const raw = localStorage.getItem(key);\n if (raw !== null) {\n restored = deserialize(raw);\n }\n } catch {\n // corrupt data — use initial\n }\n }\n\n const store = atom<T>(restored);\n\n if (typeof window !== 'undefined') {\n store.subscribe((value: T) => {\n try {\n localStorage.setItem(key, serialize(value));\n } catch {\n // storage full or unavailable — silently ignore\n }\n });\n }\n\n return store;\n}\n","import { computed } from 'nanostores';\nimport { persistedAtom, serializeWithBigInt, deserializeWithBigInt } from './persistedAtom';\n\nexport interface TrackedTx {\n hash: `0x${string}`;\n label: string;\n status: 'pending' | 'confirmed' | 'failed';\n timestamp: number;\n chainId: number;\n blockNumber?: bigint;\n gasUsed?: bigint;\n}\n\nconst MAX_TXS = 50;\n\nexport const txListStore = persistedAtom<TrackedTx[]>({\n key: 'bp_tx_history',\n initial: [],\n serialize: serializeWithBigInt,\n deserialize: deserializeWithBigInt,\n});\n\nexport const pendingCount = computed(txListStore, (txs: TrackedTx[]) =>\n txs.filter((tx: TrackedTx) => tx.status === 'pending').length,\n);\n\nexport function addTx(hash: `0x${string}`, label: string, chainId: number) {\n const existing = txListStore.get();\n if (existing.some((tx) => tx.hash === hash)) return;\n const newTx: TrackedTx = { hash, label, status: 'pending', timestamp: Date.now(), chainId };\n txListStore.set([newTx, ...existing].slice(0, MAX_TXS));\n}\n\nexport function updateTx(\n hash: `0x${string}`,\n update: Partial<Pick<TrackedTx, 'status' | 'blockNumber' | 'gasUsed'>>,\n) {\n txListStore.set(\n txListStore.get().map((tx: TrackedTx) =>\n tx.hash === hash ? { ...tx, ...update } : tx,\n ),\n );\n}\n\nexport function clearTxs() {\n txListStore.set([]);\n}\n","import { persistedAtom } from './persistedAtom';\nimport { getEnvVar } from '../utils/env';\n\nconst defaultBlueprintId = getEnvVar('VITE_BLUEPRINT_ID') ?? '0';\nconst defaultServiceId = getEnvVar('VITE_SERVICE_ID') ?? getEnvVar('VITE_SERVICE_IDS')?.split(',')[0] ?? '0';\n\nexport interface OperatorInfo {\n address: string;\n rpcAddress: string;\n}\n\nexport interface InfraConfig {\n blueprintId: string;\n serviceId: string;\n /** Whether the user has validated the service on-chain */\n serviceValidated: boolean;\n /** Cached service info from last validation */\n serviceInfo?: {\n active: boolean;\n operatorCount: number;\n owner: string;\n blueprintId: string;\n permitted: boolean;\n /** Operators with RPC endpoints (cached for RFQ) */\n operators?: OperatorInfo[];\n };\n}\n\nexport const infraStore = persistedAtom<InfraConfig>({\n key: 'bp_infra',\n initial: {\n blueprintId: defaultBlueprintId,\n serviceId: defaultServiceId,\n serviceValidated: false,\n },\n});\n\nexport function updateInfra(update: Partial<InfraConfig>) {\n infraStore.set({ ...infraStore.get(), ...update });\n}\n\nexport function getInfra(): InfraConfig {\n return infraStore.get();\n}\n","import { atom } from 'nanostores';\n\nexport type Theme = 'dark' | 'light';\n\nexport const kTheme = 'bp_theme';\nexport const DEFAULT_THEME = 'dark';\n\nexport const themeStore = atom<Theme>(initStore());\n\nexport function themeIsDark() {\n return themeStore.get() === 'dark';\n}\n\nfunction initStore() {\n if (typeof window !== 'undefined') {\n const persisted = localStorage.getItem(kTheme) as Theme | undefined;\n const attr = document.querySelector('html')?.getAttribute('data-theme');\n return persisted ?? (attr as Theme) ?? DEFAULT_THEME;\n }\n return DEFAULT_THEME;\n}\n\nexport function toggleTheme() {\n const next = themeStore.get() === 'dark' ? 'light' : 'dark';\n themeStore.set(next);\n localStorage.setItem(kTheme, next);\n document.querySelector('html')?.setAttribute('data-theme', next);\n}\n","/**\n * Tangle core precompile ABIs — shared across all blueprints.\n * Blueprint-specific ABIs (agentSandboxBlueprintAbi, tradingBlueprintAbi, etc.)\n * stay in each consuming app.\n */\n\nexport const tangleJobsAbi = [\n {\n type: 'function',\n name: 'submitJob',\n inputs: [\n { name: 'serviceId', type: 'uint64' },\n { name: 'job', type: 'uint8' },\n { name: 'args', type: 'bytes' },\n ],\n outputs: [{ name: 'callId', type: 'uint64' }],\n stateMutability: 'payable',\n },\n {\n type: 'event',\n name: 'JobCalled',\n inputs: [\n { name: 'serviceId', type: 'uint64', indexed: true },\n { name: 'job', type: 'uint8', indexed: true },\n { name: 'callId', type: 'uint64', indexed: true },\n { name: 'caller', type: 'address', indexed: false },\n { name: 'args', type: 'bytes', indexed: false },\n ],\n },\n {\n type: 'event',\n name: 'JobResultReceived',\n inputs: [\n { name: 'serviceId', type: 'uint64', indexed: true },\n { name: 'job', type: 'uint8', indexed: true },\n { name: 'callId', type: 'uint64', indexed: true },\n { name: 'operator', type: 'address', indexed: false },\n { name: 'outputs', type: 'bytes', indexed: false },\n ],\n },\n {\n type: 'event',\n name: 'JobSubmitted',\n inputs: [\n { name: 'serviceId', type: 'uint64', indexed: true },\n { name: 'callId', type: 'uint64', indexed: true },\n { name: 'jobIndex', type: 'uint8', indexed: false },\n { name: 'caller', type: 'address', indexed: false },\n { name: 'inputs', type: 'bytes', indexed: false },\n ],\n },\n {\n type: 'event',\n name: 'JobCompleted',\n inputs: [\n { name: 'serviceId', type: 'uint64', indexed: true },\n { name: 'callId', type: 'uint64', indexed: true },\n ],\n },\n {\n type: 'event',\n name: 'JobResultSubmitted',\n inputs: [\n { name: 'serviceId', type: 'uint64', indexed: true },\n { name: 'callId', type: 'uint64', indexed: true },\n { name: 'operator', type: 'address', indexed: true },\n { name: 'output', type: 'bytes', indexed: false },\n ],\n },\n] as const;\n\nexport const tangleServicesAbi = [\n {\n type: 'function',\n name: 'requestService',\n inputs: [\n { name: 'blueprintId', type: 'uint64' },\n { name: 'operators', type: 'address[]' },\n { name: 'config', type: 'bytes' },\n { name: 'permittedCallers', type: 'address[]' },\n { name: 'ttl', type: 'uint64' },\n { name: 'paymentToken', type: 'address' },\n { name: 'paymentAmount', type: 'uint256' },\n ],\n outputs: [{ name: 'requestId', type: 'uint64' }],\n stateMutability: 'payable',\n },\n {\n type: 'function',\n name: 'createServiceFromQuotes',\n inputs: [\n { name: 'blueprintId', type: 'uint64' },\n {\n name: 'quotes',\n type: 'tuple[]',\n components: [\n {\n name: 'details',\n type: 'tuple',\n components: [\n { name: 'blueprintId', type: 'uint64' },\n { name: 'ttlBlocks', type: 'uint64' },\n { name: 'totalCost', type: 'uint256' },\n { name: 'timestamp', type: 'uint64' },\n { name: 'expiry', type: 'uint64' },\n { name: 'confidentiality', type: 'uint8' },\n {\n name: 'securityCommitments',\n type: 'tuple[]',\n components: [\n {\n name: 'asset',\n type: 'tuple',\n components: [\n { name: 'kind', type: 'uint8' },\n { name: 'token', type: 'address' },\n ],\n },\n { name: 'exposureBps', type: 'uint16' },\n ],\n },\n {\n name: 'resourceCommitments',\n type: 'tuple[]',\n components: [\n { name: 'kind', type: 'uint8' },\n { name: 'count', type: 'uint64' },\n ],\n },\n ],\n },\n { name: 'signature', type: 'bytes' },\n { name: 'operator', type: 'address' },\n ],\n },\n { name: 'config', type: 'bytes' },\n { name: 'permittedCallers', type: 'address[]' },\n { name: 'ttl', type: 'uint64' },\n ],\n outputs: [{ name: 'serviceId', type: 'uint64' }],\n stateMutability: 'payable',\n },\n {\n type: 'function',\n name: 'getService',\n inputs: [{ name: 'serviceId', type: 'uint64' }],\n outputs: [\n {\n name: '',\n type: 'tuple',\n components: [\n { name: 'blueprintId', type: 'uint64' },\n { name: 'owner', type: 'address' },\n { name: 'createdAt', type: 'uint64' },\n { name: 'ttl', type: 'uint64' },\n { name: 'terminatedAt', type: 'uint64' },\n { name: 'lastPaymentAt', type: 'uint64' },\n { name: 'operatorCount', type: 'uint32' },\n { name: 'minOperators', type: 'uint32' },\n { name: 'maxOperators', type: 'uint32' },\n { name: 'membership', type: 'uint8' },\n { name: 'pricing', type: 'uint8' },\n { name: 'status', type: 'uint8' },\n ],\n },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'isServiceActive',\n inputs: [{ name: 'serviceId', type: 'uint64' }],\n outputs: [{ name: '', type: 'bool' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'getServiceOperators',\n inputs: [{ name: 'serviceId', type: 'uint64' }],\n outputs: [{ name: '', type: 'address[]' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'isPermittedCaller',\n inputs: [\n { name: 'serviceId', type: 'uint64' },\n { name: 'caller', type: 'address' },\n ],\n outputs: [{ name: '', type: 'bool' }],\n stateMutability: 'view',\n },\n {\n type: 'event',\n name: 'ServiceRequested',\n inputs: [\n { name: 'requestId', type: 'uint64', indexed: true },\n { name: 'blueprintId', type: 'uint64', indexed: true },\n { name: 'requester', type: 'address', indexed: true },\n ],\n },\n {\n type: 'event',\n name: 'ServiceActivated',\n inputs: [\n { name: 'serviceId', type: 'uint64', indexed: true },\n { name: 'requestId', type: 'uint64', indexed: true },\n { name: 'blueprintId', type: 'uint64', indexed: true },\n ],\n },\n] as const;\n\nexport const tangleOperatorsAbi = [\n {\n type: 'function',\n name: 'blueprintOperatorCount',\n inputs: [{ name: 'blueprintId', type: 'uint64' }],\n outputs: [{ name: '', type: 'uint256' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'isOperatorRegistered',\n inputs: [\n { name: 'blueprintId', type: 'uint64' },\n { name: 'operator', type: 'address' },\n ],\n outputs: [{ name: '', type: 'bool' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'getOperatorPreferences',\n inputs: [\n { name: 'blueprintId', type: 'uint64' },\n { name: 'operator', type: 'address' },\n ],\n outputs: [\n {\n name: 'preferences',\n type: 'tuple',\n components: [\n { name: 'ecdsaPublicKey', type: 'bytes' },\n { name: 'rpcAddress', type: 'string' },\n ],\n },\n ],\n stateMutability: 'view',\n },\n {\n type: 'event',\n name: 'OperatorRegistered',\n inputs: [\n { name: 'blueprintId', type: 'uint64', indexed: true },\n { name: 'operator', type: 'address', indexed: true },\n { name: 'ecdsaPublicKey', type: 'bytes', indexed: false },\n { name: 'rpcAddress', type: 'string', indexed: false },\n ],\n },\n {\n type: 'event',\n name: 'OperatorUnregistered',\n inputs: [\n { name: 'blueprintId', type: 'uint64', indexed: true },\n { name: 'operator', type: 'address', indexed: true },\n ],\n },\n] as const;\n","import { createPublicClient, http } from 'viem';\nimport type { PublicClient } from 'viem';\nimport { atom } from 'nanostores';\nimport { getNetworks, tangleLocal, type CoreAddresses } from './chains';\nimport { persistedAtom } from '../stores/persistedAtom';\nimport { getEnvVar } from '../utils/env';\n\nconst defaultChainId = Number(getEnvVar('VITE_CHAIN_ID') ?? tangleLocal.id);\n\nexport const selectedChainIdStore = persistedAtom<number>({\n key: 'bp_selected_chain',\n initial: defaultChainId,\n});\n\nconst clientCache = new Map<number, PublicClient>();\n\nfunction configuredDefaultChainId(): number {\n const networks = getNetworks();\n if (networks[defaultChainId]) return defaultChainId;\n\n for (const [chainId, net] of Object.entries(networks)) {\n if (\n net?.shortLabel === 'Local' ||\n net?.label === 'Tangle Local' ||\n net?.chain?.name === 'Tangle Local'\n ) {\n return Number(chainId);\n }\n }\n\n const [firstConfigured] = Object.keys(networks);\n return firstConfigured ? Number(firstConfigured) : defaultChainId;\n}\n\nfunction normalizeSelectedChainId(chainId: number): number {\n const networks = getNetworks();\n if (!Object.keys(networks).length) return chainId;\n return networks[chainId] ? chainId : configuredDefaultChainId();\n}\n\nexport function sanitizeSelectedChainId(): number {\n const normalized = normalizeSelectedChainId(selectedChainIdStore.get());\n if (normalized !== selectedChainIdStore.get()) {\n selectedChainIdStore.set(normalized);\n }\n return normalized;\n}\n\nfunction getOrCreateClient(chainId: number): PublicClient {\n const normalizedChainId = normalizeSelectedChainId(chainId);\n\n const cached = clientCache.get(normalizedChainId);\n if (cached) return cached;\n const networks = getNetworks();\n const net = networks[normalizedChainId];\n if (!net) {\n const fallback = networks[configuredDefaultChainId()];\n if (!fallback) {\n return createPublicClient({ chain: tangleLocal, transport: http() });\n }\n return createPublicClient({ chain: fallback.chain, transport: http(fallback.rpcUrl) });\n }\n const client = createPublicClient({ chain: net.chain, transport: http(net.rpcUrl) });\n clientCache.set(normalizedChainId, client);\n return client;\n}\n\nexport const publicClientStore = atom<PublicClient>(getOrCreateClient(sanitizeSelectedChainId()));\n\nselectedChainIdStore.subscribe((chainId: number) => {\n const normalized = normalizeSelectedChainId(chainId);\n if (normalized !== chainId) {\n selectedChainIdStore.set(normalized);\n return;\n }\n publicClientStore.set(getOrCreateClient(normalized));\n});\n\nexport function getPublicClient(): PublicClient {\n sanitizeSelectedChainId();\n return publicClientStore.get();\n}\n\nexport const publicClient = new Proxy({} as PublicClient, {\n get(_target, prop) {\n const client = getOrCreateClient(sanitizeSelectedChainId());\n const value = (client as any)[prop];\n return typeof value === 'function' ? value.bind(client) : value;\n },\n});\n\nexport function getAddresses<T extends CoreAddresses = CoreAddresses>(): T {\n const networks = getNetworks<T>();\n const selectedChainId = sanitizeSelectedChainId();\n const net = networks[selectedChainId];\n return net?.addresses ?? networks[configuredDefaultChainId()]?.addresses ?? {} as T;\n}\n","import { encodeAbiParameters } from 'viem';\nimport type { JobDefinition } from '../blueprints/registry';\n\n/**\n * Generic ABI encoder for any blueprint job.\n *\n * Builds the ordered parameter array from:\n * 1. contextParams (e.g. sidecar_url, sandbox_id) — prepended first\n * 2. fields with abiType set — appended in definition order\n *\n * Delegates to job.customEncoder when present (for nested-struct jobs like batch_create).\n */\nexport function encodeJobArgs(\n job: JobDefinition,\n formValues: Record<string, unknown>,\n context?: Record<string, unknown>,\n): `0x${string}` {\n if (job.customEncoder) {\n return job.customEncoder(formValues, context);\n }\n\n const abiDefs: { name: string; type: string }[] = [];\n const values: unknown[] = [];\n\n // Context params first (sidecar_url, sandbox_id, etc.)\n if (job.contextParams) {\n for (const cp of job.contextParams) {\n abiDefs.push({ name: cp.abiName, type: cp.abiType });\n values.push(coerceValue(context?.[cp.abiName], cp.abiType));\n }\n }\n\n // Form fields with ABI metadata\n for (const field of job.fields) {\n if (!field.abiType) continue;\n abiDefs.push({ name: field.abiParam ?? field.name, type: field.abiType });\n values.push(coerceValue(formValues[field.name], field.abiType));\n }\n\n return encodeAbiParameters(abiDefs, values);\n}\n\nfunction coerceValue(value: unknown, abiType: string): unknown {\n switch (abiType) {\n case 'bool':\n return Boolean(value);\n case 'uint8':\n case 'uint16':\n case 'uint32':\n return Number(value) || 0;\n case 'uint64':\n case 'uint128':\n case 'uint256':\n return BigInt(Number(value) || 0);\n case 'string':\n return String(value ?? '');\n case 'string[]':\n if (Array.isArray(value)) return value.map(String);\n return String(value ?? '').split('\\n').filter(Boolean);\n case 'address[]':\n if (Array.isArray(value)) return value;\n return String(value ?? '')\n .split('\\n')\n .map((s) => s.trim())\n .filter((s) => /^0x[a-fA-F0-9]{40}$/.test(s));\n default:\n return value;\n }\n}\n","import { useState, useCallback, useEffect, useMemo } from 'react';\nimport type { JobDefinition } from '../blueprints/registry';\n\nexport interface JobFormState {\n values: Record<string, unknown>;\n errors: Record<string, string>;\n onChange: (name: string, value: unknown) => void;\n validate: () => boolean;\n reset: () => void;\n}\n\nfunction buildDefaults(job: JobDefinition): Record<string, unknown> {\n const init: Record<string, unknown> = {};\n for (const f of job.fields) {\n if (f.internal) continue;\n if (f.defaultValue !== undefined) {\n init[f.name] = f.defaultValue;\n } else if (f.type === 'boolean') {\n init[f.name] = false;\n } else if (f.type === 'number') {\n init[f.name] = f.min ?? 0;\n } else {\n init[f.name] = '';\n }\n }\n return init;\n}\n\nexport function useJobForm(job: JobDefinition | null): JobFormState {\n const defaults = useMemo(() => (job ? buildDefaults(job) : {}), [job]);\n const [values, setValues] = useState<Record<string, unknown>>(defaults);\n const [errors, setErrors] = useState<Record<string, string>>({});\n\n // Sync form values when job changes (e.g. blueprint selection or async load)\n useEffect(() => {\n setValues(defaults);\n setErrors({});\n }, [defaults]);\n\n const onChange = useCallback((name: string, value: unknown) => {\n setValues((prev) => ({ ...prev, [name]: value }));\n setErrors((prev) => {\n if (!prev[name]) return prev;\n const next = { ...prev };\n delete next[name];\n return next;\n });\n }, []);\n\n const validate = useCallback((): boolean => {\n if (!job) return false;\n const errs: Record<string, string> = {};\n for (const f of job.fields) {\n if (f.internal) continue;\n const v = values[f.name];\n if (f.required && (v === undefined || v === null || v === '')) {\n errs[f.name] = `${f.label} is required`;\n continue;\n }\n if (f.type === 'number' && typeof v === 'number') {\n if (f.min != null && v < f.min) {\n errs[f.name] = `${f.label} must be at least ${f.min}`;\n } else if (f.max != null && v > f.max) {\n errs[f.name] = `${f.label} must be at most ${f.max}`;\n }\n }\n }\n setErrors(errs);\n return Object.keys(errs).length === 0;\n }, [job, values]);\n\n const reset = useCallback(() => {\n setValues(defaults);\n setErrors({});\n }, [defaults]);\n\n return { values, errors, onChange, validate, reset };\n}\n","import { useState, useEffect, useCallback } from 'react';\nimport type { Address } from 'viem';\nimport { sha256 as viemSha256, toHex } from 'viem';\nimport type { DiscoveredOperator } from './useOperators';\nimport { resolveOperatorRpc } from '../utils/resolveOperatorRpc';\n\n/**\n * RFQ (Request for Quote) hook — fetches pricing quotes from operators.\n *\n * Implements the Tangle pricing protocol:\n * 1. Solve PoW challenge (SHA256 with 20-bit difficulty)\n * 2. Send gRPC GetPrice request to each operator's registered RPC\n * 3. Collect signed QuoteDetails for createServiceFromQuotes()\n *\n * When operators don't have a pricing engine (no rpcAddress), falls back to\n * multiplier-based estimation from the on-chain getDefaultJobRates().\n */\n\n// ── Types ──\n\ntype SecurityCommitment = {\n asset: { kind: number; token: Address };\n exposureBps: number;\n};\n\ntype ResourceCommitment = {\n kind: number;\n count: bigint;\n};\n\nexport interface OperatorQuote {\n operator: Address;\n totalCost: bigint;\n signature: `0x${string}`;\n details: {\n blueprintId: bigint;\n ttlBlocks: bigint;\n totalCost: bigint;\n timestamp: bigint;\n expiry: bigint;\n confidentiality: number;\n securityCommitments: readonly SecurityCommitment[];\n resourceCommitments: readonly ResourceCommitment[];\n };\n costRate: number;\n teeAttested?: boolean;\n teeProvider?: string;\n}\n\nexport interface UseQuotesResult {\n quotes: OperatorQuote[];\n isLoading: boolean;\n isSolvingPow: boolean;\n errors: Map<Address, string>;\n totalCost: bigint;\n refetch: () => void;\n}\n\n// ── PoW solver (mirrors Tangle pricing-engine/src/pow.rs) ──\n\nconst POW_DIFFICULTY = 20;\nconst WEI_PER_TNT = 1_000_000_000_000_000_000; // 10^18\nconst RESOURCE_KIND_TO_ID = {\n CPU: 0,\n MemoryMB: 1,\n StorageMB: 2,\n NetworkEgressMB: 3,\n NetworkIngressMB: 4,\n GPU: 5,\n} as const;\nconst ZERO_ADDRESS = '0x0000000000000000000000000000000000000000' as Address;\nconst DEFAULT_RESOURCE_REQUIREMENTS = [\n { kind: 'CPU', count: 1 },\n { kind: 'MemoryMB', count: 1024 },\n { kind: 'StorageMB', count: 10240 },\n] as const;\n\nfunction sha256(data: Uint8Array): Uint8Array {\n return viemSha256(data, 'bytes');\n}\n\nfunction generateChallenge(blueprintId: bigint, timestamp: bigint): Uint8Array {\n const input = new Uint8Array(16);\n const view = new DataView(input.buffer);\n view.setBigUint64(0, blueprintId, false);\n view.setBigUint64(8, timestamp, false);\n return sha256(input);\n}\n\nfunction checkDifficulty(hash: Uint8Array, difficulty: number): boolean {\n const zeroBytes = Math.floor(difficulty / 8);\n const zeroBits = difficulty % 8;\n for (let i = 0; i < zeroBytes; i++) {\n if (hash[i] !== 0) return false;\n }\n if (zeroBits > 0) {\n const mask = 0xff << (8 - zeroBits);\n if ((hash[zeroBytes] & mask) !== 0) return false;\n }\n return true;\n}\n\nexport async function solvePoW(\n blueprintId: bigint,\n timestamp: bigint,\n): Promise<{ hash: Uint8Array; nonce: number; proof: Uint8Array }> {\n const challenge = generateChallenge(blueprintId, timestamp);\n const buf = new Uint8Array(challenge.length + 8);\n buf.set(challenge, 0);\n const view = new DataView(buf.buffer);\n\n for (let nonce = 0; nonce < 0x1_0000_0000; nonce++) {\n view.setBigUint64(challenge.length, BigInt(nonce), false);\n const hash = sha256(buf);\n if (checkDifficulty(hash, POW_DIFFICULTY)) {\n // Bincode-serialize Proof { hash: Vec<u8>, nonce: u64 }\n const proof = new Uint8Array(8 + 32 + 8);\n const pv = new DataView(proof.buffer);\n pv.setBigUint64(0, 32n, true);\n proof.set(hash, 8);\n pv.setBigUint64(40, BigInt(nonce), true);\n return { hash, nonce, proof };\n }\n // Yield to browser every 5000 iterations\n if (nonce % 5000 === 0 && nonce > 0) {\n await new Promise((r) => setTimeout(r, 0));\n }\n }\n throw new Error('PoW: exhausted nonce space');\n}\n\nexport function formatCost(totalCost: bigint): string {\n // totalCost is in wei (1e18 wei = 1 TNT)\n const tnt = Number(totalCost) / WEI_PER_TNT;\n if (tnt === 0) return '0 TNT';\n if (tnt < 0.001) return `${(tnt * 1_000_000).toFixed(2)} \\u03bcTNT`;\n if (tnt < 0.01) return `${(tnt * 1000).toFixed(2)} mTNT`;\n if (tnt < 1000) return `${tnt.toFixed(4)} TNT`;\n return `${tnt.toLocaleString(undefined, { maximumFractionDigits: 2 })} TNT`;\n}\n\nfunction quoteConfidentiality(requireTee: boolean): number {\n return requireTee ? 1 : 0;\n}\n\nfunction resourceKindToId(kind: string): number {\n const mapped = RESOURCE_KIND_TO_ID[kind as keyof typeof RESOURCE_KIND_TO_ID];\n if (mapped === undefined) {\n throw new Error(`Unsupported resource kind in quote: ${kind}`);\n }\n return mapped;\n}\n\nfunction mapJsonSecurityCommitment(sc: any): SecurityCommitment {\n return {\n asset: {\n kind: sc.asset?.kind ?? 0,\n token: (sc.asset?.token ?? ZERO_ADDRESS) as Address,\n },\n exposureBps: sc.exposure_bps ?? 0,\n };\n}\n\nfunction mapJsonResourceCommitment(resource: any): ResourceCommitment {\n return {\n kind: resourceKindToId(String(resource.kind ?? 'CPU')),\n count: BigInt(resource.count ?? 0),\n };\n}\n\n// ── Hook ──\n\nexport function useQuotes(\n operators: DiscoveredOperator[],\n blueprintId: bigint,\n ttlBlocks: bigint,\n enabled: boolean,\n requireTee = false,\n): UseQuotesResult {\n const [quotes, setQuotes] = useState<OperatorQuote[]>([]);\n const [isLoading, setIsLoading] = useState(false);\n const [isSolvingPow, setIsSolvingPow] = useState(false);\n const [errors, setErrors] = useState<Map<Address, string>>(new Map());\n const [fetchKey, setFetchKey] = useState(0);\n\n const refetch = useCallback(() => setFetchKey((k) => k + 1), []);\n\n useEffect(() => {\n if (!enabled || operators.length === 0) {\n // Only set state if it's actually non-empty to avoid triggering re-renders\n setQuotes((prev) => (prev.length === 0 ? prev : []));\n setErrors((prev) => (prev.size === 0 ? prev : new Map()));\n return;\n }\n\n let cancelled = false;\n setIsLoading(true);\n setIsSolvingPow(true);\n setQuotes([]);\n setErrors(new Map());\n\n async function fetchQuotes() {\n const results: OperatorQuote[] = [];\n const errs = new Map<Address, string>();\n\n const promises = operators.map(async (op) => {\n try {\n if (!op.rpcAddress) throw new Error('No RPC address registered');\n\n const rpcUrl = resolveOperatorRpc(op.rpcAddress);\n const timestamp = BigInt(Math.floor(Date.now() / 1000));\n\n // Solve PoW challenge\n if (!cancelled) setIsSolvingPow(true);\n const { proof } = await solvePoW(blueprintId, timestamp);\n if (!cancelled) setIsSolvingPow(false);\n\n // Try gRPC GetPrice endpoint\n // Since we may not have the generated protobuf types, try a JSON/REST\n // fallback first, then gRPC if available\n const response = await fetchPriceFromOperator(rpcUrl, {\n blueprintId,\n ttlBlocks,\n proofOfWork: proof,\n challengeTimestamp: timestamp,\n requireTee,\n });\n\n if (!response) throw new Error('No quote returned from operator');\n\n if (!cancelled) results.push(response);\n } catch (err) {\n if (!cancelled) {\n errs.set(op.address, err instanceof Error ? err.message : String(err));\n }\n }\n });\n\n await Promise.allSettled(promises);\n\n if (!cancelled) {\n setQuotes(results);\n setErrors(errs);\n setIsLoading(false);\n setIsSolvingPow(false);\n }\n }\n\n fetchQuotes();\n return () => {\n cancelled = true;\n };\n }, [operators, blueprintId, ttlBlocks, enabled, fetchKey, requireTee]);\n\n const totalCost = quotes.reduce((sum, q) => sum + q.totalCost, 0n);\n\n return { quotes, isLoading, isSolvingPow, errors, totalCost, refetch };\n}\n\n/**\n * Attempt to fetch a price from an operator's RPC endpoint.\n * Tries a JSON endpoint first (/pricing/quote), which operators may optionally expose.\n * Returns null if the operator doesn't support pricing.\n */\nasync function fetchPriceFromOperator(\n rpcUrl: string,\n params: {\n blueprintId: bigint;\n ttlBlocks: bigint;\n proofOfWork: Uint8Array;\n challengeTimestamp: bigint;\n requireTee: boolean;\n },\n): Promise<OperatorQuote | null> {\n // Try JSON endpoint (simpler, no protobuf dependency required)\n try {\n const response = await fetch(`${rpcUrl}/pricing/quote`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n blueprint_id: String(params.blueprintId),\n ttl_blocks: String(params.ttlBlocks),\n proof_of_work: toHex(params.proofOfWork),\n challenge_timestamp: String(params.challengeTimestamp),\n require_tee: params.requireTee,\n resource_requirements: DEFAULT_RESOURCE_REQUIREMENTS,\n }),\n signal: AbortSignal.timeout(10_000),\n });\n\n if (!response.ok) throw new Error(`HTTP ${response.status}`);\n const data = await response.json();\n\n return {\n operator: data.operator as Address,\n totalCost: BigInt(data.total_cost ?? '0'),\n signature: (data.signature ?? '0x') as `0x${string}`,\n costRate: Number(data.cost_rate ?? 0),\n teeAttested: Boolean(data.tee_attested),\n teeProvider: data.tee_provider || undefined,\n details: {\n blueprintId: BigInt(data.details?.blueprint_id ?? params.blueprintId),\n ttlBlocks: BigInt(data.details?.ttl_blocks ?? params.ttlBlocks),\n totalCost: BigInt(data.details?.total_cost ?? '0'),\n timestamp: BigInt(data.details?.timestamp ?? params.challengeTimestamp),\n expiry: BigInt(data.details?.expiry ?? '0'),\n confidentiality: Number(data.details?.confidentiality ?? quoteConfidentiality(params.requireTee)),\n securityCommitments: (data.details?.security_commitments ?? []).map(mapJsonSecurityCommitment),\n resourceCommitments: (data.details?.resources ?? []).map(mapJsonResourceCommitment),\n },\n };\n } catch {\n // JSON endpoint not available — operator doesn't have pricing engine\n return null;\n }\n}\n","import { useState, useEffect, useCallback, useRef } from 'react';\nimport type { Address } from 'viem';\nimport { toHex } from 'viem';\nimport { solvePoW, formatCost } from './useQuotes';\n\n/**\n * Per-job RFQ hook — fetches price quotes for a specific job before submission.\n *\n * Implements the GetJobPrice protocol:\n * 1. Solve PoW challenge (same as service-level RFQ)\n * 2. POST to operator's /pricing/job-quote endpoint\n * 3. Return signed JobQuoteDetails for submitJobFromQuote()\n *\n * This is the per-job counterpart to useQuotes (which handles service creation).\n * Together they provide full RFQ coverage for the UI.\n */\n\n// ── Types ──\n\nexport interface JobQuote {\n serviceId: bigint;\n jobIndex: number;\n price: bigint;\n timestamp: bigint;\n expiry: bigint;\n signature: `0x${string}`;\n operatorAddress: Address;\n}\n\nexport interface UseJobPriceResult {\n quote: JobQuote | null;\n isLoading: boolean;\n isSolvingPow: boolean;\n error: string | null;\n formattedPrice: string;\n refetch: () => void;\n}\n\n/** Rewrite operator RPC hostname for browser reachability */\nfunction resolveOperatorRpc(raw: string): string {\n if (typeof window === 'undefined') return raw;\n const withProto = raw.includes('://') ? raw : `http://${raw}`;\n try {\n const url = new URL(withProto);\n const pageHost = window.location.hostname;\n const isNonRoutable =\n url.hostname.endsWith('.local') ||\n !url.hostname.includes('.') ||\n url.hostname === '127.0.0.1' ||\n url.hostname === 'localhost';\n if (isNonRoutable && pageHost !== url.hostname) {\n url.hostname = pageHost;\n }\n return url.toString().replace(/\\/$/, '');\n } catch {\n return withProto;\n }\n}\n\n// ── Hook ──\n\nexport function useJobPrice(\n operatorRpcUrl: string | undefined,\n serviceId: bigint,\n jobIndex: number,\n blueprintId: bigint,\n enabled: boolean,\n): UseJobPriceResult {\n const [quote, setQuote] = useState<JobQuote | null>(null);\n const [isLoading, setIsLoading] = useState(false);\n const [isSolvingPow, setIsSolvingPow] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [fetchKey, setFetchKey] = useState(0);\n const cancelledRef = useRef(false);\n\n const refetch = useCallback(() => setFetchKey((k) => k + 1), []);\n\n useEffect(() => {\n if (!enabled || !operatorRpcUrl || serviceId === 0n) {\n setQuote(null);\n setError(null);\n return;\n }\n\n cancelledRef.current = false;\n setIsLoading(true);\n setError(null);\n setQuote(null);\n\n async function fetchJobQuote() {\n try {\n const rpcUrl = resolveOperatorRpc(operatorRpcUrl!);\n const timestamp = BigInt(Math.floor(Date.now() / 1000));\n\n // Solve PoW\n setIsSolvingPow(true);\n const { proof } = await solvePoW(blueprintId, timestamp);\n if (cancelledRef.current) return;\n setIsSolvingPow(false);\n\n // Fetch job price from operator\n const response = await fetch(`${rpcUrl}/pricing/job-quote`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n service_id: String(serviceId),\n job_index: jobIndex,\n proof_of_work: toHex(proof),\n challenge_timestamp: String(timestamp),\n }),\n signal: AbortSignal.timeout(10_000),\n });\n\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${await response.text().catch(() => 'Unknown error')}`);\n }\n\n const data = await response.json();\n if (cancelledRef.current) return;\n\n setQuote({\n serviceId: BigInt(data.service_id ?? serviceId),\n jobIndex: data.job_index ?? jobIndex,\n price: BigInt(data.price ?? '0'),\n timestamp: BigInt(data.timestamp ?? timestamp),\n expiry: BigInt(data.expiry ?? '0'),\n signature: (data.signature ?? '0x') as `0x${string}`,\n operatorAddress: data.operator as Address,\n });\n } catch (err) {\n if (!cancelledRef.current) {\n setError(err instanceof Error ? err.message : String(err));\n }\n } finally {\n if (!cancelledRef.current) {\n setIsLoading(false);\n setIsSolvingPow(false);\n }\n }\n }\n\n fetchJobQuote();\n return () => {\n cancelledRef.current = true;\n };\n }, [operatorRpcUrl, serviceId, jobIndex, blueprintId, enabled, fetchKey]);\n\n const formattedPrice = quote ? formatCost(quote.price) : '--';\n\n return { quote, isLoading, isSolvingPow, error, formattedPrice, refetch };\n}\n\n/**\n * Batch version — fetches job prices for multiple jobs at once.\n * Used by the blueprint job list to show all prices simultaneously.\n */\nexport interface JobPriceEntry {\n jobIndex: number;\n jobName: string;\n price: bigint;\n formattedPrice: string;\n mode: 'flat' | 'dynamic' | 'free';\n quote: JobQuote | null;\n error: string | null;\n}\n\nexport interface UseJobPricesResult {\n prices: JobPriceEntry[];\n isLoading: boolean;\n error: string | null;\n refetch: () => void;\n}\n\nexport function useJobPrices(\n operatorRpcUrl: string | undefined,\n serviceId: bigint,\n blueprintId: bigint,\n jobIndexes: { index: number; name: string; multiplier: number }[],\n enabled: boolean,\n): UseJobPricesResult {\n const [prices, setPrices] = useState<JobPriceEntry[]>([]);\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [fetchKey, setFetchKey] = useState(0);\n\n const refetch = useCallback(() => setFetchKey((k) => k + 1), []);\n\n useEffect(() => {\n if (!enabled || !operatorRpcUrl || serviceId === 0n || jobIndexes.length === 0) {\n setPrices([]);\n setError(null);\n return;\n }\n\n let cancelled = false;\n setIsLoading(true);\n setError(null);\n\n async function fetchAllPrices() {\n try {\n const rpcUrl = resolveOperatorRpc(operatorRpcUrl!);\n const timestamp = BigInt(Math.floor(Date.now() / 1000));\n const { proof } = await solvePoW(blueprintId, timestamp);\n if (cancelled) return;\n\n // Fetch all job prices in parallel\n const results = await Promise.allSettled(\n jobIndexes.map(async (job) => {\n const response = await fetch(`${rpcUrl}/pricing/job-quote`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n service_id: String(serviceId),\n job_index: job.index,\n proof_of_work: toHex(proof),\n challenge_timestamp: String(timestamp),\n }),\n signal: AbortSignal.timeout(10_000),\n });\n\n if (!response.ok) return null;\n return response.json();\n }),\n );\n\n if (cancelled) return;\n\n const entries: JobPriceEntry[] = jobIndexes.map((job, i) => {\n const result = results[i];\n if (result.status === 'fulfilled' && result.value) {\n const data = result.value;\n const price = BigInt(data.price ?? '0');\n return {\n jobIndex: job.index,\n jobName: job.name,\n price,\n formattedPrice: formatCost(price),\n mode: (data.mode ?? 'flat') as 'flat' | 'dynamic' | 'free',\n quote: {\n serviceId: BigInt(data.service_id ?? serviceId),\n jobIndex: job.index,\n price,\n timestamp: BigInt(data.timestamp ?? timestamp),\n expiry: BigInt(data.expiry ?? '0'),\n signature: (data.signature ?? '0x') as `0x${string}`,\n operatorAddress: data.operator as Address,\n },\n error: null,\n };\n }\n // Fallback: estimate from multiplier (base rate = 0.001 TNT = 1e15 wei)\n const estimatedPrice = BigInt(job.multiplier) * 1_000_000_000_000_000n;\n return {\n jobIndex: job.index,\n jobName: job.name,\n price: estimatedPrice,\n formattedPrice: `~${formatCost(estimatedPrice)}`,\n mode: 'flat' as const,\n quote: null,\n error: 'No RFQ response — showing estimate',\n };\n });\n\n setPrices(entries);\n } catch (err) {\n if (!cancelled) {\n setError(err instanceof Error ? err.message : String(err));\n }\n } finally {\n if (!cancelled) {\n setIsLoading(false);\n }\n }\n }\n\n fetchAllPrices();\n return () => {\n cancelled = true;\n };\n }, [operatorRpcUrl, serviceId, blueprintId, jobIndexes, enabled, fetchKey]);\n\n return { prices, isLoading, error, refetch };\n}\n","import { useCallback, useState, useMemo } from 'react';\nimport { useAccount, useWriteContract, useWaitForTransactionReceipt } from 'wagmi';\nimport { decodeEventLog } from 'viem';\nimport { tangleJobsAbi } from '../contracts/abi';\nimport { getAddresses } from '../contracts/publicClient';\nimport { addTx, updateTx } from '../stores/txHistory';\nimport { selectedChainIdStore } from '../contracts/publicClient';\nimport { useEffect } from 'react';\n\nexport interface SubmitJobOpts {\n serviceId: bigint;\n jobId: number;\n args: `0x${string}`;\n label?: string;\n value?: bigint;\n}\n\nexport type JobSubmitStatus = 'idle' | 'signing' | 'pending' | 'confirmed' | 'failed';\n\nexport function useSubmitJob() {\n const { address } = useAccount();\n const { writeContractAsync, data: hash, isPending: isSigning } = useWriteContract();\n const [status, setStatus] = useState<JobSubmitStatus>('idle');\n const [error, setError] = useState<string | null>(null);\n const [txHash, setTxHash] = useState<`0x${string}` | undefined>();\n\n const { data: receipt, isSuccess, isError } = useWaitForTransactionReceipt({\n hash: txHash,\n });\n\n // Extract callId from the JobCalled event in the receipt logs\n const callId = useMemo<number | null>(() => {\n if (!receipt?.logs) return null;\n for (const log of receipt.logs) {\n try {\n const decoded = decodeEventLog({\n abi: tangleJobsAbi,\n data: log.data,\n topics: log.topics,\n });\n if (decoded.eventName === 'JobCalled' && 'callId' in decoded.args) {\n return Number(decoded.args.callId);\n }\n } catch {\n // Not a matching event, skip\n }\n }\n return null;\n }, [receipt]);\n\n useEffect(() => {\n if (isSuccess && txHash) {\n setStatus('confirmed');\n updateTx(txHash, { status: 'confirmed' });\n }\n if (isError && txHash) {\n setStatus('failed');\n updateTx(txHash, { status: 'failed' });\n }\n }, [isSuccess, isError, txHash]);\n\n const submitJob = useCallback(\n async (opts: SubmitJobOpts) => {\n if (!address) {\n setError('Wallet not connected');\n return undefined;\n }\n\n const addrs = getAddresses();\n const label = opts.label ?? `Job #${opts.jobId}`;\n\n try {\n setStatus('signing');\n setError(null);\n\n const result = await writeContractAsync({\n address: addrs.jobs,\n abi: tangleJobsAbi,\n functionName: 'submitJob',\n args: [opts.serviceId, opts.jobId, opts.args],\n value: opts.value,\n });\n\n setTxHash(result);\n setStatus('pending');\n addTx(result, label, selectedChainIdStore.get());\n\n return result;\n } catch (err: any) {\n setStatus('failed');\n const msg = err?.shortMessage ?? err?.message ?? 'Transaction failed';\n setError(msg);\n return undefined;\n }\n },\n [address, writeContractAsync],\n );\n\n const reset = useCallback(() => {\n setStatus('idle');\n setError(null);\n setTxHash(undefined);\n }, []);\n\n return {\n submitJob,\n reset,\n status,\n error,\n txHash,\n callId,\n isSigning,\n isConnected: !!address,\n };\n}\n","import { useStore } from '@nanostores/react';\nimport { themeStore, type Theme } from '../stores/theme';\n\nexport function useThemeValue(): Theme {\n return useStore(themeStore);\n}\n"],"mappings":";AACO,SAAS,mBAAmB,KAAqB;AACtD,MAAI,OAAO,WAAW,YAAa,QAAO;AAC1C,QAAM,YAAY,IAAI,SAAS,KAAK,IAAI,MAAM,UAAU,GAAG;AAC3D,MAAI;AACF,UAAM,MAAM,IAAI,IAAI,SAAS;AAC7B,UAAM,WAAW,OAAO,SAAS;AACjC,UAAM,gBACJ,IAAI,SAAS,SAAS,QAAQ,KAC9B,CAAC,IAAI,SAAS,SAAS,GAAG,KAC1B,IAAI,aAAa,eACjB,IAAI,aAAa;AACnB,QAAI,iBAAiB,aAAa,IAAI,UAAU;AAC9C,UAAI,WAAW;AAAA,IACjB;AACA,WAAO,IAAI,SAAS,EAAE,QAAQ,OAAO,EAAE;AAAA,EACzC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;;;ACnBA,SAAS,mBAAmB;AAC5B,SAAS,eAAe;;;ACSxB,SAAS,oBAAuC;AAC9C,SAAS,YAAyD,OAAO,CAAC;AAC5E;AAEO,SAAS,UAAU,KAAkD;AAC1E,QAAM,QAAQ,kBAAkB,EAAE,GAAG;AACrC,SAAO,OAAO,UAAU,WAAW,QAAQ;AAC7C;AAEO,SAAS,WAAoB;AAClC,SAAO,QAAQ,kBAAkB,EAAE,GAAG;AACxC;;;ADZO,SAAS,cAAc,QAAyB;AACrD,QAAM,aAAa,UAAU,UAAU,cAAc,KAAK;AAC1D,MAAI,OAAO,WAAW,YAAa,QAAO;AAC1C,MAAI;AACF,UAAM,MAAM,IAAI,IAAI,UAAU;AAC9B,UAAM,aAAa,IAAI,aAAa,eAAe,IAAI,aAAa;AACpE,UAAM,WAAW,OAAO,SAAS;AACjC,UAAM,cAAc,aAAa,eAAe,aAAa;AAE7D,QAAI,cAAc,CAAC,eAAe,SAAS,GAAG;AAC5C,aAAO,GAAG,OAAO,SAAS,MAAM;AAAA,IAClC;AAEA,QAAI,cAAc,CAAC,aAAa;AAC9B,UAAI,WAAW;AACf,aAAO,IAAI,SAAS,EAAE,QAAQ,OAAO,EAAE;AAAA,IACzC;AAAA,EACF,QAAQ;AAAA,EAER;AACA,SAAO;AACT;AAEO,IAAM,SAAS,cAAc;AAO7B,SAAS,uBAAuB,UAA6B,CAAC,GAAG;AACtE,QAAM,UAAU,QAAQ,WAAW,OAAO,UAAU,eAAe,KAAK,KAAK;AAC7E,QAAM,cAAc,cAAc,QAAQ,MAAM;AAEhD,SAAO,YAAY;AAAA,IACjB,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,gBAAgB,EAAE,MAAM,SAAS,QAAQ,OAAO,UAAU,GAAG;AAAA,IAC7D,SAAS,EAAE,SAAS,EAAE,MAAM,CAAC,WAAW,EAAE,EAAE;AAAA,IAC5C,gBAAgB,EAAE,SAAS,EAAE,MAAM,YAAY,KAAK,GAAG,EAAE;AAAA,IACzD,WAAW,EAAE,YAAY,EAAE,SAAS,6CAA6C,EAAE;AAAA,EACrF,CAAC;AACH;AAEO,IAAM,cAAc,uBAAuB;AAE3C,IAAM,gBAAgB,YAAY;AAAA,EACvC,IAAI;AAAA,EACJ,MAAM;AAAA,EACN,gBAAgB,EAAE,MAAM,UAAU,QAAQ,QAAQ,UAAU,GAAG;AAAA,EAC/D,SAAS;AAAA,IACP,SAAS;AAAA,MACP,MAAM,CAAC,kCAAkC;AAAA,MACzC,WAAW,CAAC,gCAAgC;AAAA,IAC9C;AAAA,EACF;AAAA,EACA,gBAAgB,EAAE,SAAS,EAAE,MAAM,mBAAmB,KAAK,wCAAwC,EAAE;AAAA,EACrG,WAAW,EAAE,YAAY,EAAE,SAAS,6CAA6C,EAAE;AACrF,CAAC;AAEM,IAAM,gBAAgB,YAAY;AAAA,EACvC,IAAI;AAAA,EACJ,MAAM;AAAA,EACN,gBAAgB,EAAE,MAAM,UAAU,QAAQ,OAAO,UAAU,GAAG;AAAA,EAC9D,SAAS;AAAA,IACP,SAAS;AAAA,MACP,MAAM,CAAC,0BAA0B;AAAA,MACjC,WAAW,CAAC,wBAAwB;AAAA,IACtC;AAAA,EACF;AAAA,EACA,gBAAgB,EAAE,SAAS,EAAE,MAAM,mBAAmB,KAAK,gCAAgC,EAAE;AAAA,EAC7F,WAAW,EAAE,YAAY,EAAE,SAAS,6CAA6C,EAAE;AACrF,CAAC;AAiBD,IAAI,YAAgD,CAAC;AAG9C,SAAS,kBACd,MACA;AACA,cAAY;AACd;AAEO,SAAS,cAAyF;AACvG,SAAO;AACT;AAGO,IAAM,kBAAkB,CAAC,aAAa,eAAe,aAAa;;;AEhHzE,SAAS,YAA+B;AAMjC,SAAS,oBAAoB,OAAwB;AAC1D,SAAO,KAAK;AAAA,IAAU;AAAA,IAAO,CAAC,MAAM,MAClC,OAAO,MAAM,WAAW,EAAE,UAAU,EAAE,SAAS,EAAE,IAAI;AAAA,EACvD;AACF;AAGO,SAAS,sBAAyB,KAAgB;AACvD,SAAO,KAAK,MAAM,KAAK,CAAC,MAAM,MAAM;AAClC,QAAI,KAAK,OAAO,MAAM,YAAY,cAAc,KAAK,OAAO,EAAE,aAAa,UAAU;AACnF,aAAO,OAAO,EAAE,QAAQ;AAAA,IAC1B;AACA,WAAO;AAAA,EACT,CAAC;AACH;AAkBO,SAAS,cAAiB,MAA6C;AAC5E,QAAM,EAAE,KAAK,SAAS,YAAY,KAAK,WAAW,cAAc,KAAK,MAAM,IAAI;AAE/E,MAAI,WAAW;AACf,MAAI,OAAO,WAAW,aAAa;AACjC,QAAI;AACF,YAAM,MAAM,aAAa,QAAQ,GAAG;AACpC,UAAI,QAAQ,MAAM;AAChB,mBAAW,YAAY,GAAG;AAAA,MAC5B;AAAA,IACF,QAAQ;AAAA,IAER;AAAA,EACF;AAEA,QAAM,QAAQ,KAAQ,QAAQ;AAE9B,MAAI,OAAO,WAAW,aAAa;AACjC,UAAM,UAAU,CAAC,UAAa;AAC5B,UAAI;AACF,qBAAa,QAAQ,KAAK,UAAU,KAAK,CAAC;AAAA,MAC5C,QAAQ;AAAA,MAER;AAAA,IACF,CAAC;AAAA,EACH;AAEA,SAAO;AACT;;;AClEA,SAAS,gBAAgB;AAazB,IAAM,UAAU;AAET,IAAM,cAAc,cAA2B;AAAA,EACpD,KAAK;AAAA,EACL,SAAS,CAAC;AAAA,EACV,WAAW;AAAA,EACX,aAAa;AACf,CAAC;AAEM,IAAM,eAAe;AAAA,EAAS;AAAA,EAAa,CAAC,QACjD,IAAI,OAAO,CAAC,OAAkB,GAAG,WAAW,SAAS,EAAE;AACzD;AAEO,SAAS,MAAM,MAAqB,OAAe,SAAiB;AACzE,QAAM,WAAW,YAAY,IAAI;AACjC,MAAI,SAAS,KAAK,CAAC,OAAO,GAAG,SAAS,IAAI,EAAG;AAC7C,QAAM,QAAmB,EAAE,MAAM,OAAO,QAAQ,WAAW,WAAW,KAAK,IAAI,GAAG,QAAQ;AAC1F,cAAY,IAAI,CAAC,OAAO,GAAG,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;AACxD;AAEO,SAAS,SACd,MACA,QACA;AACA,cAAY;AAAA,IACV,YAAY,IAAI,EAAE;AAAA,MAAI,CAAC,OACrB,GAAG,SAAS,OAAO,EAAE,GAAG,IAAI,GAAG,OAAO,IAAI;AAAA,IAC5C;AAAA,EACF;AACF;AAEO,SAAS,WAAW;AACzB,cAAY,IAAI,CAAC,CAAC;AACpB;;;AC3CA,IAAM,qBAAqB,UAAU,mBAAmB,KAAK;AAC7D,IAAM,mBAAmB,UAAU,iBAAiB,KAAK,UAAU,kBAAkB,GAAG,MAAM,GAAG,EAAE,CAAC,KAAK;AAwBlG,IAAM,aAAa,cAA2B;AAAA,EACnD,KAAK;AAAA,EACL,SAAS;AAAA,IACP,aAAa;AAAA,IACb,WAAW;AAAA,IACX,kBAAkB;AAAA,EACpB;AACF,CAAC;AAEM,SAAS,YAAY,QAA8B;AACxD,aAAW,IAAI,EAAE,GAAG,WAAW,IAAI,GAAG,GAAG,OAAO,CAAC;AACnD;AAEO,SAAS,WAAwB;AACtC,SAAO,WAAW,IAAI;AACxB;;;AC3CA,SAAS,QAAAA,aAAY;AAId,IAAM,SAAS;AACf,IAAM,gBAAgB;AAEtB,IAAM,aAAaA,MAAY,UAAU,CAAC;AAE1C,SAAS,cAAc;AAC5B,SAAO,WAAW,IAAI,MAAM;AAC9B;AAEA,SAAS,YAAY;AACnB,MAAI,OAAO,WAAW,aAAa;AACjC,UAAM,YAAY,aAAa,QAAQ,MAAM;AAC7C,UAAM,OAAO,SAAS,cAAc,MAAM,GAAG,aAAa,YAAY;AACtE,WAAO,aAAc,QAAkB;AAAA,EACzC;AACA,SAAO;AACT;AAEO,SAAS,cAAc;AAC5B,QAAM,OAAO,WAAW,IAAI,MAAM,SAAS,UAAU;AACrD,aAAW,IAAI,IAAI;AACnB,eAAa,QAAQ,QAAQ,IAAI;AACjC,WAAS,cAAc,MAAM,GAAG,aAAa,cAAc,IAAI;AACjE;;;ACrBO,IAAM,gBAAgB;AAAA,EAC3B;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,QAAQ;AAAA,MACN,EAAE,MAAM,aAAa,MAAM,SAAS;AAAA,MACpC,EAAE,MAAM,OAAO,MAAM,QAAQ;AAAA,MAC7B,EAAE,MAAM,QAAQ,MAAM,QAAQ;AAAA,IAChC;AAAA,IACA,SAAS,CAAC,EAAE,MAAM,UAAU,MAAM,SAAS,CAAC;AAAA,IAC5C,iBAAiB;AAAA,EACnB;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,QAAQ;AAAA,MACN,EAAE,MAAM,aAAa,MAAM,UAAU,SAAS,KAAK;AAAA,MACnD,EAAE,MAAM,OAAO,MAAM,SAAS,SAAS,KAAK;AAAA,MAC5C,EAAE,MAAM,UAAU,MAAM,UAAU,SAAS,KAAK;AAAA,MAChD,EAAE,MAAM,UAAU,MAAM,WAAW,SAAS,MAAM;AAAA,MAClD,EAAE,MAAM,QAAQ,MAAM,SAAS,SAAS,MAAM;AAAA,IAChD;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,QAAQ;AAAA,MACN,EAAE,MAAM,aAAa,MAAM,UAAU,SAAS,KAAK;AAAA,MACnD,EAAE,MAAM,OAAO,MAAM,SAAS,SAAS,KAAK;AAAA,MAC5C,EAAE,MAAM,UAAU,MAAM,UAAU,SAAS,KAAK;AAAA,MAChD,EAAE,MAAM,YAAY,MAAM,WAAW,SAAS,MAAM;AAAA,MACpD,EAAE,MAAM,WAAW,MAAM,SAAS,SAAS,MAAM;AAAA,IACnD;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,QAAQ;AAAA,MACN,EAAE,MAAM,aAAa,MAAM,UAAU,SAAS,KAAK;AAAA,MACnD,EAAE,MAAM,UAAU,MAAM,UAAU,SAAS,KAAK;AAAA,MAChD,EAAE,MAAM,YAAY,MAAM,SAAS,SAAS,MAAM;AAAA,MAClD,EAAE,MAAM,UAAU,MAAM,WAAW,SAAS,MAAM;AAAA,MAClD,EAAE,MAAM,UAAU,MAAM,SAAS,SAAS,MAAM;AAAA,IAClD;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,QAAQ;AAAA,MACN,EAAE,MAAM,aAAa,MAAM,UAAU,SAAS,KAAK;AAAA,MACnD,EAAE,MAAM,UAAU,MAAM,UAAU,SAAS,KAAK;AAAA,IAClD;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,QAAQ;AAAA,MACN,EAAE,MAAM,aAAa,MAAM,UAAU,SAAS,KAAK;AAAA,MACnD,EAAE,MAAM,UAAU,MAAM,UAAU,SAAS,KAAK;AAAA,MAChD,EAAE,MAAM,YAAY,MAAM,WAAW,SAAS,KAAK;AAAA,MACnD,EAAE,MAAM,UAAU,MAAM,SAAS,SAAS,MAAM;AAAA,IAClD;AAAA,EACF;AACF;AAEO,IAAM,oBAAoB;AAAA,EAC/B;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,QAAQ;AAAA,MACN,EAAE,MAAM,eAAe,MAAM,SAAS;AAAA,MACtC,EAAE,MAAM,aAAa,MAAM,YAAY;AAAA,MACvC,EAAE,MAAM,UAAU,MAAM,QAAQ;AAAA,MAChC,EAAE,MAAM,oBAAoB,MAAM,YAAY;AAAA,MAC9C,EAAE,MAAM,OAAO,MAAM,SAAS;AAAA,MAC9B,EAAE,MAAM,gBAAgB,MAAM,UAAU;AAAA,MACxC,EAAE,MAAM,iBAAiB,MAAM,UAAU;AAAA,IAC3C;AAAA,IACA,SAAS,CAAC,EAAE,MAAM,aAAa,MAAM,SAAS,CAAC;AAAA,IAC/C,iBAAiB;AAAA,EACnB;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,QAAQ;AAAA,MACN,EAAE,MAAM,eAAe,MAAM,SAAS;AAAA,MACtC;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,YAAY;AAAA,UACV;AAAA,YACE,MAAM;AAAA,YACN,MAAM;AAAA,YACN,YAAY;AAAA,cACV,EAAE,MAAM,eAAe,MAAM,SAAS;AAAA,cACtC,EAAE,MAAM,aAAa,MAAM,SAAS;AAAA,cACpC,EAAE,MAAM,aAAa,MAAM,UAAU;AAAA,cACrC,EAAE,MAAM,aAAa,MAAM,SAAS;AAAA,cACpC,EAAE,MAAM,UAAU,MAAM,SAAS;AAAA,cACjC,EAAE,MAAM,mBAAmB,MAAM,QAAQ;AAAA,cACzC;AAAA,gBACE,MAAM;AAAA,gBACN,MAAM;AAAA,gBACN,YAAY;AAAA,kBACV;AAAA,oBACE,MAAM;AAAA,oBACN,MAAM;AAAA,oBACN,YAAY;AAAA,sBACV,EAAE,MAAM,QAAQ,MAAM,QAAQ;AAAA,sBAC9B,EAAE,MAAM,SAAS,MAAM,UAAU;AAAA,oBACnC;AAAA,kBACF;AAAA,kBACA,EAAE,MAAM,eAAe,MAAM,SAAS;AAAA,gBACxC;AAAA,cACF;AAAA,cACA;AAAA,gBACE,MAAM;AAAA,gBACN,MAAM;AAAA,gBACN,YAAY;AAAA,kBACV,EAAE,MAAM,QAAQ,MAAM,QAAQ;AAAA,kBAC9B,EAAE,MAAM,SAAS,MAAM,SAAS;AAAA,gBAClC;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,UACA,EAAE,MAAM,aAAa,MAAM,QAAQ;AAAA,UACnC,EAAE,MAAM,YAAY,MAAM,UAAU;AAAA,QACtC;AAAA,MACF;AAAA,MACA,EAAE,MAAM,UAAU,MAAM,QAAQ;AAAA,MAChC,EAAE,MAAM,oBAAoB,MAAM,YAAY;AAAA,MAC9C,EAAE,MAAM,OAAO,MAAM,SAAS;AAAA,IAChC;AAAA,IACA,SAAS,CAAC,EAAE,MAAM,aAAa,MAAM,SAAS,CAAC;AAAA,IAC/C,iBAAiB;AAAA,EACnB;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,QAAQ,CAAC,EAAE,MAAM,aAAa,MAAM,SAAS,CAAC;AAAA,IAC9C,SAAS;AAAA,MACP;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,YAAY;AAAA,UACV,EAAE,MAAM,eAAe,MAAM,SAAS;AAAA,UACtC,EAAE,MAAM,SAAS,MAAM,UAAU;AAAA,UACjC,EAAE,MAAM,aAAa,MAAM,SAAS;AAAA,UACpC,EAAE,MAAM,OAAO,MAAM,SAAS;AAAA,UAC9B,EAAE,MAAM,gBAAgB,MAAM,SAAS;AAAA,UACvC,EAAE,MAAM,iBAAiB,MAAM,SAAS;AAAA,UACxC,EAAE,MAAM,iBAAiB,MAAM,SAAS;AAAA,UACxC,EAAE,MAAM,gBAAgB,MAAM,SAAS;AAAA,UACvC,EAAE,MAAM,gBAAgB,MAAM,SAAS;AAAA,UACvC,EAAE,MAAM,cAAc,MAAM,QAAQ;AAAA,UACpC,EAAE,MAAM,WAAW,MAAM,QAAQ;AAAA,UACjC,EAAE,MAAM,UAAU,MAAM,QAAQ;AAAA,QAClC;AAAA,MACF;AAAA,IACF;AAAA,IACA,iBAAiB;AAAA,EACnB;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,QAAQ,CAAC,EAAE,MAAM,aAAa,MAAM,SAAS,CAAC;AAAA,IAC9C,SAAS,CAAC,EAAE,MAAM,IAAI,MAAM,OAAO,CAAC;AAAA,IACpC,iBAAiB;AAAA,EACnB;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,QAAQ,CAAC,EAAE,MAAM,aAAa,MAAM,SAAS,CAAC;AAAA,IAC9C,SAAS,CAAC,EAAE,MAAM,IAAI,MAAM,YAAY,CAAC;AAAA,IACzC,iBAAiB;AAAA,EACnB;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,QAAQ;AAAA,MACN,EAAE,MAAM,aAAa,MAAM,SAAS;AAAA,MACpC,EAAE,MAAM,UAAU,MAAM,UAAU;AAAA,IACpC;AAAA,IACA,SAAS,CAAC,EAAE,MAAM,IAAI,MAAM,OAAO,CAAC;AAAA,IACpC,iBAAiB;AAAA,EACnB;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,QAAQ;AAAA,MACN,EAAE,MAAM,aAAa,MAAM,UAAU,SAAS,KAAK;AAAA,MACnD,EAAE,MAAM,eAAe,MAAM,UAAU,SAAS,KAAK;AAAA,MACrD,EAAE,MAAM,aAAa,MAAM,WAAW,SAAS,KAAK;AAAA,IACtD;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,QAAQ;AAAA,MACN,EAAE,MAAM,aAAa,MAAM,UAAU,SAAS,KAAK;AAAA,MACnD,EAAE,MAAM,aAAa,MAAM,UAAU,SAAS,KAAK;AAAA,MACnD,EAAE,MAAM,eAAe,MAAM,UAAU,SAAS,KAAK;AAAA,IACvD;AAAA,EACF;AACF;AAEO,IAAM,qBAAqB;AAAA,EAChC;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,QAAQ,CAAC,EAAE,MAAM,eAAe,MAAM,SAAS,CAAC;AAAA,IAChD,SAAS,CAAC,EAAE,MAAM,IAAI,MAAM,UAAU,CAAC;AAAA,IACvC,iBAAiB;AAAA,EACnB;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,QAAQ;AAAA,MACN,EAAE,MAAM,eAAe,MAAM,SAAS;AAAA,MACtC,EAAE,MAAM,YAAY,MAAM,UAAU;AAAA,IACtC;AAAA,IACA,SAAS,CAAC,EAAE,MAAM,IAAI,MAAM,OAAO,CAAC;AAAA,IACpC,iBAAiB;AAAA,EACnB;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,QAAQ;AAAA,MACN,EAAE,MAAM,eAAe,MAAM,SAAS;AAAA,MACtC,EAAE,MAAM,YAAY,MAAM,UAAU;AAAA,IACtC;AAAA,IACA,SAAS;AAAA,MACP;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,YAAY;AAAA,UACV,EAAE,MAAM,kBAAkB,MAAM,QAAQ;AAAA,UACxC,EAAE,MAAM,cAAc,MAAM,SAAS;AAAA,QACvC;AAAA,MACF;AAAA,IACF;AAAA,IACA,iBAAiB;AAAA,EACnB;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,QAAQ;AAAA,MACN,EAAE,MAAM,eAAe,MAAM,UAAU,SAAS,KAAK;AAAA,MACrD,EAAE,MAAM,YAAY,MAAM,WAAW,SAAS,KAAK;AAAA,MACnD,EAAE,MAAM,kBAAkB,MAAM,SAAS,SAAS,MAAM;AAAA,MACxD,EAAE,MAAM,cAAc,MAAM,UAAU,SAAS,MAAM;AAAA,IACvD;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,QAAQ;AAAA,MACN,EAAE,MAAM,eAAe,MAAM,UAAU,SAAS,KAAK;AAAA,MACrD,EAAE,MAAM,YAAY,MAAM,WAAW,SAAS,KAAK;AAAA,IACrD;AAAA,EACF;AACF;;;AC3QA,SAAS,oBAAoB,YAAY;AAEzC,SAAS,QAAAC,aAAY;AAKrB,IAAM,iBAAiB,OAAO,UAAU,eAAe,KAAK,YAAY,EAAE;AAEnE,IAAM,uBAAuB,cAAsB;AAAA,EACxD,KAAK;AAAA,EACL,SAAS;AACX,CAAC;AAED,IAAM,cAAc,oBAAI,IAA0B;AAElD,SAAS,2BAAmC;AAC1C,QAAM,WAAW,YAAY;AAC7B,MAAI,SAAS,cAAc,EAAG,QAAO;AAErC,aAAW,CAAC,SAAS,GAAG,KAAK,OAAO,QAAQ,QAAQ,GAAG;AACrD,QACE,KAAK,eAAe,WACpB,KAAK,UAAU,kBACf,KAAK,OAAO,SAAS,gBACrB;AACA,aAAO,OAAO,OAAO;AAAA,IACvB;AAAA,EACF;AAEA,QAAM,CAAC,eAAe,IAAI,OAAO,KAAK,QAAQ;AAC9C,SAAO,kBAAkB,OAAO,eAAe,IAAI;AACrD;AAEA,SAAS,yBAAyB,SAAyB;AACzD,QAAM,WAAW,YAAY;AAC7B,MAAI,CAAC,OAAO,KAAK,QAAQ,EAAE,OAAQ,QAAO;AAC1C,SAAO,SAAS,OAAO,IAAI,UAAU,yBAAyB;AAChE;AAEO,SAAS,0BAAkC;AAChD,QAAM,aAAa,yBAAyB,qBAAqB,IAAI,CAAC;AACtE,MAAI,eAAe,qBAAqB,IAAI,GAAG;AAC7C,yBAAqB,IAAI,UAAU;AAAA,EACrC;AACA,SAAO;AACT;AAEA,SAAS,kBAAkB,SAA+B;AACxD,QAAM,oBAAoB,yBAAyB,OAAO;AAE1D,QAAM,SAAS,YAAY,IAAI,iBAAiB;AAChD,MAAI,OAAQ,QAAO;AACnB,QAAM,WAAW,YAAY;AAC7B,QAAM,MAAM,SAAS,iBAAiB;AACtC,MAAI,CAAC,KAAK;AACR,UAAM,WAAW,SAAS,yBAAyB,CAAC;AACpD,QAAI,CAAC,UAAU;AACb,aAAO,mBAAmB,EAAE,OAAO,aAAa,WAAW,KAAK,EAAE,CAAC;AAAA,IACrE;AACA,WAAO,mBAAmB,EAAE,OAAO,SAAS,OAAO,WAAW,KAAK,SAAS,MAAM,EAAE,CAAC;AAAA,EACvF;AACA,QAAM,SAAS,mBAAmB,EAAE,OAAO,IAAI,OAAO,WAAW,KAAK,IAAI,MAAM,EAAE,CAAC;AACnF,cAAY,IAAI,mBAAmB,MAAM;AACzC,SAAO;AACT;AAEO,IAAM,oBAAoBC,MAAmB,kBAAkB,wBAAwB,CAAC,CAAC;AAEhG,qBAAqB,UAAU,CAAC,YAAoB;AAClD,QAAM,aAAa,yBAAyB,OAAO;AACnD,MAAI,eAAe,SAAS;AAC1B,yBAAqB,IAAI,UAAU;AACnC;AAAA,EACF;AACA,oBAAkB,IAAI,kBAAkB,UAAU,CAAC;AACrD,CAAC;AAEM,SAAS,kBAAgC;AAC9C,0BAAwB;AACxB,SAAO,kBAAkB,IAAI;AAC/B;AAEO,IAAM,eAAe,IAAI,MAAM,CAAC,GAAmB;AAAA,EACxD,IAAI,SAAS,MAAM;AACjB,UAAM,SAAS,kBAAkB,wBAAwB,CAAC;AAC1D,UAAM,QAAS,OAAe,IAAI;AAClC,WAAO,OAAO,UAAU,aAAa,MAAM,KAAK,MAAM,IAAI;AAAA,EAC5D;AACF,CAAC;AAEM,SAAS,eAA2D;AACzE,QAAM,WAAW,YAAe;AAChC,QAAM,kBAAkB,wBAAwB;AAChD,QAAM,MAAM,SAAS,eAAe;AACpC,SAAO,KAAK,aAAa,SAAS,yBAAyB,CAAC,GAAG,aAAa,CAAC;AAC/E;;;AChGA,SAAS,2BAA2B;AAY7B,SAAS,cACd,KACA,YACA,SACe;AACf,MAAI,IAAI,eAAe;AACrB,WAAO,IAAI,cAAc,YAAY,OAAO;AAAA,EAC9C;AAEA,QAAM,UAA4C,CAAC;AACnD,QAAM,SAAoB,CAAC;AAG3B,MAAI,IAAI,eAAe;AACrB,eAAW,MAAM,IAAI,eAAe;AAClC,cAAQ,KAAK,EAAE,MAAM,GAAG,SAAS,MAAM,GAAG,QAAQ,CAAC;AACnD,aAAO,KAAK,YAAY,UAAU,GAAG,OAAO,GAAG,GAAG,OAAO,CAAC;AAAA,IAC5D;AAAA,EACF;AAGA,aAAW,SAAS,IAAI,QAAQ;AAC9B,QAAI,CAAC,MAAM,QAAS;AACpB,YAAQ,KAAK,EAAE,MAAM,MAAM,YAAY,MAAM,MAAM,MAAM,MAAM,QAAQ,CAAC;AACxE,WAAO,KAAK,YAAY,WAAW,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC;AAAA,EAChE;AAEA,SAAO,oBAAoB,SAAS,MAAM;AAC5C;AAEA,SAAS,YAAY,OAAgB,SAA0B;AAC7D,UAAQ,SAAS;AAAA,IACf,KAAK;AACH,aAAO,QAAQ,KAAK;AAAA,IACtB,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACH,aAAO,OAAO,KAAK,KAAK;AAAA,IAC1B,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACH,aAAO,OAAO,OAAO,KAAK,KAAK,CAAC;AAAA,IAClC,KAAK;AACH,aAAO,OAAO,SAAS,EAAE;AAAA,IAC3B,KAAK;AACH,UAAI,MAAM,QAAQ,KAAK,EAAG,QAAO,MAAM,IAAI,MAAM;AACjD,aAAO,OAAO,SAAS,EAAE,EAAE,MAAM,IAAI,EAAE,OAAO,OAAO;AAAA,IACvD,KAAK;AACH,UAAI,MAAM,QAAQ,KAAK,EAAG,QAAO;AACjC,aAAO,OAAO,SAAS,EAAE,EACtB,MAAM,IAAI,EACV,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,EACnB,OAAO,CAAC,MAAM,sBAAsB,KAAK,CAAC,CAAC;AAAA,IAChD;AACE,aAAO;AAAA,EACX;AACF;;;ACpEA,SAAS,UAAU,aAAa,WAAW,eAAe;AAW1D,SAAS,cAAc,KAA6C;AAClE,QAAM,OAAgC,CAAC;AACvC,aAAW,KAAK,IAAI,QAAQ;AAC1B,QAAI,EAAE,SAAU;AAChB,QAAI,EAAE,iBAAiB,QAAW;AAChC,WAAK,EAAE,IAAI,IAAI,EAAE;AAAA,IACnB,WAAW,EAAE,SAAS,WAAW;AAC/B,WAAK,EAAE,IAAI,IAAI;AAAA,IACjB,WAAW,EAAE,SAAS,UAAU;AAC9B,WAAK,EAAE,IAAI,IAAI,EAAE,OAAO;AAAA,IAC1B,OAAO;AACL,WAAK,EAAE,IAAI,IAAI;AAAA,IACjB;AAAA,EACF;AACA,SAAO;AACT;AAEO,SAAS,WAAW,KAAyC;AAClE,QAAM,WAAW,QAAQ,MAAO,MAAM,cAAc,GAAG,IAAI,CAAC,GAAI,CAAC,GAAG,CAAC;AACrE,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAkC,QAAQ;AACtE,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAiC,CAAC,CAAC;AAG/D,YAAU,MAAM;AACd,cAAU,QAAQ;AAClB,cAAU,CAAC,CAAC;AAAA,EACd,GAAG,CAAC,QAAQ,CAAC;AAEb,QAAM,WAAW,YAAY,CAAC,MAAc,UAAmB;AAC7D,cAAU,CAAC,UAAU,EAAE,GAAG,MAAM,CAAC,IAAI,GAAG,MAAM,EAAE;AAChD,cAAU,CAAC,SAAS;AAClB,UAAI,CAAC,KAAK,IAAI,EAAG,QAAO;AACxB,YAAM,OAAO,EAAE,GAAG,KAAK;AACvB,aAAO,KAAK,IAAI;AAChB,aAAO;AAAA,IACT,CAAC;AAAA,EACH,GAAG,CAAC,CAAC;AAEL,QAAM,WAAW,YAAY,MAAe;AAC1C,QAAI,CAAC,IAAK,QAAO;AACjB,UAAM,OAA+B,CAAC;AACtC,eAAW,KAAK,IAAI,QAAQ;AAC1B,UAAI,EAAE,SAAU;AAChB,YAAM,IAAI,OAAO,EAAE,IAAI;AACvB,UAAI,EAAE,aAAa,MAAM,UAAa,MAAM,QAAQ,MAAM,KAAK;AAC7D,aAAK,EAAE,IAAI,IAAI,GAAG,EAAE,KAAK;AACzB;AAAA,MACF;AACA,UAAI,EAAE,SAAS,YAAY,OAAO,MAAM,UAAU;AAChD,YAAI,EAAE,OAAO,QAAQ,IAAI,EAAE,KAAK;AAC9B,eAAK,EAAE,IAAI,IAAI,GAAG,EAAE,KAAK,qBAAqB,EAAE,GAAG;AAAA,QACrD,WAAW,EAAE,OAAO,QAAQ,IAAI,EAAE,KAAK;AACrC,eAAK,EAAE,IAAI,IAAI,GAAG,EAAE,KAAK,oBAAoB,EAAE,GAAG;AAAA,QACpD;AAAA,MACF;AAAA,IACF;AACA,cAAU,IAAI;AACd,WAAO,OAAO,KAAK,IAAI,EAAE,WAAW;AAAA,EACtC,GAAG,CAAC,KAAK,MAAM,CAAC;AAEhB,QAAM,QAAQ,YAAY,MAAM;AAC9B,cAAU,QAAQ;AAClB,cAAU,CAAC,CAAC;AAAA,EACd,GAAG,CAAC,QAAQ,CAAC;AAEb,SAAO,EAAE,QAAQ,QAAQ,UAAU,UAAU,MAAM;AACrD;;;AC7EA,SAAS,YAAAC,WAAU,aAAAC,YAAW,eAAAC,oBAAmB;AAEjD,SAAS,UAAU,YAAY,aAAa;AA0D5C,IAAM,iBAAiB;AACvB,IAAM,cAAc;AACpB,IAAM,sBAAsB;AAAA,EAC1B,KAAK;AAAA,EACL,UAAU;AAAA,EACV,WAAW;AAAA,EACX,iBAAiB;AAAA,EACjB,kBAAkB;AAAA,EAClB,KAAK;AACP;AACA,IAAM,eAAe;AACrB,IAAM,gCAAgC;AAAA,EACpC,EAAE,MAAM,OAAO,OAAO,EAAE;AAAA,EACxB,EAAE,MAAM,YAAY,OAAO,KAAK;AAAA,EAChC,EAAE,MAAM,aAAa,OAAO,MAAM;AACpC;AAEA,SAAS,OAAO,MAA8B;AAC5C,SAAO,WAAW,MAAM,OAAO;AACjC;AAEA,SAAS,kBAAkB,aAAqB,WAA+B;AAC7E,QAAM,QAAQ,IAAI,WAAW,EAAE;AAC/B,QAAM,OAAO,IAAI,SAAS,MAAM,MAAM;AACtC,OAAK,aAAa,GAAG,aAAa,KAAK;AACvC,OAAK,aAAa,GAAG,WAAW,KAAK;AACrC,SAAO,OAAO,KAAK;AACrB;AAEA,SAAS,gBAAgB,MAAkB,YAA6B;AACtE,QAAM,YAAY,KAAK,MAAM,aAAa,CAAC;AAC3C,QAAM,WAAW,aAAa;AAC9B,WAAS,IAAI,GAAG,IAAI,WAAW,KAAK;AAClC,QAAI,KAAK,CAAC,MAAM,EAAG,QAAO;AAAA,EAC5B;AACA,MAAI,WAAW,GAAG;AAChB,UAAM,OAAO,OAAS,IAAI;AAC1B,SAAK,KAAK,SAAS,IAAI,UAAU,EAAG,QAAO;AAAA,EAC7C;AACA,SAAO;AACT;AAEA,eAAsB,SACpB,aACA,WACiE;AACjE,QAAM,YAAY,kBAAkB,aAAa,SAAS;AAC1D,QAAM,MAAM,IAAI,WAAW,UAAU,SAAS,CAAC;AAC/C,MAAI,IAAI,WAAW,CAAC;AACpB,QAAM,OAAO,IAAI,SAAS,IAAI,MAAM;AAEpC,WAAS,QAAQ,GAAG,QAAQ,YAAe,SAAS;AAClD,SAAK,aAAa,UAAU,QAAQ,OAAO,KAAK,GAAG,KAAK;AACxD,UAAM,OAAO,OAAO,GAAG;AACvB,QAAI,gBAAgB,MAAM,cAAc,GAAG;AAEzC,YAAM,QAAQ,IAAI,WAAW,IAAI,KAAK,CAAC;AACvC,YAAM,KAAK,IAAI,SAAS,MAAM,MAAM;AACpC,SAAG,aAAa,GAAG,KAAK,IAAI;AAC5B,YAAM,IAAI,MAAM,CAAC;AACjB,SAAG,aAAa,IAAI,OAAO,KAAK,GAAG,IAAI;AACvC,aAAO,EAAE,MAAM,OAAO,MAAM;AAAA,IAC9B;AAEA,QAAI,QAAQ,QAAS,KAAK,QAAQ,GAAG;AACnC,YAAM,IAAI,QAAQ,CAAC,MAAM,WAAW,GAAG,CAAC,CAAC;AAAA,IAC3C;AAAA,EACF;AACA,QAAM,IAAI,MAAM,4BAA4B;AAC9C;AAEO,SAAS,WAAW,WAA2B;AAEpD,QAAM,MAAM,OAAO,SAAS,IAAI;AAChC,MAAI,QAAQ,EAAG,QAAO;AACtB,MAAI,MAAM,KAAO,QAAO,IAAI,MAAM,KAAW,QAAQ,CAAC,CAAC;AACvD,MAAI,MAAM,KAAM,QAAO,IAAI,MAAM,KAAM,QAAQ,CAAC,CAAC;AACjD,MAAI,MAAM,IAAM,QAAO,GAAG,IAAI,QAAQ,CAAC,CAAC;AACxC,SAAO,GAAG,IAAI,eAAe,QAAW,EAAE,uBAAuB,EAAE,CAAC,CAAC;AACvE;AAEA,SAAS,qBAAqB,YAA6B;AACzD,SAAO,aAAa,IAAI;AAC1B;AAEA,SAAS,iBAAiB,MAAsB;AAC9C,QAAM,SAAS,oBAAoB,IAAwC;AAC3E,MAAI,WAAW,QAAW;AACxB,UAAM,IAAI,MAAM,uCAAuC,IAAI,EAAE;AAAA,EAC/D;AACA,SAAO;AACT;AAEA,SAAS,0BAA0B,IAA6B;AAC9D,SAAO;AAAA,IACL,OAAO;AAAA,MACL,MAAM,GAAG,OAAO,QAAQ;AAAA,MACxB,OAAQ,GAAG,OAAO,SAAS;AAAA,IAC7B;AAAA,IACA,aAAa,GAAG,gBAAgB;AAAA,EAClC;AACF;AAEA,SAAS,0BAA0B,UAAmC;AACpE,SAAO;AAAA,IACL,MAAM,iBAAiB,OAAO,SAAS,QAAQ,KAAK,CAAC;AAAA,IACrD,OAAO,OAAO,SAAS,SAAS,CAAC;AAAA,EACnC;AACF;AAIO,SAAS,UACd,WACA,aACA,WACA,SACA,aAAa,OACI;AACjB,QAAM,CAAC,QAAQ,SAAS,IAAIC,UAA0B,CAAC,CAAC;AACxD,QAAM,CAAC,WAAW,YAAY,IAAIA,UAAS,KAAK;AAChD,QAAM,CAAC,cAAc,eAAe,IAAIA,UAAS,KAAK;AACtD,QAAM,CAAC,QAAQ,SAAS,IAAIA,UAA+B,oBAAI,IAAI,CAAC;AACpE,QAAM,CAAC,UAAU,WAAW,IAAIA,UAAS,CAAC;AAE1C,QAAM,UAAUC,aAAY,MAAM,YAAY,CAAC,MAAM,IAAI,CAAC,GAAG,CAAC,CAAC;AAE/D,EAAAC,WAAU,MAAM;AACd,QAAI,CAAC,WAAW,UAAU,WAAW,GAAG;AAEtC,gBAAU,CAAC,SAAU,KAAK,WAAW,IAAI,OAAO,CAAC,CAAE;AACnD,gBAAU,CAAC,SAAU,KAAK,SAAS,IAAI,OAAO,oBAAI,IAAI,CAAE;AACxD;AAAA,IACF;AAEA,QAAI,YAAY;AAChB,iBAAa,IAAI;AACjB,oBAAgB,IAAI;AACpB,cAAU,CAAC,CAAC;AACZ,cAAU,oBAAI,IAAI,CAAC;AAEnB,mBAAe,cAAc;AAC3B,YAAM,UAA2B,CAAC;AAClC,YAAM,OAAO,oBAAI,IAAqB;AAEtC,YAAM,WAAW,UAAU,IAAI,OAAO,OAAO;AAC3C,YAAI;AACF,cAAI,CAAC,GAAG,WAAY,OAAM,IAAI,MAAM,2BAA2B;AAE/D,gBAAMC,UAAS,mBAAmB,GAAG,UAAU;AAC/C,gBAAM,YAAY,OAAO,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI,CAAC;AAGtD,cAAI,CAAC,UAAW,iBAAgB,IAAI;AACpC,gBAAM,EAAE,MAAM,IAAI,MAAM,SAAS,aAAa,SAAS;AACvD,cAAI,CAAC,UAAW,iBAAgB,KAAK;AAKrC,gBAAM,WAAW,MAAM,uBAAuBA,SAAQ;AAAA,YACpD;AAAA,YACA;AAAA,YACA,aAAa;AAAA,YACb,oBAAoB;AAAA,YACpB;AAAA,UACF,CAAC;AAED,cAAI,CAAC,SAAU,OAAM,IAAI,MAAM,iCAAiC;AAEhE,cAAI,CAAC,UAAW,SAAQ,KAAK,QAAQ;AAAA,QACvC,SAAS,KAAK;AACZ,cAAI,CAAC,WAAW;AACd,iBAAK,IAAI,GAAG,SAAS,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,UACvE;AAAA,QACF;AAAA,MACF,CAAC;AAED,YAAM,QAAQ,WAAW,QAAQ;AAEjC,UAAI,CAAC,WAAW;AACd,kBAAU,OAAO;AACjB,kBAAU,IAAI;AACd,qBAAa,KAAK;AAClB,wBAAgB,KAAK;AAAA,MACvB;AAAA,IACF;AAEA,gBAAY;AACZ,WAAO,MAAM;AACX,kBAAY;AAAA,IACd;AAAA,EACF,GAAG,CAAC,WAAW,aAAa,WAAW,SAAS,UAAU,UAAU,CAAC;AAErE,QAAM,YAAY,OAAO,OAAO,CAAC,KAAK,MAAM,MAAM,EAAE,WAAW,EAAE;AAEjE,SAAO,EAAE,QAAQ,WAAW,cAAc,QAAQ,WAAW,QAAQ;AACvE;AAOA,eAAe,uBACbA,SACA,QAO+B;AAE/B,MAAI;AACF,UAAM,WAAW,MAAM,MAAM,GAAGA,OAAM,kBAAkB;AAAA,MACtD,QAAQ;AAAA,MACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,MAC9C,MAAM,KAAK,UAAU;AAAA,QACnB,cAAc,OAAO,OAAO,WAAW;AAAA,QACvC,YAAY,OAAO,OAAO,SAAS;AAAA,QACnC,eAAe,MAAM,OAAO,WAAW;AAAA,QACvC,qBAAqB,OAAO,OAAO,kBAAkB;AAAA,QACrD,aAAa,OAAO;AAAA,QACpB,uBAAuB;AAAA,MACzB,CAAC;AAAA,MACD,QAAQ,YAAY,QAAQ,GAAM;AAAA,IACpC,CAAC;AAED,QAAI,CAAC,SAAS,GAAI,OAAM,IAAI,MAAM,QAAQ,SAAS,MAAM,EAAE;AAC3D,UAAM,OAAO,MAAM,SAAS,KAAK;AAEjC,WAAO;AAAA,MACL,UAAU,KAAK;AAAA,MACf,WAAW,OAAO,KAAK,cAAc,GAAG;AAAA,MACxC,WAAY,KAAK,aAAa;AAAA,MAC9B,UAAU,OAAO,KAAK,aAAa,CAAC;AAAA,MACpC,aAAa,QAAQ,KAAK,YAAY;AAAA,MACtC,aAAa,KAAK,gBAAgB;AAAA,MAClC,SAAS;AAAA,QACP,aAAa,OAAO,KAAK,SAAS,gBAAgB,OAAO,WAAW;AAAA,QACpE,WAAW,OAAO,KAAK,SAAS,cAAc,OAAO,SAAS;AAAA,QAC9D,WAAW,OAAO,KAAK,SAAS,cAAc,GAAG;AAAA,QACjD,WAAW,OAAO,KAAK,SAAS,aAAa,OAAO,kBAAkB;AAAA,QACtE,QAAQ,OAAO,KAAK,SAAS,UAAU,GAAG;AAAA,QAC1C,iBAAiB,OAAO,KAAK,SAAS,mBAAmB,qBAAqB,OAAO,UAAU,CAAC;AAAA,QAChG,sBAAsB,KAAK,SAAS,wBAAwB,CAAC,GAAG,IAAI,yBAAyB;AAAA,QAC7F,sBAAsB,KAAK,SAAS,aAAa,CAAC,GAAG,IAAI,yBAAyB;AAAA,MACpF;AAAA,IACF;AAAA,EACF,QAAQ;AAEN,WAAO;AAAA,EACT;AACF;;;AC3TA,SAAS,YAAAC,WAAU,aAAAC,YAAW,eAAAC,cAAa,cAAc;AAEzD,SAAS,SAAAC,cAAa;AAqCtB,SAASC,oBAAmB,KAAqB;AAC/C,MAAI,OAAO,WAAW,YAAa,QAAO;AAC1C,QAAM,YAAY,IAAI,SAAS,KAAK,IAAI,MAAM,UAAU,GAAG;AAC3D,MAAI;AACF,UAAM,MAAM,IAAI,IAAI,SAAS;AAC7B,UAAM,WAAW,OAAO,SAAS;AACjC,UAAM,gBACJ,IAAI,SAAS,SAAS,QAAQ,KAC9B,CAAC,IAAI,SAAS,SAAS,GAAG,KAC1B,IAAI,aAAa,eACjB,IAAI,aAAa;AACnB,QAAI,iBAAiB,aAAa,IAAI,UAAU;AAC9C,UAAI,WAAW;AAAA,IACjB;AACA,WAAO,IAAI,SAAS,EAAE,QAAQ,OAAO,EAAE;AAAA,EACzC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAIO,SAAS,YACd,gBACA,WACA,UACA,aACA,SACmB;AACnB,QAAM,CAAC,OAAO,QAAQ,IAAIC,UAA0B,IAAI;AACxD,QAAM,CAAC,WAAW,YAAY,IAAIA,UAAS,KAAK;AAChD,QAAM,CAAC,cAAc,eAAe,IAAIA,UAAS,KAAK;AACtD,QAAM,CAAC,OAAO,QAAQ,IAAIA,UAAwB,IAAI;AACtD,QAAM,CAAC,UAAU,WAAW,IAAIA,UAAS,CAAC;AAC1C,QAAM,eAAe,OAAO,KAAK;AAEjC,QAAM,UAAUC,aAAY,MAAM,YAAY,CAAC,MAAM,IAAI,CAAC,GAAG,CAAC,CAAC;AAE/D,EAAAC,WAAU,MAAM;AACd,QAAI,CAAC,WAAW,CAAC,kBAAkB,cAAc,IAAI;AACnD,eAAS,IAAI;AACb,eAAS,IAAI;AACb;AAAA,IACF;AAEA,iBAAa,UAAU;AACvB,iBAAa,IAAI;AACjB,aAAS,IAAI;AACb,aAAS,IAAI;AAEb,mBAAe,gBAAgB;AAC7B,UAAI;AACF,cAAMC,UAASJ,oBAAmB,cAAe;AACjD,cAAM,YAAY,OAAO,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI,CAAC;AAGtD,wBAAgB,IAAI;AACpB,cAAM,EAAE,MAAM,IAAI,MAAM,SAAS,aAAa,SAAS;AACvD,YAAI,aAAa,QAAS;AAC1B,wBAAgB,KAAK;AAGrB,cAAM,WAAW,MAAM,MAAM,GAAGI,OAAM,sBAAsB;AAAA,UAC1D,QAAQ;AAAA,UACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,UAC9C,MAAM,KAAK,UAAU;AAAA,YACnB,YAAY,OAAO,SAAS;AAAA,YAC5B,WAAW;AAAA,YACX,eAAeC,OAAM,KAAK;AAAA,YAC1B,qBAAqB,OAAO,SAAS;AAAA,UACvC,CAAC;AAAA,UACD,QAAQ,YAAY,QAAQ,GAAM;AAAA,QACpC,CAAC;AAED,YAAI,CAAC,SAAS,IAAI;AAChB,gBAAM,IAAI,MAAM,QAAQ,SAAS,MAAM,KAAK,MAAM,SAAS,KAAK,EAAE,MAAM,MAAM,eAAe,CAAC,EAAE;AAAA,QAClG;AAEA,cAAM,OAAO,MAAM,SAAS,KAAK;AACjC,YAAI,aAAa,QAAS;AAE1B,iBAAS;AAAA,UACP,WAAW,OAAO,KAAK,cAAc,SAAS;AAAA,UAC9C,UAAU,KAAK,aAAa;AAAA,UAC5B,OAAO,OAAO,KAAK,SAAS,GAAG;AAAA,UAC/B,WAAW,OAAO,KAAK,aAAa,SAAS;AAAA,UAC7C,QAAQ,OAAO,KAAK,UAAU,GAAG;AAAA,UACjC,WAAY,KAAK,aAAa;AAAA,UAC9B,iBAAiB,KAAK;AAAA,QACxB,CAAC;AAAA,MACH,SAAS,KAAK;AACZ,YAAI,CAAC,aAAa,SAAS;AACzB,mBAAS,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,QAC3D;AAAA,MACF,UAAE;AACA,YAAI,CAAC,aAAa,SAAS;AACzB,uBAAa,KAAK;AAClB,0BAAgB,KAAK;AAAA,QACvB;AAAA,MACF;AAAA,IACF;AAEA,kBAAc;AACd,WAAO,MAAM;AACX,mBAAa,UAAU;AAAA,IACzB;AAAA,EACF,GAAG,CAAC,gBAAgB,WAAW,UAAU,aAAa,SAAS,QAAQ,CAAC;AAExE,QAAM,iBAAiB,QAAQ,WAAW,MAAM,KAAK,IAAI;AAEzD,SAAO,EAAE,OAAO,WAAW,cAAc,OAAO,gBAAgB,QAAQ;AAC1E;AAuBO,SAAS,aACd,gBACA,WACA,aACA,YACA,SACoB;AACpB,QAAM,CAAC,QAAQ,SAAS,IAAIJ,UAA0B,CAAC,CAAC;AACxD,QAAM,CAAC,WAAW,YAAY,IAAIA,UAAS,KAAK;AAChD,QAAM,CAAC,OAAO,QAAQ,IAAIA,UAAwB,IAAI;AACtD,QAAM,CAAC,UAAU,WAAW,IAAIA,UAAS,CAAC;AAE1C,QAAM,UAAUC,aAAY,MAAM,YAAY,CAAC,MAAM,IAAI,CAAC,GAAG,CAAC,CAAC;AAE/D,EAAAC,WAAU,MAAM;AACd,QAAI,CAAC,WAAW,CAAC,kBAAkB,cAAc,MAAM,WAAW,WAAW,GAAG;AAC9E,gBAAU,CAAC,CAAC;AACZ,eAAS,IAAI;AACb;AAAA,IACF;AAEA,QAAI,YAAY;AAChB,iBAAa,IAAI;AACjB,aAAS,IAAI;AAEb,mBAAe,iBAAiB;AAC9B,UAAI;AACF,cAAMC,UAASJ,oBAAmB,cAAe;AACjD,cAAM,YAAY,OAAO,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI,CAAC;AACtD,cAAM,EAAE,MAAM,IAAI,MAAM,SAAS,aAAa,SAAS;AACvD,YAAI,UAAW;AAGf,cAAM,UAAU,MAAM,QAAQ;AAAA,UAC5B,WAAW,IAAI,OAAO,QAAQ;AAC5B,kBAAM,WAAW,MAAM,MAAM,GAAGI,OAAM,sBAAsB;AAAA,cAC1D,QAAQ;AAAA,cACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,cAC9C,MAAM,KAAK,UAAU;AAAA,gBACnB,YAAY,OAAO,SAAS;AAAA,gBAC5B,WAAW,IAAI;AAAA,gBACf,eAAeC,OAAM,KAAK;AAAA,gBAC1B,qBAAqB,OAAO,SAAS;AAAA,cACvC,CAAC;AAAA,cACD,QAAQ,YAAY,QAAQ,GAAM;AAAA,YACpC,CAAC;AAED,gBAAI,CAAC,SAAS,GAAI,QAAO;AACzB,mBAAO,SAAS,KAAK;AAAA,UACvB,CAAC;AAAA,QACH;AAEA,YAAI,UAAW;AAEf,cAAM,UAA2B,WAAW,IAAI,CAAC,KAAK,MAAM;AAC1D,gBAAM,SAAS,QAAQ,CAAC;AACxB,cAAI,OAAO,WAAW,eAAe,OAAO,OAAO;AACjD,kBAAM,OAAO,OAAO;AACpB,kBAAM,QAAQ,OAAO,KAAK,SAAS,GAAG;AACtC,mBAAO;AAAA,cACL,UAAU,IAAI;AAAA,cACd,SAAS,IAAI;AAAA,cACb;AAAA,cACA,gBAAgB,WAAW,KAAK;AAAA,cAChC,MAAO,KAAK,QAAQ;AAAA,cACpB,OAAO;AAAA,gBACL,WAAW,OAAO,KAAK,cAAc,SAAS;AAAA,gBAC9C,UAAU,IAAI;AAAA,gBACd;AAAA,gBACA,WAAW,OAAO,KAAK,aAAa,SAAS;AAAA,gBAC7C,QAAQ,OAAO,KAAK,UAAU,GAAG;AAAA,gBACjC,WAAY,KAAK,aAAa;AAAA,gBAC9B,iBAAiB,KAAK;AAAA,cACxB;AAAA,cACA,OAAO;AAAA,YACT;AAAA,UACF;AAEA,gBAAM,iBAAiB,OAAO,IAAI,UAAU,IAAI;AAChD,iBAAO;AAAA,YACL,UAAU,IAAI;AAAA,YACd,SAAS,IAAI;AAAA,YACb,OAAO;AAAA,YACP,gBAAgB,IAAI,WAAW,cAAc,CAAC;AAAA,YAC9C,MAAM;AAAA,YACN,OAAO;AAAA,YACP,OAAO;AAAA,UACT;AAAA,QACF,CAAC;AAED,kBAAU,OAAO;AAAA,MACnB,SAAS,KAAK;AACZ,YAAI,CAAC,WAAW;AACd,mBAAS,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,QAC3D;AAAA,MACF,UAAE;AACA,YAAI,CAAC,WAAW;AACd,uBAAa,KAAK;AAAA,QACpB;AAAA,MACF;AAAA,IACF;AAEA,mBAAe;AACf,WAAO,MAAM;AACX,kBAAY;AAAA,IACd;AAAA,EACF,GAAG,CAAC,gBAAgB,WAAW,aAAa,YAAY,SAAS,QAAQ,CAAC;AAE1E,SAAO,EAAE,QAAQ,WAAW,OAAO,QAAQ;AAC7C;;;AC1RA,SAAS,eAAAC,cAAa,YAAAC,WAAU,WAAAC,gBAAe;AAC/C,SAAS,YAAY,kBAAkB,oCAAoC;AAC3E,SAAS,sBAAsB;AAK/B,SAAS,aAAAC,kBAAiB;AAYnB,SAAS,eAAe;AAC7B,QAAM,EAAE,QAAQ,IAAI,WAAW;AAC/B,QAAM,EAAE,oBAAoB,MAAM,MAAM,WAAW,UAAU,IAAI,iBAAiB;AAClF,QAAM,CAAC,QAAQ,SAAS,IAAIC,UAA0B,MAAM;AAC5D,QAAM,CAAC,OAAO,QAAQ,IAAIA,UAAwB,IAAI;AACtD,QAAM,CAAC,QAAQ,SAAS,IAAIA,UAAoC;AAEhE,QAAM,EAAE,MAAM,SAAS,WAAW,QAAQ,IAAI,6BAA6B;AAAA,IACzE,MAAM;AAAA,EACR,CAAC;AAGD,QAAM,SAASC,SAAuB,MAAM;AAC1C,QAAI,CAAC,SAAS,KAAM,QAAO;AAC3B,eAAW,OAAO,QAAQ,MAAM;AAC9B,UAAI;AACF,cAAM,UAAU,eAAe;AAAA,UAC7B,KAAK;AAAA,UACL,MAAM,IAAI;AAAA,UACV,QAAQ,IAAI;AAAA,QACd,CAAC;AACD,YAAI,QAAQ,cAAc,eAAe,YAAY,QAAQ,MAAM;AACjE,iBAAO,OAAO,QAAQ,KAAK,MAAM;AAAA,QACnC;AAAA,MACF,QAAQ;AAAA,MAER;AAAA,IACF;AACA,WAAO;AAAA,EACT,GAAG,CAAC,OAAO,CAAC;AAEZ,EAAAF,WAAU,MAAM;AACd,QAAI,aAAa,QAAQ;AACvB,gBAAU,WAAW;AACrB,eAAS,QAAQ,EAAE,QAAQ,YAAY,CAAC;AAAA,IAC1C;AACA,QAAI,WAAW,QAAQ;AACrB,gBAAU,QAAQ;AAClB,eAAS,QAAQ,EAAE,QAAQ,SAAS,CAAC;AAAA,IACvC;AAAA,EACF,GAAG,CAAC,WAAW,SAAS,MAAM,CAAC;AAE/B,QAAM,YAAYG;AAAA,IAChB,OAAO,SAAwB;AAC7B,UAAI,CAAC,SAAS;AACZ,iBAAS,sBAAsB;AAC/B,eAAO;AAAA,MACT;AAEA,YAAM,QAAQ,aAAa;AAC3B,YAAM,QAAQ,KAAK,SAAS,QAAQ,KAAK,KAAK;AAE9C,UAAI;AACF,kBAAU,SAAS;AACnB,iBAAS,IAAI;AAEb,cAAM,SAAS,MAAM,mBAAmB;AAAA,UACtC,SAAS,MAAM;AAAA,UACf,KAAK;AAAA,UACL,cAAc;AAAA,UACd,MAAM,CAAC,KAAK,WAAW,KAAK,OAAO,KAAK,IAAI;AAAA,UAC5C,OAAO,KAAK;AAAA,QACd,CAAC;AAED,kBAAU,MAAM;AAChB,kBAAU,SAAS;AACnB,cAAM,QAAQ,OAAO,qBAAqB,IAAI,CAAC;AAE/C,eAAO;AAAA,MACT,SAAS,KAAU;AACjB,kBAAU,QAAQ;AAClB,cAAM,MAAM,KAAK,gBAAgB,KAAK,WAAW;AACjD,iBAAS,GAAG;AACZ,eAAO;AAAA,MACT;AAAA,IACF;AAAA,IACA,CAAC,SAAS,kBAAkB;AAAA,EAC9B;AAEA,QAAM,QAAQA,aAAY,MAAM;AAC9B,cAAU,MAAM;AAChB,aAAS,IAAI;AACb,cAAU,MAAS;AAAA,EACrB,GAAG,CAAC,CAAC;AAEL,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,aAAa,CAAC,CAAC;AAAA,EACjB;AACF;;;AClHA,SAAS,gBAAgB;AAGlB,SAAS,gBAAuB;AACrC,SAAO,SAAS,UAAU;AAC5B;","names":["atom","atom","atom","useState","useEffect","useCallback","useState","useCallback","useEffect","rpcUrl","useState","useEffect","useCallback","toHex","resolveOperatorRpc","useState","useCallback","useEffect","rpcUrl","toHex","useCallback","useState","useMemo","useEffect","useState","useMemo","useCallback"]}