{"version":3,"sources":["../../src/react/useAgentRunner.ts","../../src/core/crypto.ts","../../src/registry/ipfs-fetcher.ts","../../src/core/types.ts","../../src/agent/agent-runner.ts","../../src/config/config.ts"],"sourcesContent":["// ---------------------------------------------------------------------------\n// @agentx/sdk — useAgentRunner React Hook\n// ---------------------------------------------------------------------------\n// Wraps AgentRunner.useAgent() for React + wagmi integration.\n//\n//   const { ctx, isLoading, error } = useAgentRunner(agentId)\n//   // ctx.prompt → inject into LLM\n//   // ctx.skills → RunnableSkill[] with execute()\n//   // ctx.mcp    → MCP connection info\n// ---------------------------------------------------------------------------\n\n'use client'\n\nimport { useState, useEffect, useRef } from 'react'\nimport { usePublicClient, useWalletClient } from 'wagmi'\nimport type { Address } from 'viem'\n\nimport { AgentRunner } from '../agent/agent-runner'\nimport type { AgentRunContext, OnChainReader } from '../agent/agent-runner'\nimport { IPFSFetcher } from '../registry/ipfs-fetcher'\nimport { KNOWN_CHAINS } from '../config/config'\nimport type { ChainConfig } from '../config/config'\n\n// ── IdentityRegistry ABI (minimal — only what useAgent needs) ──────────────\n\nconst IDENTITY_REGISTRY_ABI = [\n  // getAgentMetadata returns MetadataEntry[] with key+value strings\n  {\n    name: 'getAgentMetadata',\n    type: 'function',\n    stateMutability: 'view',\n    inputs: [{ name: 'agentId', type: 'uint256' }],\n    outputs: [\n      {\n        name: '',\n        type: 'tuple[]',\n        components: [\n          { name: 'key', type: 'string' },\n          { name: 'value', type: 'bytes' },\n        ],\n      },\n    ],\n  },\n] as const\n\n// ── SubscriptionManager ABI (minimal) ─────────────────────────────────────\n\nconst SUBSCRIPTION_MANAGER_ABI = [\n  {\n    name: 'hasActiveSubscription',\n    type: 'function',\n    stateMutability: 'view',\n    inputs: [\n      { name: 'subscriber', type: 'address' },\n      { name: 'agentId', type: 'uint256' },\n    ],\n    outputs: [{ name: '', type: 'bool' }],\n  },\n] as const\n\n// ── Hook Config ────────────────────────────────────────────────────────────\n\nexport interface UseAgentRunnerConfig {\n  agentId: number\n  chainConfig?: ChainConfig\n  ipfsGateways?: string[]\n}\n\nexport interface UseAgentRunnerResult {\n  ctx: AgentRunContext | null\n  isLoading: boolean\n  error: Error | null\n  /** Re-trigger the load (e.g. after connecting wallet or subscribing) */\n  refetch: () => void\n}\n\n// ── OnChainReader Implementation (viem) ────────────────────────────────────\n\nclass ViemOnChainReader implements OnChainReader {\n  constructor(\n    private publicClient: ReturnType<typeof usePublicClient>,\n    private chainConfig: ChainConfig\n  ) {}\n\n  async getTokenURI(_agentId: number): Promise<string> {\n    // tokenURI is standard ERC-721 metadata — not needed for our flow\n    // Metadata is fetched via getAgentMetadata\n    return ''\n  }\n\n  async getAttributes(agentId: number): Promise<Record<string, string>> {\n    if (!this.publicClient) throw new Error('Public client not available')\n\n    const entries = (await this.publicClient.readContract({\n      address: this.chainConfig.contracts.identityRegistry,\n      abi: IDENTITY_REGISTRY_ABI,\n      functionName: 'getAgentMetadata',\n      args: [BigInt(agentId)],\n    })) as { key: string; value: string }[]\n\n    const attrs: Record<string, string> = {}\n    for (const entry of entries) {\n      // value is bytes — convert to string\n      const hexStr = entry.value\n      if (hexStr && hexStr !== '0x') {\n        attrs[entry.key] = hexToStringUTF8(hexStr)\n      } else {\n        attrs[entry.key] = ''\n      }\n    }\n    return attrs\n  }\n\n  async hasActiveSubscription(address: string, agentId: number): Promise<boolean> {\n    if (!this.publicClient) return false\n\n    try {\n      return (await this.publicClient.readContract({\n        address: this.chainConfig.contracts.subscriptionManager,\n        abi: SUBSCRIPTION_MANAGER_ABI,\n        functionName: 'hasActiveSubscription',\n        args: [address as Address, BigInt(agentId)],\n      })) as boolean\n    } catch {\n      return false\n    }\n  }\n}\n\n// ── Helpers ────────────────────────────────────────────────────────────────\n\nfunction hexToStringUTF8(hex: string): string {\n  if (!hex.startsWith('0x')) return hex\n  const hexClean = hex.slice(2)\n  if (hexClean.length === 0) return ''\n  try {\n    const bytes = new Uint8Array(hexClean.length / 2)\n    for (let i = 0; i < bytes.length; i++) {\n      bytes[i] = parseInt(hexClean.substring(i * 2, i * 2 + 2), 16)\n    }\n    return new TextDecoder().decode(bytes)\n  } catch {\n    return hex\n  }\n}\n\n// ── Hook ───────────────────────────────────────────────────────────────────\n\nexport function useAgentRunner(config: UseAgentRunnerConfig): UseAgentRunnerResult {\n  const { agentId, chainConfig: chainConfigOverride, ipfsGateways } = config\n\n  const publicClient = usePublicClient()\n  const { data: walletClient } = useWalletClient()\n\n  const [ctx, setCtx] = useState<AgentRunContext | null>(null)\n  const [isLoading, setIsLoading] = useState(false)\n  const [error, setError] = useState<Error | null>(null)\n  const [refetchKey, setRefetchKey] = useState(0)\n\n  const runnerRef = useRef<AgentRunner | null>(null)\n  const mountedRef = useRef(true)\n\n  useEffect(() => {\n    mountedRef.current = true\n    return () => {\n      mountedRef.current = false\n    }\n  }, [])\n\n  useEffect(() => {\n    if (!publicClient || !walletClient) {\n      setError(new Error('Wallet not connected'))\n      return\n    }\n\n    const chainConfig =\n      chainConfigOverride ?? (publicClient.chain?.id ? KNOWN_CHAINS[publicClient.chain.id] : undefined)\n\n    if (!chainConfig) {\n      setError(new Error(`Chain ${publicClient.chain?.id} not supported`))\n      return\n    }\n\n    // Create OnChainReader\n    const reader = new ViemOnChainReader(publicClient, chainConfig)\n\n    // WalletSigner from wagmi\n    const signer = {\n      async signMessage(message: string): Promise<string> {\n        if (!walletClient.account) throw new Error('Wallet not connected')\n        return walletClient.signMessage({ account: walletClient.account, message })\n      },\n      async getAddress(): Promise<string> {\n        if (!walletClient.account) throw new Error('Wallet not connected')\n        return walletClient.account.address\n      },\n      async getPrivateKey(): Promise<string> {\n        // wagmi walletClient doesn't expose private key\n        // ECIES decryption requires private key — must be injected from wallet provider\n        throw new Error(\n          'Private key not available via wagmi. ' +\n          'Use window.ethereum.request({ method: \"eth_private_key\" }) or inject getPrivateKey via custom WalletSigner.'\n        )\n      },\n    }\n\n    // IPFS Fetcher\n    const ipfsFetcher = new IPFSFetcher({\n      fallbackGateways: ipfsGateways ?? chainConfig.ipfsGateways ?? [\n        'gateway.pinata.cloud',\n        'dweb.link',\n        'cf-ipfs.com',\n      ],\n    })\n\n    runnerRef.current = new AgentRunner({\n      reader,\n      wallet: signer,\n      ipfsFetcher,\n    })\n\n    setIsLoading(true)\n    setError(null)\n\n    runnerRef.current\n      .useAgent(agentId)\n      .then(result => {\n        if (mountedRef.current) {\n          setCtx(result)\n          setIsLoading(false)\n        }\n      })\n      .catch(err => {\n        if (mountedRef.current) {\n          setError(err instanceof Error ? err : new Error(String(err)))\n          setIsLoading(false)\n        }\n      })\n\n    return () => {\n      mountedRef.current = false\n    }\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [agentId, publicClient?.chain?.id, publicClient, walletClient, refetchKey])\n\n  const refetch = () => setRefetchKey(k => k + 1)\n\n  return { ctx, isLoading, error, refetch }\n}\n","// ---------------------------------------------------------------------------\n// @agentx/sdk — Crypto Engine\n// ---------------------------------------------------------------------------\n// AES-256-GCM for content encryption (NIST standard wire format).\n// ECIES (secp256k1) for key wrapping.\n//\n// Wire format (AES-256-GCM):\n//   base64( IV[12] || ciphertext || authTag[16] )\n//\n// ECIES wire format (compatible with eciesjs):\n//   hex( ephemeralPub[33] || IV[16] || ciphertext || MAC[32] )\n//\n// Pure JS — works in browser, Node, edge. No native deps except @noble/*.\n// ---------------------------------------------------------------------------\n\nimport { gcm } from '@noble/ciphers/aes.js'\nimport { secp256k1 } from '@noble/curves/secp256k1.js'\nimport { sha256 } from '@noble/hashes/sha2.js'\nimport { hkdf } from '@noble/hashes/hkdf.js'\nimport { hmac } from '@noble/hashes/hmac.js'\nimport { bytesToHex, hexToBytes } from '@noble/ciphers/utils.js'\n\n// ── randomBytes implementation (cross-runtime: browser / Node) ────────────\n\nexport function randomBytes(length: number): Uint8Array {\n  // browser: crypto.getRandomValues\n  if (typeof crypto !== 'undefined' && crypto.getRandomValues) {\n    const buf = new Uint8Array(length)\n    crypto.getRandomValues(buf)\n    return buf\n  }\n  // Node: crypto.randomBytes\n  // eslint-disable-next-line @typescript-eslint/no-require-imports\n  const nodeCrypto = require('crypto')\n  return new Uint8Array(nodeCrypto.randomBytes(length))\n}\n\nimport type { EncryptedPayload, AgentPrivatePayload } from './types'\nimport type { PackResult } from './types'\n\n// ── Re-exports for convenience ─────────────────────────────────────────────\n\nexport { bytesToHex, hexToBytes }\n\n// ── Constants ──────────────────────────────────────────────────────────────\n\nconst AES_KEY_SIZE = 32\nconst IV_SIZE = 12 // GCM recommended\nconst TAG_SIZE = 16 // GCM auth tag\n\n// ── Base64 helpers (cross-runtime) ─────────────────────────────────────────\n\nfunction toBase64(bytes: Uint8Array): string {\n  // Works in browser (btoa + binary) and Node (Buffer)\n  if (typeof Buffer !== 'undefined') return Buffer.from(bytes).toString('base64')\n  let binary = ''\n  for (let i = 0; i < bytes.length; i++) binary += String.fromCharCode(bytes[i]!)\n  return btoa(binary)\n}\n\nfunction fromBase64(b64: string): Uint8Array {\n  if (typeof Buffer !== 'undefined') return new Uint8Array(Buffer.from(b64, 'base64'))\n  const binary = atob(b64)\n  const bytes = new Uint8Array(binary.length)\n  for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i)\n  return bytes\n}\n\n// ── AES-256-GCM ────────────────────────────────────────────────────────────\n\n/**\n * Encrypt with AES-256-GCM.\n * Wire format: base64( IV[12] || ciphertext || authTag[16] )\n */\nexport function aesEncrypt(plaintext: string, keyHex: string): string {\n  const key = hexToBytes(keyHex)\n  const iv = randomBytes(IV_SIZE)\n  const plainBytes = new TextEncoder().encode(plaintext)\n\n  const cipher = gcm(key, iv)\n  const encrypted = cipher.encrypt(plainBytes)\n  // noble gcm.encrypt returns: ciphertext || authTag(16)\n  const ciphertext = encrypted.subarray(0, -TAG_SIZE)\n  const authTag = encrypted.subarray(-TAG_SIZE)\n\n  // Pack: IV || ciphertext || authTag\n  const combined = new Uint8Array(IV_SIZE + ciphertext.length + TAG_SIZE)\n  combined.set(iv, 0)\n  combined.set(ciphertext, IV_SIZE)\n  combined.set(authTag, IV_SIZE + ciphertext.length)\n\n  return toBase64(combined)\n}\n\n/**\n * Decrypt AES-256-GCM.\n */\nexport function aesDecrypt(encryptedBase64: string, keyHex: string): string {\n  const key = hexToBytes(keyHex)\n  const combined = fromBase64(encryptedBase64)\n\n  const iv = combined.subarray(0, IV_SIZE)\n  const ciphertext = combined.subarray(IV_SIZE, -TAG_SIZE)\n  const authTag = combined.subarray(-TAG_SIZE)\n\n  const cipher = gcm(key, iv)\n  // noble decrypt expects: ciphertext || authTag\n  const ciphertextWithTag = new Uint8Array(ciphertext.length + TAG_SIZE)\n  ciphertextWithTag.set(ciphertext, 0)\n  ciphertextWithTag.set(authTag, ciphertext.length)\n\n  const decrypted = cipher.decrypt(ciphertextWithTag)\n  return new TextDecoder().decode(decrypted)\n}\n\n/**\n * Encrypt with AES-256-GCM — master-key wire format.\n * Layout: base64( IV[12] || authTag[16] || ciphertext ).\n * Kept byte-for-byte compatible with the Gateway's legacy at-rest key\n * encryption (`gateway/src/lib/crypto.ts`) so existing stored rows decrypt\n * unchanged. New code should prefer `aesEncrypt`/`aesDecrypt` unless data\n * written in this layout must be read.\n */\nexport function encryptWithKey(plaintext: string, keyHex: string): string {\n  const key = hexToBytes(keyHex)\n  const iv = randomBytes(IV_SIZE)\n  const plainBytes = new TextEncoder().encode(plaintext)\n\n  const cipher = gcm(key, iv)\n  const encrypted = cipher.encrypt(plainBytes)\n  const ciphertext = encrypted.subarray(0, -TAG_SIZE)\n  const authTag = encrypted.subarray(-TAG_SIZE)\n\n  const combined = new Uint8Array(IV_SIZE + TAG_SIZE + ciphertext.length)\n  combined.set(iv, 0)\n  combined.set(authTag, IV_SIZE)\n  combined.set(ciphertext, IV_SIZE + TAG_SIZE)\n\n  return toBase64(combined)\n}\n\n/**\n * Decrypt AES-256-GCM — master-key wire format\n * (base64( IV[12] || authTag[16] || ciphertext )).\n */\nexport function decryptWithKey(encryptedBase64: string, keyHex: string): string {\n  const key = hexToBytes(keyHex)\n  const combined = fromBase64(encryptedBase64)\n\n  const iv = combined.subarray(0, IV_SIZE)\n  const authTag = combined.subarray(IV_SIZE, IV_SIZE + TAG_SIZE)\n  const ciphertext = combined.subarray(IV_SIZE + TAG_SIZE)\n\n  const cipher = gcm(key, iv)\n  const ciphertextWithTag = new Uint8Array(ciphertext.length + TAG_SIZE)\n  ciphertextWithTag.set(ciphertext, 0)\n  ciphertextWithTag.set(authTag, ciphertext.length)\n\n  const decrypted = cipher.decrypt(ciphertextWithTag)\n  return new TextDecoder().decode(decrypted)\n}\n\n/**\n * Generate a cryptographically random AES-256 key (hex, 64 chars).\n */\nexport function generateAesKey(): string {\n  return bytesToHex(randomBytes(AES_KEY_SIZE))\n}\n\n// ── ECIES (secp256k1) ──────────────────────────────────────────────────────\n//\n// eciesjs-compatible wire format:\n//   ephemeralPub(33B compressed) || IV(16B) || ciphertext || MAC(32B)\n//   Encoding: hex\n//\n// HKDF(SHA-256) derives AES key + HMAC key from ECDH shared secret.\n// ---------------------------------------------------------------------------\n\nfunction eciesEncode(\n  ephemeralPub: Uint8Array,\n  iv: Uint8Array,\n  ciphertext: Uint8Array,\n  mac: Uint8Array\n): string {\n  const out = new Uint8Array(33 + 16 + ciphertext.length + 32)\n  out.set(ephemeralPub, 0)\n  out.set(iv, 33)\n  out.set(ciphertext, 33 + 16)\n  out.set(mac, 33 + 16 + ciphertext.length)\n  return bytesToHex(out)\n}\n\nfunction eciesDecode(dataHex: string): {\n  ephemeralPub: Uint8Array\n  iv: Uint8Array\n  ciphertext: Uint8Array\n  mac: Uint8Array\n} {\n  const d = hexToBytes(dataHex)\n  return {\n    ephemeralPub: d.subarray(0, 33),\n    iv: d.subarray(33, 49),\n    ciphertext: d.subarray(49, -32),\n    mac: d.subarray(-32),\n  }\n}\n\n// Simple AES-256-CTR implementation on top of @noble/ciphers AES core\nfunction aesCtrEncrypt(key: Uint8Array, ctrBytes: Uint8Array, data: Uint8Array): Uint8Array {\n  const blockSize = 16\n  const cipher = gcm(key, ctrBytes) // GCM internally handles CTR\n  // Use noble's CTR approach: encrypt the plaintext directly with the derived stream\n  // noble uses AES-CTR internally for GCM; simpler: implement CTR with AES-ECB\n  const result = new Uint8Array(data.length)\n  const counter = new Uint8Array(blockSize)\n  counter.set(ctrBytes)\n  for (let i = 0; i < data.length; i += blockSize) {\n    const keystream = gcm(key, counter).encrypt(new Uint8Array(blockSize))\n    for (let j = 0; j < blockSize && i + j < data.length; j++) {\n      result[i + j] = keystream[j]! ^ data[i + j]!\n    }\n    // Increment counter (big-endian)\n    for (let j = blockSize - 1; j >= 0; j--) {\n      const val = counter[j]\n      if (val !== undefined) {\n        counter[j] = (val + 1) & 0xff\n        if (counter[j] !== 0) break\n      }\n    }\n  }\n  return result\n}\n\n/**\n * Encrypt data with recipient's secp256k1 public key (ECIES).\n *\n * @param dataHex    The data to encrypt (hex, e.g. AES key)\n * @param publicKey  Recipient's public key (hex, 04-prefixed uncompressed or 02/03 compressed)\n */\nexport function eciesEncrypt(dataHex: string, publicKey: string): string {\n  // 1. Ephemeral keypair\n  const ephPriv = randomBytes(32)\n  const ephPub = secp256k1.getPublicKey(ephPriv, true) // 33B compressed\n\n  // 2. Parse recipient public key\n  let recipientPub: Uint8Array\n  if (publicKey.startsWith('04') && publicKey.length === 130) {\n    recipientPub = hexToBytes(publicKey)\n  } else if (publicKey.startsWith('02') || publicKey.startsWith('03')) {\n    recipientPub = hexToBytes(publicKey)\n  } else {\n    throw new Error('Invalid public key format: expected hex with 02/03/04 prefix')\n  }\n\n  // 3. ECDH\n  const shared = secp256k1.getSharedSecret(ephPriv, recipientPub)\n  const sharedX = shared.subarray(1, 33) // x-coordinate only\n  const sharedKey = sha256(sharedX)\n\n  // 4. HKDF: encKey(32) || macKey(32)\n  const hkdfOut = hkdf(sha256, sharedKey, undefined, undefined, 64)\n  const encKey = hkdfOut.subarray(0, 32)\n  const macKey = hkdfOut.subarray(32, 64)\n\n  // 5. AES-256-CTR encrypt\n  const iv = randomBytes(16)\n  const plaintext = hexToBytes(dataHex)\n  const ciphertext = aesCtrEncrypt(encKey, iv, plaintext)\n\n  // 6. HMAC: MAC(ephemeralPub || IV || ciphertext)\n  const macInput = new Uint8Array(33 + 16 + ciphertext.length)\n  macInput.set(ephPub, 0)\n  macInput.set(iv, 33)\n  macInput.set(ciphertext, 33 + 16)\n  const mac = hmac(sha256, macKey, macInput)\n\n  return eciesEncode(ephPub, iv, ciphertext, mac)\n}\n\n/**\n * Decrypt ECIES ciphertext with recipient's secp256k1 private key.\n */\nexport function eciesDecrypt(dataHex: string, privateKey: string): string {\n  const { ephemeralPub, iv, ciphertext, mac } = eciesDecode(dataHex)\n\n  // 1. ECDH\n  const privBytes = hexToBytes(privateKey)\n  const shared = secp256k1.getSharedSecret(privBytes, ephemeralPub)\n  const sharedX = shared.subarray(1, 33)\n  const sharedKey = sha256(sharedX)\n\n  // 2. HKDF\n  const hkdfOut = hkdf(sha256, sharedKey, undefined, undefined, 64)\n  const encKey = hkdfOut.subarray(0, 32)\n  const macKey = hkdfOut.subarray(32, 64)\n\n  // 3. Verify MAC\n  const macInput = new Uint8Array(33 + 16 + ciphertext.length)\n  macInput.set(ephemeralPub, 0)\n  macInput.set(iv, 33)\n  macInput.set(ciphertext, 33 + 16)\n  const expectedMac = hmac(sha256, macKey, macInput)\n  if (!constantTimeEqual(mac, expectedMac)) {\n    throw new Error('ECIES decryption failed: MAC mismatch')\n  }\n\n  // 4. Decrypt\n  const plaintext = aesCtrEncrypt(encKey, iv, ciphertext) // CTR encrypt = decrypt\n  return bytesToHex(plaintext)\n}\n\nfunction constantTimeEqual(a: Uint8Array, b: Uint8Array): boolean {\n  if (a.length !== b.length) return false\n  let diff = 0\n  for (let i = 0; i < a.length; i++) diff |= a[i]! ^ b[i]!\n  return diff === 0\n}\n\n// ── High-Level: Agent Pack / Unpack ────────────────────────────────────────\n\n/**\n * Encrypt an Agent's private payload with AES-256-GCM.\n */\nexport function encryptPayload(\n  payload: AgentPrivatePayload,\n  keyHex?: string\n): EncryptedPayload {\n  const key = keyHex ?? generateAesKey()\n  return {\n    encrypted: true,\n    algorithm: 'AES-256-GCM',\n    data: aesEncrypt(JSON.stringify(payload), key),\n  }\n}\n\n/**\n * Decrypt an EncryptedPayload.\n */\nexport function decryptPayload(\n  encrypted: EncryptedPayload,\n  keyHex: string\n): AgentPrivatePayload {\n  if (encrypted.algorithm !== 'AES-256-GCM') {\n    throw new Error(`Unsupported algorithm: ${encrypted.algorithm}`)\n  }\n  return JSON.parse(aesDecrypt(encrypted.data, keyHex)) as AgentPrivatePayload\n}\n\n/**\n * Pack an AgentPayload for publishing.\n *   1. Split public/private\n *   2. AES-256-GCM encrypt private part\n *   3. ECIES wrap AES key with creator's public key\n */\nexport function packAgentForPublish(\n  agent: import('./types').AgentPayload,\n  publicKey: string,\n  aesKeyHex?: string\n): PackResult {\n  const key = aesKeyHex ?? generateAesKey()\n\n  const eciesEncryptedKeyHex = eciesEncrypt(key, publicKey)\n\n  return {\n    encryptedCid: '', // filled after IPFS upload\n    publicCid: '',    // filled after IPFS upload\n    aesKeyHex: key,\n    eciesEncryptedKeyHex,\n  }\n}\n\n// ── Integrated Publish Pipeline ────────────────────────────────────────────\n\nimport type { IPFSUploader, IPFSUploadResult } from '../ipfs/ipfs-uploader'\n\nexport interface PublishAgentConfig {\n  /** Agent payload to publish */\n  agent: import('./types').AgentPayload\n  /** Creator's secp256k1 public key (hex) */\n  publicKey: string\n  /** IPFS uploader instance with Pinata JWT configured */\n  uploader: IPFSUploader\n  /** Optional AES key (auto-generated if not provided) */\n  aesKeyHex?: string\n  /** Agent name for IPFS metadata */\n  agentName?: string\n}\n\nexport interface PublishAgentResult {\n  /** AES encryption key (hex) */\n  aesKeyHex: string\n  /** ECIES-encrypted AES key for on-chain storage */\n  eciesEncryptedKeyHex: string\n  /** CID of the encrypted private payload on IPFS */\n  encryptedCid: string\n  /** Public IPFS gateway URL to the encrypted payload */\n  encryptedUrl: string\n  /** CID of the public metadata on IPFS */\n  publicCid: string\n  /** Public IPFS gateway URL to the public metadata */\n  publicUrl: string\n  /** Full PackResult (compatible with existing code) */\n  pack: PackResult\n  /** Raw IPFS upload results */\n  uploads: { encrypted: IPFSUploadResult; public: IPFSUploadResult }\n}\n\n/**\n * Full publish pipeline: encrypt + upload to IPFS.\n *\n * Usage:\n *   const uploader = new IPFSUploader({ pinataJwt: '...' })\n *   const result = await publishAgent({ agent, publicKey, uploader })\n *   // result.encryptedCid → IPFS CID to mint as on-chain tokenURI\n */\nexport async function publishAgent(config: PublishAgentConfig): Promise<PublishAgentResult> {\n  const { agent, publicKey, uploader, aesKeyHex, agentName } = config\n\n  if (!uploader.isConfigured()) {\n    throw new Error('IPFSUploader is not configured — set pinataJwt or customEndpoint')\n  }\n\n  const key = aesKeyHex ?? generateAesKey()\n  const eciesEncryptedKeyHex = eciesEncrypt(key, publicKey)\n\n  // Split into private (encrypted) and public payloads\n  const privatePayload: import('./types').AgentPrivatePayload = {\n    prompt: agent.prompt,\n    skills: agent.skills,\n    mcp: agent.mcp,\n  }\n  const encryptedPayload = encryptPayload(privatePayload, key)\n\n  // Upload both parts to IPFS in parallel\n  const [encrypted, publicMeta] = await Promise.all([\n    uploader.uploadEncryptedPayload(encryptedPayload, agentName),\n    uploader.uploadJSON({\n      name: agent.name,\n      description: agent.description,\n      version: agent.version,\n      tags: agent.tags,\n      capabilities: agent.capabilities,\n      category: agent.category,\n      eciesKey: eciesEncryptedKeyHex,\n    }),\n  ])\n\n  const pack: PackResult = {\n    encryptedCid: encrypted.cid,\n    publicCid: publicMeta.cid,\n    aesKeyHex: key,\n    eciesEncryptedKeyHex,\n  }\n\n  return {\n    aesKeyHex: key,\n    eciesEncryptedKeyHex,\n    encryptedCid: encrypted.cid,\n    encryptedUrl: encrypted.url,\n    publicCid: publicMeta.cid,\n    publicUrl: publicMeta.url,\n    pack,\n    uploads: { encrypted, public: publicMeta },\n  }\n}\n\n/**\n * Unpack an Agent:\n *   1. ECIES decrypt the AES key (private key)\n *   2. AES-256-GCM decrypt the payload\n */\nexport function unpackAgent(\n  encryptedPayload: EncryptedPayload,\n  eciesEncryptedKey: string,\n  privateKey: string\n): AgentPrivatePayload {\n  const aesKeyHex = eciesDecrypt(eciesEncryptedKey, privateKey)\n  return decryptPayload(encryptedPayload, aesKeyHex)\n}\n\n// ── Key Pair Utilities ─────────────────────────────────────────────────────\n\n/**\n * Generate a secp256k1 keypair compatible with Ethereum wallets.\n */\nexport function generateKeyPair(): { privateKey: string; publicKey: string } {\n  const priv = randomBytes(32)\n  const pub = secp256k1.getPublicKey(priv, false) // uncompressed 04-prefixed\n  return { privateKey: bytesToHex(priv), publicKey: bytesToHex(pub) }\n}\n\n/**\n * Derive public key from private key (hex).\n */\nexport function getPublicKey(privateKey: string): string {\n  return bytesToHex(secp256k1.getPublicKey(hexToBytes(privateKey), false))\n}\n","// ---------------------------------------------------------------------------\n// @agentx/sdk — IPFS Fetcher\n// ---------------------------------------------------------------------------\n// Multi-gateway IPFS fetcher with in-memory cache, deduplication, and\n// automatic fallback.  Compatible with the EncryptedPayload wire format.\n// ---------------------------------------------------------------------------\n\nimport type { EncryptedPayload } from '../core/types'\n\n// ── Types ───────────────────────────────────────────────────────────────────\n\nexport interface IPFSFetcherConfig {\n  /** Primary IPFS gateway (default: ipfs.io) */\n  gateway?: string\n  /** Fallback gateways in order of preference */\n  fallbackGateways?: string[]\n  /** Request timeout in ms (default: 10_000) */\n  timeoutMs?: number\n  /** Max cached entries (LRU-like eviction, default: 200) */\n  maxCache?: number\n}\n\ntype CacheEntry<T> = {\n  data: T\n  timestamp: number\n}\n\n// ── Implementation ─────────────────────────────────────────────────────────\n\nexport class IPFSFetcher {\n  private gateway: string\n  private fallbackGateways: string[]\n  private timeoutMs: number\n\n  private cache = new Map<string, CacheEntry<unknown>>()\n  private maxCache: number\n  private pending = new Map<string, Promise<unknown>>()\n  private failed = new Set<string>()\n\n  constructor(config: IPFSFetcherConfig = {}) {\n    this.gateway = config.gateway ?? 'ipfs.io'\n    this.fallbackGateways = config.fallbackGateways ?? [\n      'gateway.pinata.cloud',\n      'dweb.link',\n      'cf-ipfs.com',\n    ]\n    this.timeoutMs = config.timeoutMs ?? 10_000\n    this.maxCache = config.maxCache ?? 200\n  }\n\n  // ── Public API ──────────────────────────────────────────────────────────\n\n  /** Fetch JSON from a single IPFS CID. */\n  async fetchJSON<T = unknown>(cid: string): Promise<T> {\n    const cached = this.cache.get(cid)\n    if (cached) return cached.data as T\n\n    if (this.failed.has(cid)) throw new Error(`CID ${cid} previously failed`)\n\n    const pending = this.pending.get(cid)\n    if (pending) return pending as Promise<T>\n\n    const promise = this._doFetch<T>(cid)\n    this.pending.set(cid, promise)\n\n    try {\n      const data = await promise\n      this._cacheSet(cid, data)\n      return data\n    } catch (e) {\n      this.failed.add(cid)\n      throw e\n    } finally {\n      this.pending.delete(cid)\n    }\n  }\n\n  /** Fetch encrypted agent payload (validates algorithm). */\n  async fetchEncryptedPayload(cid: string): Promise<EncryptedPayload> {\n    const raw = await this.fetchJSON<Record<string, unknown>>(cid)\n    if (!raw.encrypted || raw.algorithm !== 'AES-256-GCM' || typeof raw.data !== 'string') {\n      throw new Error(`Invalid EncryptedPayload at CID ${cid}`)\n    }\n    return raw as unknown as EncryptedPayload\n  }\n\n  /** Batch fetch multiple CIDs with concurrency control. */\n  async fetchBatch<T = unknown>(cids: string[], concurrency = 5): Promise<Map<string, T>> {\n    const results = new Map<string, T>()\n    const unique = [...new Set(cids)].filter(c => this.isValidCID(c))\n\n    for (let i = 0; i < unique.length; i += concurrency) {\n      const batch = unique.slice(i, i + concurrency)\n      const settled = await Promise.allSettled(\n        batch.map(cid => this.fetchJSON<T>(cid))\n      )\n      settled.forEach((r, j) => {\n        if (r.status === 'fulfilled') results.set(batch[j]!, r.value)\n      })\n      if (i + concurrency < unique.length) {\n        await new Promise(r => setTimeout(r, 200))\n      }\n    }\n    return results\n  }\n\n  /** Check if a string looks like a valid IPFS CID. */\n  isValidCID(cid: string): boolean {\n    return /^(Qm[1-9A-HJ-NP-Za-km-z]{44,}|b[a-z2-7]{58,}|[A-Za-z0-9+/]{46,})$/.test(cid)\n  }\n\n  /** Clear cache (optionally for a specific CID). */\n  clearCache(cid?: string): void {\n    if (cid) {\n      this.cache.delete(cid)\n    } else {\n      this.cache.clear()\n    }\n    this.failed.clear()\n  }\n\n  /** Number of cached entries. */\n  get cacheSize(): number {\n    return this.cache.size\n  }\n\n  // ── Internal ─────────────────────────────────────────────────────────────\n\n  private async _doFetch<T>(cid: string): Promise<T> {\n    if (!this.isValidCID(cid)) throw new Error(`Invalid CID: ${cid}`)\n\n    // Try primary gateway\n    try {\n      return await this._fetchFrom(cid, this.gateway, this.timeoutMs)\n    } catch {\n      // fall through to alternatives\n    }\n\n    // Try fallback gateways\n    for (const gw of this.fallbackGateways) {\n      try {\n        return await this._fetchFrom(cid, gw, this.timeoutMs)\n      } catch {\n        // try next\n      }\n    }\n\n    throw new Error(`All IPFS gateways failed for CID ${cid}`)\n  }\n\n  private async _fetchFrom<T>(cid: string, gateway: string, timeoutMs: number): Promise<T> {\n    const url = `https://${gateway}/ipfs/${cid}`\n    const res = await fetch(url, {\n      headers: { Accept: 'application/json' },\n      signal: AbortSignal.timeout(timeoutMs),\n    })\n    if (!res.ok) throw new Error(`HTTP ${res.status}`)\n    return (await res.json()) as T\n  }\n\n  private _cacheSet(cid: string, data: unknown): void {\n    this.cache.set(cid, { data, timestamp: Date.now() })\n    // Simple LRU-like eviction\n    if (this.cache.size > this.maxCache) {\n      const oldest = [...this.cache.entries()].sort(\n        (a, b) => a[1].timestamp - b[1].timestamp\n      )[0]\n      if (oldest) this.cache.delete(oldest[0])\n    }\n  }\n}\n\n/** Singleton-friendly default instance. */\nexport const defaultIPFSFetcher = new IPFSFetcher()\n","// ---------------------------------------------------------------------------\n// @agentx/sdk — Core Type Definitions\n// ---------------------------------------------------------------------------\n// Agent = Prompt + Skills[] + MCP\n// All crypto-related \"wire\" fields (encryptedPayloadCid, eciesEncryptedKey)\n// live in IPFS metadata attributes → existing ERC8004 contracts are unchanged.\n// ---------------------------------------------------------------------------\n\n// ── JSON Schema (MCP standard subset) ──────────────────────────────────────\n\nexport interface JSONSchema {\n  type: 'object' | 'array' | 'string' | 'number' | 'boolean' | 'integer' | 'null'\n  properties?: Record<string, JSONSchemaProperty>\n  required?: string[]\n  description?: string\n  items?: JSONSchema\n  enum?: (string | number | boolean | null)[]\n}\n\nexport interface JSONSchemaProperty {\n  type?: JSONSchema['type'] | JSONSchema['type'][]\n  description?: string\n  properties?: Record<string, JSONSchemaProperty>\n  required?: string[]\n  items?: JSONSchema\n  enum?: (string | number | boolean | null)[]\n  format?: string\n  default?: unknown\n}\n\n// ── Skill Definition ───────────────────────────────────────────────────────\n\n/**\n * A single skill module that an Agent exposes.\n * `inputSchema` and `outputSchema` follow MCP Tool JSON Schema conventions.\n */\nexport interface SkillDef {\n  /** Unique skill name (e.g. \"solidity_audit\") */\n  name: string\n  /** Human-readable description shown in the marketplace */\n  description: string\n  /** Semantic version of this skill */\n  version: string\n  /** JSON Schema for the tool's input parameters */\n  inputSchema: JSONSchema\n  /** JSON Schema for the tool's output return value */\n  outputSchema?: JSONSchema\n  /**\n   * Execution mode.\n   * - undefined / \"open\": Source is in the encrypted payload, runs locally.\n   * - { type: \"mcp\", toolName: \"...\" }: Source lives on the publisher's\n   *     MCP server.  Subscriber only gets Schema + remote execution endpoint.\n   *     MCP server verifies on-chain subscription on every call.\n   * - { type: \"a2a\", targetAgentId: 42 }: Delegates to another AgentX Agent.\n   *     The caller's AgentRunner loads + decrypts the target Agent, injects\n   *     its prompt into the LLM context, and exposes its skills as callable\n   *     tools.  This is the core Agent Composition primitive.\n   */\n  execution?: SkillExecutionRemote | A2ASkillExecution\n}\n\n/** Where the skill code actually runs. */\nexport type SkillExecutionMode = 'open' | 'mcp' | 'a2a'\n\nexport interface SkillExecutionRemote {\n  type: 'mcp'\n  /** MCP tool name on the publisher's server (e.g. \"run_strategy_abc123\") */\n  toolName: string\n  /** Optional: explicit MCP endpoint override */\n  endpoint?: string\n}\n\n/**\n * A2A Skill Execution — delegate to another AgentX Agent.\n *\n * Example: A \"trading\" Agent has a skill:\n *   execution: { type: \"a2a\", targetAgentId: 42 }\n * → When LLM calls this skill, AgentRunner loads Agent #42,\n *   decrypts its prompt+skills, and the sub-Agent runs in the\n *   same LLM conversation with its own system prompt.\n */\nexport interface A2ASkillExecution {\n  type: 'a2a'\n  /** On-chain Agent ID to delegate to */\n  targetAgentId: number\n  /** Optional: restrict which of the target Agent's skills are exposed */\n  skillFilter?: string[]\n  /** Optional: custom system prompt override for the sub-Agent */\n  promptOverride?: string\n}\n\n// ── MCP Connection ─────────────────────────────────────────────────────────\n\nexport type McpTransport = 'http' | 'sse' | 'stdio'\n\nexport interface McpConnection {\n  /** Transport type */\n  type: McpTransport\n  /** MCP server URL (required for http/sse) */\n  url?: string\n  /** Optional: limit which tools the Agent exposes to users */\n  toolFilter?: string[]\n  /** Optional: MCP server authentication header / key */\n  authHeader?: string\n}\n\n// ── Pricing ────────────────────────────────────────────────────────────────\n\nexport type PricingType = 'subscription' | 'pay_per_use' | 'free'\n\nexport interface AgentPricing {\n  type: PricingType\n  /** Amount in native unit (e.g. \"0.01\" for 0.01 ETH) */\n  amount: string\n  /** ERC20 token address, or empty for native currency */\n  currency: string\n  /** Billing period for subscriptions (e.g. \"month\", \"year\", \"day\") */\n  period?: string\n}\n\n// ── Agent Payload (the core data model) ────────────────────────────────────\n\n// ── Agent Category (application / use case) ─────────────────────────────────\n//\n// The application category of an agent. Marketplace and application launchers\n// (e.g. \"customer service\", \"airdrop tools\", \"quant strategies\") filter on this\n// field — agents without a category fall back to \"other\" for display purposes.\n// Publish flows MUST set it so the agent surfaces in the right application tab.\n\nexport const AGENT_CATEGORIES = [\n  'operations',          // 运营\n  'customer-service',    // 客服\n  'sales',               // 销售\n  'personal-assistant',  // 个人助理\n  'coding',              // 写代码 / 开发\n  'server-monitoring',   // 服务器监控\n  'airdrop',             // 空投\n  'quant-trading',       // 量化策略\n  'data-analysis',       // 数据分析\n  'content',             // 内容创作\n  'security',            // 安全\n  'finance',             // 金融\n  'other',               // 其他 / 未分类\n] as const\n\nexport type AgentCategory = (typeof AGENT_CATEGORIES)[number]\n\n/**\n * The complete Agent definition.\n *\n * - Fields above \"--- private payload ---\" are public (IPFS publicPayloadCid).\n * - Fields below are encrypted with AES-256-GCM and stored at encryptedPayloadCid.\n */\nexport interface AgentPayload {\n  // ── Public (visible in marketplace, stored at publicPayloadCid) ─────────\n  name: string\n  description: string\n  image?: string\n  version: string\n  tags: string[]\n  capabilities: string[]\n  supportedTasks: string[]\n  communicationProtocol: 'mcp' | 'a2a'\n  authenticationMethod: 'ecdsa'\n  pricing: AgentPricing\n  /**\n   * Application category / use case (see AGENT_CATEGORIES). Strongly\n   * recommended — marketplace and app launchers filter on it. Agents\n   * without a category are displayed under \"other\".\n   */\n  category?: AgentCategory\n\n  // ── Private (AES-256-GCM encrypted, stored at encryptedPayloadCid) ──────\n  prompt: string\n  skills: SkillDef[]\n  mcp: McpConnection\n}\n\n/** Subset of AgentPayload that is publicly visible */\nexport type AgentPublicPayload = Omit<\n  AgentPayload,\n  'prompt' | 'skills' | 'mcp'\n>\n\n/** Fields that must be encrypted before IPFS upload */\nexport type AgentPrivatePayload = Pick<\n  AgentPayload,\n  'prompt' | 'skills' | 'mcp'\n>\n\n// ── Encrypted Payload (IPFS wire format) ───────────────────────────────────\n\nexport interface EncryptedPayload {\n  encrypted: true\n  algorithm: 'AES-256-GCM'\n  /** base64(iv + ciphertext + authTag) */\n  data: string\n}\n\n// ── On-Chain Metadata (stored in ERC-721 tokenURI attributes) ─────────────\n\nexport interface OnChainAgentMetadata {\n  tokenURI: string\n  attributes: {\n    name: string\n    description: string\n    /** CID of the AES-256-GCM encrypted payload on IPFS */\n    encryptedPayloadCid: string\n    /** ECIES-encrypted AES key (secp256k1, hex string) */\n    eciesEncryptedKey: string\n    /** CID of the public metadata on IPFS */\n    publicPayloadCid: string\n    capabilities: string[]\n    skills: string[]\n    mcpEndpoint: string\n    version: string\n    tags: string[]\n    pricingType: PricingType\n    pricingAmount: string\n    /** Application category / use case (AGENT_CATEGORIES value). */\n    category?: string\n  }\n}\n\n// ── Agent Registry ─────────────────────────────────────────────────────────\n\nexport interface RegisteredAgent {\n  /** ERC-721 token ID (= agentId) */\n  agentId: number\n  /** Owner wallet address */\n  owner: string\n  /** Creator wallet address */\n  creator: string\n  /** Full on-chain metadata */\n  metadata: OnChainAgentMetadata\n  /** Block number where agent was registered */\n  registeredAt: number\n  /** IPFS CID of the full public payload (resolved from tokenURI) */\n  publicPayloadCid: string\n}\n\n// ── Agent Search ───────────────────────────────────────────────────────────\n\nexport interface AgentSearchQuery {\n  keyword?: string\n  capabilities?: string[]\n  tags?: string[]\n  pricingType?: PricingType\n  maxPrice?: string\n  owner?: string\n  sortBy?: 'latest' | 'reputation' | 'price_asc' | 'price_desc'\n  page?: number\n  pageSize?: number\n}\n\nexport interface AgentSearchResult {\n  agents: RegisteredAgent[]\n  total: number\n  page: number\n  pageSize: number\n}\n\n// ── Subscription ───────────────────────────────────────────────────────────\n\nexport type SubscriptionStatus = 'active' | 'expired' | 'cancelled' | 'pending'\n\nexport interface AgentSubscription {\n  subscriptionId: number\n  subscriber: string\n  agentId: number\n  status: SubscriptionStatus\n  startedAt: number\n  expiresAt: number\n  period: string\n}\n\n// ── A2A Protocol ───────────────────────────────────────────────────────────\n\nexport type A2ATaskStatus = 'created' | 'accepted' | 'in_progress' | 'completed' | 'failed'\n\nexport interface A2AAgentCard {\n  agentId: number\n  name: string\n  capabilities: string[]\n  supportedTasks: string[]\n  /** MCP endpoint URL for direct agent-to-agent communication */\n  endpoint: string\n  /** Public key for ECDSA authentication */\n  publicKey: string\n}\n\nexport interface A2ATask {\n  taskId: number\n  /** Agent that created the task */\n  creator: string\n  /** Target agent to execute the task */\n  targetAgentId: number\n  /** Task type (must be in target's supportedTasks) */\n  taskType: string\n  /** JSON input payload */\n  input: string\n  status: A2ATaskStatus\n  result?: string\n  createdAt: number\n  completedAt?: number\n}\n\n// ── Reputation ─────────────────────────────────────────────────────────────\n\nexport interface AgentReputation {\n  agentId: number\n  averageRating: number\n  totalRatings: number\n  reviews: AgentReview[]\n}\n\nexport interface AgentReview {\n  reviewer: string\n  rating: number // 1-5\n  comment: string\n  timestamp: number\n}\n\n// ── AgentX Client Configuration ────────────────────────────────────────────\n\nexport interface AgentXConfig {\n  /** Chain ID (e.g. 11155111 for Sepolia) */\n  chainId: number\n  /** RPC endpoint override (uses viem's default if omitted) */\n  rpcUrl?: string\n  /** Contract addresses for the current chain */\n  contracts: AgentXContracts\n  /** IPFS gateway URLs (ordered by priority) */\n  ipfsGateways: string[]\n  /** Default IPFS pinning service */\n  pinningService?: 'pinata'\n  pinataJwt?: string\n}\n\nexport interface AgentXContracts {\n  identityRegistry: `0x${string}`\n  subscriptionManager: `0x${string}`\n  a2aProtocolRegistry: `0x${string}`\n  reputationRegistry: `0x${string}`\n  configurationRegistry: `0x${string}`\n}\n\n// ── Agent Packing / Unpacking Result ───────────────────────────────────────\n\nexport interface PackResult {\n  /** CID of AES-256-GCM encrypted payload on IPFS */\n  encryptedCid: string\n  /** CID of public metadata on IPFS */\n  publicCid: string\n  /** Raw AES key (hex) — DO NOT share or upload this */\n  aesKeyHex: string\n  /** ECIES-encrypted AES key (hex), safe to store on-chain */\n  eciesEncryptedKeyHex: string\n}\n\nexport interface UnpackResult {\n  /** Decrypted AgentPayload */\n  agent: AgentPayload\n  /** CID where the encrypted payload was fetched from */\n  encryptedCid: string\n  /** CID of the public metadata */\n  publicCid: string\n}\n\n// ── Error Types ────────────────────────────────────────────────────────────\n\nexport enum AgentXErrorCode {\n  NOT_SUBSCRIBED = 'NOT_SUBSCRIBED',\n  SUBSCRIPTION_EXPIRED = 'SUBSCRIPTION_EXPIRED',\n  DECRYPTION_FAILED = 'DECRYPTION_FAILED',\n  IPFS_FETCH_FAILED = 'IPFS_FETCH_FAILED',\n  AGENT_NOT_FOUND = 'AGENT_NOT_FOUND',\n  INVALID_SCHEMA = 'INVALID_SCHEMA',\n  TX_FAILED = 'TX_FAILED',\n  WALLET_NOT_CONNECTED = 'WALLET_NOT_CONNECTED',\n}\n\nexport class AgentXError extends Error {\n  code: AgentXErrorCode\n  /** If NOT_SUBSCRIBED, carry enough info for wallet/X402 auto-payment */\n  paymentInfo?: SubscriptionRequired\n  constructor(code: AgentXErrorCode, message: string) {\n    super(message)\n    this.code = code\n    this.name = 'AgentXError'\n  }\n}\n\n/**\n * Structured info for wallet/X402 auto-subscription.\n * Thrown by AgentRunner.useAgent() when the user/Agent has no\n * active subscription.\n */\nexport interface SubscriptionRequired {\n  agentId: number\n  /** Plan IDs available for this Agent (on-chain query) */\n  plans?: { planId: number; price: bigint; period: string; payToken: string; trialDays: number }[]\n}\n","// ---------------------------------------------------------------------------\n// @agentx/sdk — Agent Runner\n// ---------------------------------------------------------------------------\n// The unified entry point for \"using\" an Agent.\n//\n//   const runner = new AgentRunner({ reader, wallet })\n//   const ctx = await runner.useAgent(42)\n//   // ctx.prompt → system prompt for LLM\n//   // ctx.skills → [{ name, description, inputSchema, execute }]\n//   // ctx.mcp    → MCP connection info\n//\n//   对于 Open Skill：  直接本地执行（源码在解密后的 payload 里）\n//   对于 Closed Skill：通过 MCP 远程调用 → 发布者服务器执行 + 校验订阅\n// ---------------------------------------------------------------------------\n\nimport { eciesEncrypt, generateAesKey } from '../core/crypto'\nimport { unpackAgent } from '../core/crypto'\nimport { IPFSFetcher } from '../registry/ipfs-fetcher'\nimport type {\n  AgentPayload, AgentPrivatePayload,\n  EncryptedPayload, SkillDef,\n  PackResult, SubscriptionRequired,\n} from '../core/types'\nimport { AgentXError, AgentXErrorCode } from '../core/types'\n\n// ── Injected Dependencies (viem / wagmi integration) ───────────────────────\n\n/** Minimal on-chain reader interface — implement with viem. */\nexport interface OnChainReader {\n  /** Read tokenURI from IdentityRegistry by tokenId. */\n  getTokenURI(agentId: number): Promise<string>\n  /** Get agent metadata attributes (returned as key-value pairs). */\n  getAttributes(agentId: number): Promise<Record<string, string>>\n  /** Check if `address` has an active subscription for `agentId`. */\n  hasActiveSubscription(address: string, agentId: number): Promise<boolean>\n}\n\n/** Minimal wallet signer interface — implement with wagmi/viem. */\nexport interface WalletSigner {\n  /** Sign a message (for authentication to MCP servers). */\n  signMessage(message: string): Promise<string>\n  /** Get the current wallet address. */\n  getAddress(): Promise<string>\n  /** Get the wallet's ECDSA private key (required for ECIES decryption). */\n  getPrivateKey?(): Promise<string>\n}\n\n// ── Agent Runner Configuration ─────────────────────────────────────────────\n\nexport interface AgentRunnerConfig {\n  /** On-chain data reader (injected from viem/wagmi). */\n  reader: OnChainReader\n  /** Wallet signer (injected from wagmi). */\n  wallet: WalletSigner\n  /** IPFS fetcher instance (creates default if omitted). */\n  ipfsFetcher?: IPFSFetcher\n  /** IPFS gateway list (overrides IPFSFetcher defaults). */\n  ipfsGateways?: string[]\n}\n\n// ── Run Context (returned by useAgent) ─────────────────────────────────────\n\nexport interface AgentRunContext {\n  /** Agent NFT token ID */\n  agentId: number\n  /** System prompt — inject into LLM conversation */\n  prompt: string\n  /** All skills with execution metadata */\n  skills: RunnableSkill[]\n  /** MCP connection info */\n  mcp: {\n    type: string\n    url?: string\n    toolFilter?: string[]\n  }\n  /** Subscription expiry timestamp (0 = unknown) */\n  subscriptionExpiry: number\n}\n\nexport interface RunnableSkill {\n  name: string\n  description: string\n  inputSchema: Record<string, unknown>\n  outputSchema?: Record<string, unknown>\n  /** Execution mode */\n  mode: 'open' | 'mcp' | 'a2a'\n  /** If mode='a2a', the on-chain Agent ID being delegated to */\n  a2aTargetAgentId?: number\n  /**\n   * Execute this skill with the given input.\n   * - Open: runs locally (caller provides implementation)\n   * - MCP: POSTs to the publisher's MCP server\n   * - A2A: loads target Agent context (prompt+skills) via AgentRunner\n   */\n  execute(input: Record<string, unknown>): Promise<unknown>\n}\n\n// ── A2A Delegation Result ────────────────────────────────────────────────\n\n/**\n * Standard return type for A2A skill execution.\n * The calling LLM receives the sub-Agent's prompt and skills\n * and can inject them into the conversation.\n */\nexport interface A2ASkillResult {\n  /** On-chain Agent ID that was delegated to */\n  agentId: number\n  /** Sub-Agent's decrypted system prompt */\n  prompt: string\n  /** Sub-Agent's skills (name + description + schema only, no execute) */\n  skills: {\n    name: string\n    description: string\n    inputSchema: Record<string, unknown>\n  }[]\n  /** The original input passed by the caller */\n  callerInput: Record<string, unknown>\n}\n\n// ── Agent Runner ───────────────────────────────────────────────────────────\n\nexport class AgentRunner {\n  private reader: OnChainReader\n  private wallet: WalletSigner\n  private ipfs: IPFSFetcher\n\n  constructor(config: AgentRunnerConfig) {\n    this.reader = config.reader\n    this.wallet = config.wallet\n    this.ipfs = config.ipfsFetcher ?? new IPFSFetcher({\n      fallbackGateways: config.ipfsGateways ?? [\n        'gateway.pinata.cloud',\n        'dweb.link',\n        'cf-ipfs.com',\n      ],\n    })\n  }\n\n  // ── Primary API: useAgent ────────────────────────────────────────────────\n\n  /**\n   * Load and decrypt an Agent, returning a run context ready to inject\n   * into any LLM conversation.\n   *\n   * Steps:\n   *   1. Verify on-chain subscription (frontend check)\n   *   2. Fetch metadata → get encryptedPayloadCid + eciesEncryptedKey\n   *   3. IPFS fetch encrypted payload\n   *   4. ECIES decrypt AES key (using wallet private key)\n   *   5. AES-256-GCM decrypt payload → { prompt, skills, mcp }\n   *   6. Build RunnableSkill wrappers (Open: local stub, Closed: MCP remote)\n   */\n  async useAgent(agentId: number): Promise<AgentRunContext> {\n    // 1. Subscription check (frontend — MCP server also checks)\n    const address = await this.wallet.getAddress()\n    const isActive = await this.reader.hasActiveSubscription(address, agentId)\n    if (!isActive) {\n      const err = new AgentXError(\n        AgentXErrorCode.NOT_SUBSCRIBED,\n        `No active subscription for Agent #${agentId}. ` +\n        `Check error.paymentInfo for auto-subscribe via wallet/X402.`,\n      )\n      ;(err as AgentXError & { paymentInfo: SubscriptionRequired }).paymentInfo = {\n        agentId,\n      }\n      throw err\n    }\n\n    // 2. Read on-chain metadata\n    const attrs = await this.reader.getAttributes(agentId)\n    const encryptedPayloadCid = attrs.encryptedPayloadCid\n    const eciesEncryptedKey = attrs.eciesEncryptedKey\n\n    if (!encryptedPayloadCid || !eciesEncryptedKey) {\n      throw new AgentXError(\n        AgentXErrorCode.AGENT_NOT_FOUND,\n        `Agent #${agentId} metadata incomplete — missing encryptedPayloadCid or eciesEncryptedKey`\n      )\n    }\n\n    // 3. Fetch encrypted payload from IPFS\n    let encryptedPayload: EncryptedPayload\n    try {\n      encryptedPayload = await this.ipfs.fetchEncryptedPayload(encryptedPayloadCid)\n    } catch (e) {\n      throw new AgentXError(\n        AgentXErrorCode.IPFS_FETCH_FAILED,\n        `Failed to fetch encrypted payload for agent #${agentId}: ${e}`\n      )\n    }\n\n    // 4 + 5. ECIES + AES decrypt\n    let privatePayload: AgentPrivatePayload\n    try {\n      const privKey = await this._getPrivateKey()\n      privatePayload = unpackAgent(encryptedPayload, eciesEncryptedKey, privKey)\n    } catch (e) {\n      throw new AgentXError(\n        AgentXErrorCode.DECRYPTION_FAILED,\n        `Failed to decrypt agent #${agentId}: ${e}`\n      )\n    }\n\n    // 6. Build runnable skills\n    const skills = privatePayload.skills.map(s => this._wrapSkill(s))\n\n    return {\n      agentId,\n      prompt: privatePayload.prompt,\n      skills,\n      mcp: {\n        type: privatePayload.mcp.type,\n        url: privatePayload.mcp.url,\n        toolFilter: privatePayload.mcp.toolFilter,\n      },\n      subscriptionExpiry: 0,\n    }\n  }\n\n  // ── Publishing ───────────────────────────────────────────────────────────\n\n  /**\n   * Pack an AgentPayload for publishing (encryption only, no IPFS upload).\n   * Caller is responsible for IPFS upload and on-chain registration.\n   */\n  packForPublish(payload: AgentPayload, publicKey: string): PackResult {\n    const key = generateAesKey()\n    return {\n      encryptedCid: '',\n      publicCid: '',\n      aesKeyHex: key,\n      eciesEncryptedKeyHex: eciesEncrypt(key, publicKey),\n    }\n  }\n\n  // ── Internals ────────────────────────────────────────────────────────────\n\n  /** Wrap a SkillDef into a RunnableSkill with execute(). */\n  private _wrapSkill(skill: SkillDef): RunnableSkill {\n    let mode: RunnableSkill['mode'] = 'open'\n    let executeFn: (input: Record<string, unknown>) => Promise<unknown>\n\n    if (skill.execution) {\n      if (skill.execution.type === 'mcp') {\n        mode = 'mcp'\n        const endpoint = skill.execution.endpoint ?? ''\n        const toolName = skill.execution.toolName ?? skill.name\n        executeFn = async (input: Record<string, unknown>) => {\n          return this._executeMCPTool(endpoint, toolName, input)\n        }\n      } else if (skill.execution.type === 'a2a') {\n        mode = 'a2a'\n        executeFn = async (input: Record<string, unknown>) => {\n          return this._executeA2ASkill(skill, input)\n        }\n      } else {\n        throw new AgentXError(\n          AgentXErrorCode.INVALID_SCHEMA,\n          `Unknown execution type \"${(skill.execution as Record<string,string>).type}\" for skill \"${skill.name}\"`\n        )\n      }\n    } else {\n      executeFn = async () => {\n        throw new AgentXError(\n          AgentXErrorCode.INVALID_SCHEMA,\n          `Open skill \"${skill.name}\" has no local executor. ` +\n          `Implement execute() or switch to execution.type = \"mcp\" or \"a2a\".`\n        )\n      }\n    }\n\n    return {\n      name: skill.name,\n      description: skill.description,\n      inputSchema: skill.inputSchema as unknown as Record<string, unknown>,\n      outputSchema: skill.outputSchema as unknown as Record<string, unknown>,\n      mode,\n      execute: executeFn,\n      /** If A2A, carry delegation metadata so the LLM can see it */\n      a2aTargetAgentId: skill.execution?.type === 'a2a' ? (skill.execution as import('../core/types').A2ASkillExecution).targetAgentId : undefined,\n    }\n  }\n\n  /** Call a tool on the publisher's MCP server (Closed skill). */\n  private async _executeMCPTool(\n    endpoint: string,\n    toolName: string,\n    params: Record<string, unknown>\n  ): Promise<unknown> {\n    const address = await this.wallet.getAddress()\n\n    const timestamp = Math.floor(Date.now() / 1000)\n    const message = `agentx:mcp:${toolName}:${timestamp}`\n    const signature = await this.wallet.signMessage(message)\n\n    const res = await fetch(endpoint, {\n      method: 'POST',\n      headers: {\n        'Content-Type': 'application/json',\n        'X-Subscriber-Address': address,\n        'X-Signature': signature,\n        'X-Timestamp': String(timestamp),\n      },\n      body: JSON.stringify({\n        method: 'tools/call',\n        params: {\n          name: toolName,\n          arguments: params,\n        },\n      }),\n    })\n\n    if (!res.ok) {\n      const text = await res.text()\n      if (res.status === 403) {\n        throw new AgentXError(\n          AgentXErrorCode.SUBSCRIPTION_EXPIRED,\n          `MCP server rejected request: subscription may have expired. ${text}`\n        )\n      }\n      throw new AgentXError(\n        AgentXErrorCode.TX_FAILED,\n        `MCP tool \"${toolName}\" failed (HTTP ${res.status}): ${text}`\n      )\n    }\n\n    const data = await res.json() as { content?: { type: string; text?: string }[] }\n    const content = data.content?.[0]\n    if (content?.type === 'text' && content.text) {\n      try {\n        return JSON.parse(content.text)\n      } catch {\n        return content.text\n      }\n    }\n    return data\n  }\n\n  /**\n   * Execute an A2A skill — delegate to another AgentX Agent.\n   *\n   * Standard Interface:\n   *   Input:  { task, ...taskSpecificParams }\n   *   Output: { agentId, prompt, skills[] }\n   *\n   * The caller (LLM) receives the sub-Agent's prompt + skill list.\n   * The LLM then decides how to use the sub-Agent — typically by\n   * injecting the sub-Agent's system prompt and calling its skills.\n   */\n  private async _executeA2ASkill(\n    skill: SkillDef,\n    input: Record<string, unknown>\n  ): Promise<A2ASkillResult> {\n    const exec = skill.execution as import('../core/types').A2ASkillExecution\n    if (!exec || exec.type !== 'a2a') {\n      throw new AgentXError(\n        AgentXErrorCode.INVALID_SCHEMA,\n        `Skill \"${skill.name}\" is not an A2A delegation skill`\n      )\n    }\n\n    const targetAgentId = exec.targetAgentId\n\n    // Load the target Agent's full context\n    let subContext: AgentRunContext\n    try {\n      subContext = await this.useAgent(targetAgentId)\n    } catch (e) {\n      throw new AgentXError(\n        AgentXErrorCode.AGENT_NOT_FOUND,\n        `A2A delegation failed: cannot load Agent #${targetAgentId}. ${e}`\n      )\n    }\n\n    // Apply skill filter if specified\n    if (exec.skillFilter && exec.skillFilter.length > 0) {\n      const filterSet = new Set(exec.skillFilter)\n      subContext = {\n        ...subContext,\n        skills: subContext.skills.filter(s => filterSet.has(s.name)),\n      }\n    }\n\n    // Apply prompt override if specified\n    if (exec.promptOverride) {\n      subContext = { ...subContext, prompt: exec.promptOverride }\n    }\n\n    return {\n      agentId: targetAgentId,\n      prompt: subContext.prompt,\n      skills: subContext.skills.map(s => ({\n        name: s.name,\n        description: s.description,\n        inputSchema: s.inputSchema,\n      })),\n      // Pass the caller's input to the sub-agent's context\n      callerInput: input,\n    }\n  }\n\n  private async _getPrivateKey(): Promise<string> {\n    if (this.wallet.getPrivateKey) return this.wallet.getPrivateKey()\n    throw new AgentXError(\n      AgentXErrorCode.WALLET_NOT_CONNECTED,\n      'Wallet must support getPrivateKey() for ECIES decryption.'\n    )\n  }\n}\n","// ---------------------------------------------------------------------------\n// @agentx/sdk — Configuration\n// ---------------------------------------------------------------------------\n// Wraps ConfigurationRegistry contract for key-value settings.\n// ---------------------------------------------------------------------------\n\nimport { stringToHex, hexToString } from 'viem'\nimport type { PublicClient, WalletClient, Address, Hash } from 'viem'\n\nconst CONFIG_ABI = {\n  setConfig: {\n    inputs: [{ name: 'key', type: 'string' }, { name: 'value', type: 'bytes' }] as const,\n    name: 'setConfig' as const,\n    outputs: [] as const,\n    stateMutability: 'nonpayable' as const,\n    type: 'function' as const,\n  },\n  getConfig: {\n    inputs: [{ name: 'key', type: 'string' }] as const,\n    name: 'getConfig' as const,\n    outputs: [{ name: '', type: 'bytes' }] as const,\n    stateMutability: 'view' as const,\n    type: 'function' as const,\n  },\n  getAllConfig: {\n    inputs: [] as const,\n    name: 'getAllConfig' as const,\n    outputs: [{ name: '', type: 'tuple[]', components: [{ name: 'key', type: 'string' }, { name: 'value', type: 'bytes' }] }] as const,\n    stateMutability: 'view' as const,\n    type: 'function' as const,\n  },\n} as const\n\n// ── Known chain configs ────────────────────────────────────────────────────\n\n// Moves these to a separate file when the list grows.\n\nexport interface ChainConfig {\n  chainId: number\n  contracts: {\n    identityRegistry: Address\n    subscriptionManager: Address\n    a2aProtocolRegistry: Address\n    reputationRegistry: Address\n    configurationRegistry: Address\n    multiEndpointRegistry: Address\n  }\n  ipfsGateways: string[]\n  rpcUrl?: string\n}\n\nexport const KNOWN_CHAINS: Record<number, ChainConfig> = {\n  // Sepolia Testnet\n  // v3 (deployed 2026-07-13): platformFee=250bps(2.5%), ReentrancyGuard, audit fixes\n  11155111: {\n    chainId: 11155111,\n    contracts: {\n      identityRegistry: '0xe94ad380d3F8d08a7590eda0C84f354a93F96e5F',\n      subscriptionManager: '0xC15fE80b9d800abb72121F353a6ae6d6E9077E63',\n      a2aProtocolRegistry: '0x309C7447d89f3087A9924BB686d88df020F7e9cB',\n      reputationRegistry: '0xeb6B410ea71b8d9dA0c96f6A91d35027CE143DC9',\n      configurationRegistry: '0x68DcE00e4C9077c94BC68016cD14B09557faEA6c',\n      multiEndpointRegistry: '0xEB5e866f186d4B73F97aa0d70B86f2C6e2e21Cb7',\n    },\n    ipfsGateways: ['ipfs.io', 'gateway.pinata.cloud', 'dweb.link', 'cf-ipfs.com'],\n  },\n\n  // OxaChain L1 Mainnet\n  // Chain ID 19505, Clique PoA, Shanghai+Cancun, gas token OXA\n  // Deployer: 0x8E869A0624fF9e766Df71b5B08897d00E4d260ba\n  // RPC: https://rpc-oxa.0xainet.top\n  // Explorer: https://explorer-oxa.0xainet.top\n  // All 6 core contracts deployed 2026-07-14\n  19505: {\n    chainId: 19505,\n    contracts: {\n      identityRegistry: '0xbf5F9db266c8c97E3334466C88597Eb758AfE212',\n      subscriptionManager: '0x019AC9d945467478Dd371CDbD70cb2f325800E6B',\n      a2aProtocolRegistry: '0x7F42a7dC4A0F3C107664C3750bE1B5B6fa6BEb86',\n      reputationRegistry: '0x6a18C2664E1b42063860d864b6448b824d7B843F',\n      configurationRegistry: '0x07280674ccc2898Fd038A9e3C22005CA83ffD2F8',\n      multiEndpointRegistry: '0xB361d04F49000013FC131D3C59C41c8486C64f8c',\n    },\n    ipfsGateways: ['ipfs.io', 'gateway.pinata.cloud', 'dweb.link', 'cf-ipfs.com'],\n    rpcUrl: 'https://rpc-oxa.0xainet.top',\n  },\n}\n\n// ── Config Registry ────────────────────────────────────────────────────────\n\nexport interface ConfigRegistryOpts {\n  contractAddress: Address\n  publicClient: PublicClient\n  walletClient: WalletClient\n}\n\nexport class ConfigurationRegistry {\n  private address: Address\n  private publicClient: PublicClient\n  private walletClient: WalletClient\n\n  constructor(opts: ConfigRegistryOpts) {\n    this.address = opts.contractAddress\n    this.publicClient = opts.publicClient\n    this.walletClient = opts.walletClient\n  }\n\n  private get account(): Promise<Address> {\n    return this.walletClient.getAddresses().then(a => {\n      if (!a[0]) throw new Error('Wallet not connected')\n      return a[0]\n    })\n  }\n\n  async set(key: string, value: string): Promise<Hash> {\n    const acct = await this.account\n    const { request } = await this.publicClient.simulateContract({\n      account: acct,\n      address: this.address,\n      abi: [CONFIG_ABI.setConfig],\n      functionName: 'setConfig',\n      args: [key, stringToHex(value)],\n    })\n    return this.walletClient.writeContract(request)\n  }\n\n  async get(key: string): Promise<string> {\n    const r = await this.publicClient.readContract({\n      address: this.address,\n      abi: [CONFIG_ABI.getConfig],\n      functionName: 'getConfig',\n      args: [key],\n    })\n    return hexToString(r as `0x${string}`)\n  }\n\n  async getAll(): Promise<Record<string, string>> {\n    const r = await this.publicClient.readContract({\n      address: this.address,\n      abi: [CONFIG_ABI.getAllConfig],\n      functionName: 'getAllConfig',\n    })\n    const map: Record<string, string> = {}\n    for (const { key, value } of r as { key: string; value: string }[]) {\n      map[key] = hexToString(value as `0x${string}`)\n    }\n    return map\n  }\n}\n"],"mappings":";;;;;;;;AAaA,SAAS,UAAU,WAAW,cAAc;AAC5C,SAAS,iBAAiB,uBAAuB;;;ACCjD,SAAS,WAAW;AACpB,SAAS,iBAAiB;AAC1B,SAAS,cAAc;AACvB,SAAS,YAAY;AACrB,SAAS,YAAY;AACrB,SAAS,YAAY,kBAAkB;AAIhC,SAAS,YAAY,QAA4B;AAEtD,MAAI,OAAO,WAAW,eAAe,OAAO,iBAAiB;AAC3D,UAAM,MAAM,IAAI,WAAW,MAAM;AACjC,WAAO,gBAAgB,GAAG;AAC1B,WAAO;AAAA,EACT;AAGA,QAAM,aAAa,UAAQ,QAAQ;AACnC,SAAO,IAAI,WAAW,WAAW,YAAY,MAAM,CAAC;AACtD;AAWA,IAAM,eAAe;AACrB,IAAM,UAAU;AAChB,IAAM,WAAW;AAYjB,SAAS,WAAW,KAAyB;AAC3C,MAAI,OAAO,WAAW,YAAa,QAAO,IAAI,WAAW,OAAO,KAAK,KAAK,QAAQ,CAAC;AACnF,QAAM,SAAS,KAAK,GAAG;AACvB,QAAM,QAAQ,IAAI,WAAW,OAAO,MAAM;AAC1C,WAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,IAAK,OAAM,CAAC,IAAI,OAAO,WAAW,CAAC;AACtE,SAAO;AACT;AA+BO,SAAS,WAAW,iBAAyB,QAAwB;AAC1E,QAAM,MAAM,WAAW,MAAM;AAC7B,QAAM,WAAW,WAAW,eAAe;AAE3C,QAAM,KAAK,SAAS,SAAS,GAAG,OAAO;AACvC,QAAM,aAAa,SAAS,SAAS,SAAS,CAAC,QAAQ;AACvD,QAAM,UAAU,SAAS,SAAS,CAAC,QAAQ;AAE3C,QAAM,SAAS,IAAI,KAAK,EAAE;AAE1B,QAAM,oBAAoB,IAAI,WAAW,WAAW,SAAS,QAAQ;AACrE,oBAAkB,IAAI,YAAY,CAAC;AACnC,oBAAkB,IAAI,SAAS,WAAW,MAAM;AAEhD,QAAM,YAAY,OAAO,QAAQ,iBAAiB;AAClD,SAAO,IAAI,YAAY,EAAE,OAAO,SAAS;AAC3C;AAoDO,SAAS,iBAAyB;AACvC,SAAO,WAAW,YAAY,YAAY,CAAC;AAC7C;AAWA,SAAS,YACP,cACA,IACA,YACA,KACQ;AACR,QAAM,MAAM,IAAI,WAAW,KAAK,KAAK,WAAW,SAAS,EAAE;AAC3D,MAAI,IAAI,cAAc,CAAC;AACvB,MAAI,IAAI,IAAI,EAAE;AACd,MAAI,IAAI,YAAY,KAAK,EAAE;AAC3B,MAAI,IAAI,KAAK,KAAK,KAAK,WAAW,MAAM;AACxC,SAAO,WAAW,GAAG;AACvB;AAEA,SAAS,YAAY,SAKnB;AACA,QAAM,IAAI,WAAW,OAAO;AAC5B,SAAO;AAAA,IACL,cAAc,EAAE,SAAS,GAAG,EAAE;AAAA,IAC9B,IAAI,EAAE,SAAS,IAAI,EAAE;AAAA,IACrB,YAAY,EAAE,SAAS,IAAI,GAAG;AAAA,IAC9B,KAAK,EAAE,SAAS,GAAG;AAAA,EACrB;AACF;AAGA,SAAS,cAAc,KAAiB,UAAsB,MAA8B;AAC1F,QAAM,YAAY;AAClB,QAAM,SAAS,IAAI,KAAK,QAAQ;AAGhC,QAAM,SAAS,IAAI,WAAW,KAAK,MAAM;AACzC,QAAM,UAAU,IAAI,WAAW,SAAS;AACxC,UAAQ,IAAI,QAAQ;AACpB,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK,WAAW;AAC/C,UAAM,YAAY,IAAI,KAAK,OAAO,EAAE,QAAQ,IAAI,WAAW,SAAS,CAAC;AACrE,aAAS,IAAI,GAAG,IAAI,aAAa,IAAI,IAAI,KAAK,QAAQ,KAAK;AACzD,aAAO,IAAI,CAAC,IAAI,UAAU,CAAC,IAAK,KAAK,IAAI,CAAC;AAAA,IAC5C;AAEA,aAAS,IAAI,YAAY,GAAG,KAAK,GAAG,KAAK;AACvC,YAAM,MAAM,QAAQ,CAAC;AACrB,UAAI,QAAQ,QAAW;AACrB,gBAAQ,CAAC,IAAK,MAAM,IAAK;AACzB,YAAI,QAAQ,CAAC,MAAM,EAAG;AAAA,MACxB;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAQO,SAAS,aAAa,SAAiB,WAA2B;AAEvE,QAAM,UAAU,YAAY,EAAE;AAC9B,QAAM,SAAS,UAAU,aAAa,SAAS,IAAI;AAGnD,MAAI;AACJ,MAAI,UAAU,WAAW,IAAI,KAAK,UAAU,WAAW,KAAK;AAC1D,mBAAe,WAAW,SAAS;AAAA,EACrC,WAAW,UAAU,WAAW,IAAI,KAAK,UAAU,WAAW,IAAI,GAAG;AACnE,mBAAe,WAAW,SAAS;AAAA,EACrC,OAAO;AACL,UAAM,IAAI,MAAM,8DAA8D;AAAA,EAChF;AAGA,QAAM,SAAS,UAAU,gBAAgB,SAAS,YAAY;AAC9D,QAAM,UAAU,OAAO,SAAS,GAAG,EAAE;AACrC,QAAM,YAAY,OAAO,OAAO;AAGhC,QAAM,UAAU,KAAK,QAAQ,WAAW,QAAW,QAAW,EAAE;AAChE,QAAM,SAAS,QAAQ,SAAS,GAAG,EAAE;AACrC,QAAM,SAAS,QAAQ,SAAS,IAAI,EAAE;AAGtC,QAAM,KAAK,YAAY,EAAE;AACzB,QAAM,YAAY,WAAW,OAAO;AACpC,QAAM,aAAa,cAAc,QAAQ,IAAI,SAAS;AAGtD,QAAM,WAAW,IAAI,WAAW,KAAK,KAAK,WAAW,MAAM;AAC3D,WAAS,IAAI,QAAQ,CAAC;AACtB,WAAS,IAAI,IAAI,EAAE;AACnB,WAAS,IAAI,YAAY,KAAK,EAAE;AAChC,QAAM,MAAM,KAAK,QAAQ,QAAQ,QAAQ;AAEzC,SAAO,YAAY,QAAQ,IAAI,YAAY,GAAG;AAChD;AAKO,SAAS,aAAa,SAAiB,YAA4B;AACxE,QAAM,EAAE,cAAc,IAAI,YAAY,IAAI,IAAI,YAAY,OAAO;AAGjE,QAAM,YAAY,WAAW,UAAU;AACvC,QAAM,SAAS,UAAU,gBAAgB,WAAW,YAAY;AAChE,QAAM,UAAU,OAAO,SAAS,GAAG,EAAE;AACrC,QAAM,YAAY,OAAO,OAAO;AAGhC,QAAM,UAAU,KAAK,QAAQ,WAAW,QAAW,QAAW,EAAE;AAChE,QAAM,SAAS,QAAQ,SAAS,GAAG,EAAE;AACrC,QAAM,SAAS,QAAQ,SAAS,IAAI,EAAE;AAGtC,QAAM,WAAW,IAAI,WAAW,KAAK,KAAK,WAAW,MAAM;AAC3D,WAAS,IAAI,cAAc,CAAC;AAC5B,WAAS,IAAI,IAAI,EAAE;AACnB,WAAS,IAAI,YAAY,KAAK,EAAE;AAChC,QAAM,cAAc,KAAK,QAAQ,QAAQ,QAAQ;AACjD,MAAI,CAAC,kBAAkB,KAAK,WAAW,GAAG;AACxC,UAAM,IAAI,MAAM,uCAAuC;AAAA,EACzD;AAGA,QAAM,YAAY,cAAc,QAAQ,IAAI,UAAU;AACtD,SAAO,WAAW,SAAS;AAC7B;AAEA,SAAS,kBAAkB,GAAe,GAAwB;AAChE,MAAI,EAAE,WAAW,EAAE,OAAQ,QAAO;AAClC,MAAI,OAAO;AACX,WAAS,IAAI,GAAG,IAAI,EAAE,QAAQ,IAAK,SAAQ,EAAE,CAAC,IAAK,EAAE,CAAC;AACtD,SAAO,SAAS;AAClB;AAsBO,SAAS,eACd,WACA,QACqB;AACrB,MAAI,UAAU,cAAc,eAAe;AACzC,UAAM,IAAI,MAAM,0BAA0B,UAAU,SAAS,EAAE;AAAA,EACjE;AACA,SAAO,KAAK,MAAM,WAAW,UAAU,MAAM,MAAM,CAAC;AACtD;AA6HO,SAAS,YACd,kBACA,mBACA,YACqB;AACrB,QAAM,YAAY,aAAa,mBAAmB,UAAU;AAC5D,SAAO,eAAe,kBAAkB,SAAS;AACnD;;;ACjcO,IAAM,cAAN,MAAkB;AAAA,EACf;AAAA,EACA;AAAA,EACA;AAAA,EAEA,QAAQ,oBAAI,IAAiC;AAAA,EAC7C;AAAA,EACA,UAAU,oBAAI,IAA8B;AAAA,EAC5C,SAAS,oBAAI,IAAY;AAAA,EAEjC,YAAY,SAA4B,CAAC,GAAG;AAC1C,SAAK,UAAU,OAAO,WAAW;AACjC,SAAK,mBAAmB,OAAO,oBAAoB;AAAA,MACjD;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,SAAK,YAAY,OAAO,aAAa;AACrC,SAAK,WAAW,OAAO,YAAY;AAAA,EACrC;AAAA;AAAA;AAAA,EAKA,MAAM,UAAuB,KAAyB;AACpD,UAAM,SAAS,KAAK,MAAM,IAAI,GAAG;AACjC,QAAI,OAAQ,QAAO,OAAO;AAE1B,QAAI,KAAK,OAAO,IAAI,GAAG,EAAG,OAAM,IAAI,MAAM,OAAO,GAAG,oBAAoB;AAExE,UAAM,UAAU,KAAK,QAAQ,IAAI,GAAG;AACpC,QAAI,QAAS,QAAO;AAEpB,UAAM,UAAU,KAAK,SAAY,GAAG;AACpC,SAAK,QAAQ,IAAI,KAAK,OAAO;AAE7B,QAAI;AACF,YAAM,OAAO,MAAM;AACnB,WAAK,UAAU,KAAK,IAAI;AACxB,aAAO;AAAA,IACT,SAAS,GAAG;AACV,WAAK,OAAO,IAAI,GAAG;AACnB,YAAM;AAAA,IACR,UAAE;AACA,WAAK,QAAQ,OAAO,GAAG;AAAA,IACzB;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,sBAAsB,KAAwC;AAClE,UAAM,MAAM,MAAM,KAAK,UAAmC,GAAG;AAC7D,QAAI,CAAC,IAAI,aAAa,IAAI,cAAc,iBAAiB,OAAO,IAAI,SAAS,UAAU;AACrF,YAAM,IAAI,MAAM,mCAAmC,GAAG,EAAE;AAAA,IAC1D;AACA,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,MAAM,WAAwB,MAAgB,cAAc,GAA4B;AACtF,UAAM,UAAU,oBAAI,IAAe;AACnC,UAAM,SAAS,CAAC,GAAG,IAAI,IAAI,IAAI,CAAC,EAAE,OAAO,OAAK,KAAK,WAAW,CAAC,CAAC;AAEhE,aAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK,aAAa;AACnD,YAAM,QAAQ,OAAO,MAAM,GAAG,IAAI,WAAW;AAC7C,YAAM,UAAU,MAAM,QAAQ;AAAA,QAC5B,MAAM,IAAI,SAAO,KAAK,UAAa,GAAG,CAAC;AAAA,MACzC;AACA,cAAQ,QAAQ,CAAC,GAAG,MAAM;AACxB,YAAI,EAAE,WAAW,YAAa,SAAQ,IAAI,MAAM,CAAC,GAAI,EAAE,KAAK;AAAA,MAC9D,CAAC;AACD,UAAI,IAAI,cAAc,OAAO,QAAQ;AACnC,cAAM,IAAI,QAAQ,OAAK,WAAW,GAAG,GAAG,CAAC;AAAA,MAC3C;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,WAAW,KAAsB;AAC/B,WAAO,oEAAoE,KAAK,GAAG;AAAA,EACrF;AAAA;AAAA,EAGA,WAAW,KAAoB;AAC7B,QAAI,KAAK;AACP,WAAK,MAAM,OAAO,GAAG;AAAA,IACvB,OAAO;AACL,WAAK,MAAM,MAAM;AAAA,IACnB;AACA,SAAK,OAAO,MAAM;AAAA,EACpB;AAAA;AAAA,EAGA,IAAI,YAAoB;AACtB,WAAO,KAAK,MAAM;AAAA,EACpB;AAAA;AAAA,EAIA,MAAc,SAAY,KAAyB;AACjD,QAAI,CAAC,KAAK,WAAW,GAAG,EAAG,OAAM,IAAI,MAAM,gBAAgB,GAAG,EAAE;AAGhE,QAAI;AACF,aAAO,MAAM,KAAK,WAAW,KAAK,KAAK,SAAS,KAAK,SAAS;AAAA,IAChE,QAAQ;AAAA,IAER;AAGA,eAAW,MAAM,KAAK,kBAAkB;AACtC,UAAI;AACF,eAAO,MAAM,KAAK,WAAW,KAAK,IAAI,KAAK,SAAS;AAAA,MACtD,QAAQ;AAAA,MAER;AAAA,IACF;AAEA,UAAM,IAAI,MAAM,oCAAoC,GAAG,EAAE;AAAA,EAC3D;AAAA,EAEA,MAAc,WAAc,KAAa,SAAiB,WAA+B;AACvF,UAAM,MAAM,WAAW,OAAO,SAAS,GAAG;AAC1C,UAAM,MAAM,MAAM,MAAM,KAAK;AAAA,MAC3B,SAAS,EAAE,QAAQ,mBAAmB;AAAA,MACtC,QAAQ,YAAY,QAAQ,SAAS;AAAA,IACvC,CAAC;AACD,QAAI,CAAC,IAAI,GAAI,OAAM,IAAI,MAAM,QAAQ,IAAI,MAAM,EAAE;AACjD,WAAQ,MAAM,IAAI,KAAK;AAAA,EACzB;AAAA,EAEQ,UAAU,KAAa,MAAqB;AAClD,SAAK,MAAM,IAAI,KAAK,EAAE,MAAM,WAAW,KAAK,IAAI,EAAE,CAAC;AAEnD,QAAI,KAAK,MAAM,OAAO,KAAK,UAAU;AACnC,YAAM,SAAS,CAAC,GAAG,KAAK,MAAM,QAAQ,CAAC,EAAE;AAAA,QACvC,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE;AAAA,MAClC,EAAE,CAAC;AACH,UAAI,OAAQ,MAAK,MAAM,OAAO,OAAO,CAAC,CAAC;AAAA,IACzC;AAAA,EACF;AACF;AAGO,IAAM,qBAAqB,IAAI,YAAY;;;ACiN3C,IAAM,cAAN,cAA0B,MAAM;AAAA,EACrC;AAAA;AAAA,EAEA;AAAA,EACA,YAAY,MAAuB,SAAiB;AAClD,UAAM,OAAO;AACb,SAAK,OAAO;AACZ,SAAK,OAAO;AAAA,EACd;AACF;;;AC9QO,IAAM,cAAN,MAAkB;AAAA,EACf;AAAA,EACA;AAAA,EACA;AAAA,EAER,YAAY,QAA2B;AACrC,SAAK,SAAS,OAAO;AACrB,SAAK,SAAS,OAAO;AACrB,SAAK,OAAO,OAAO,eAAe,IAAI,YAAY;AAAA,MAChD,kBAAkB,OAAO,gBAAgB;AAAA,QACvC;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBA,MAAM,SAAS,SAA2C;AAExD,UAAM,UAAU,MAAM,KAAK,OAAO,WAAW;AAC7C,UAAM,WAAW,MAAM,KAAK,OAAO,sBAAsB,SAAS,OAAO;AACzE,QAAI,CAAC,UAAU;AACb,YAAM,MAAM,IAAI;AAAA;AAAA,QAEd,qCAAqC,OAAO;AAAA,MAE9C;AACC,MAAC,IAA4D,cAAc;AAAA,QAC1E;AAAA,MACF;AACA,YAAM;AAAA,IACR;AAGA,UAAM,QAAQ,MAAM,KAAK,OAAO,cAAc,OAAO;AACrD,UAAM,sBAAsB,MAAM;AAClC,UAAM,oBAAoB,MAAM;AAEhC,QAAI,CAAC,uBAAuB,CAAC,mBAAmB;AAC9C,YAAM,IAAI;AAAA;AAAA,QAER,UAAU,OAAO;AAAA,MACnB;AAAA,IACF;AAGA,QAAI;AACJ,QAAI;AACF,yBAAmB,MAAM,KAAK,KAAK,sBAAsB,mBAAmB;AAAA,IAC9E,SAAS,GAAG;AACV,YAAM,IAAI;AAAA;AAAA,QAER,gDAAgD,OAAO,KAAK,CAAC;AAAA,MAC/D;AAAA,IACF;AAGA,QAAI;AACJ,QAAI;AACF,YAAM,UAAU,MAAM,KAAK,eAAe;AAC1C,uBAAiB,YAAY,kBAAkB,mBAAmB,OAAO;AAAA,IAC3E,SAAS,GAAG;AACV,YAAM,IAAI;AAAA;AAAA,QAER,4BAA4B,OAAO,KAAK,CAAC;AAAA,MAC3C;AAAA,IACF;AAGA,UAAM,SAAS,eAAe,OAAO,IAAI,OAAK,KAAK,WAAW,CAAC,CAAC;AAEhE,WAAO;AAAA,MACL;AAAA,MACA,QAAQ,eAAe;AAAA,MACvB;AAAA,MACA,KAAK;AAAA,QACH,MAAM,eAAe,IAAI;AAAA,QACzB,KAAK,eAAe,IAAI;AAAA,QACxB,YAAY,eAAe,IAAI;AAAA,MACjC;AAAA,MACA,oBAAoB;AAAA,IACtB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,eAAe,SAAuB,WAA+B;AACnE,UAAM,MAAM,eAAe;AAC3B,WAAO;AAAA,MACL,cAAc;AAAA,MACd,WAAW;AAAA,MACX,WAAW;AAAA,MACX,sBAAsB,aAAa,KAAK,SAAS;AAAA,IACnD;AAAA,EACF;AAAA;AAAA;AAAA,EAKQ,WAAW,OAAgC;AACjD,QAAI,OAA8B;AAClC,QAAI;AAEJ,QAAI,MAAM,WAAW;AACnB,UAAI,MAAM,UAAU,SAAS,OAAO;AAClC,eAAO;AACP,cAAM,WAAW,MAAM,UAAU,YAAY;AAC7C,cAAM,WAAW,MAAM,UAAU,YAAY,MAAM;AACnD,oBAAY,OAAO,UAAmC;AACpD,iBAAO,KAAK,gBAAgB,UAAU,UAAU,KAAK;AAAA,QACvD;AAAA,MACF,WAAW,MAAM,UAAU,SAAS,OAAO;AACzC,eAAO;AACP,oBAAY,OAAO,UAAmC;AACpD,iBAAO,KAAK,iBAAiB,OAAO,KAAK;AAAA,QAC3C;AAAA,MACF,OAAO;AACL,cAAM,IAAI;AAAA;AAAA,UAER,2BAA4B,MAAM,UAAoC,IAAI,gBAAgB,MAAM,IAAI;AAAA,QACtG;AAAA,MACF;AAAA,IACF,OAAO;AACL,kBAAY,YAAY;AACtB,cAAM,IAAI;AAAA;AAAA,UAER,eAAe,MAAM,IAAI;AAAA,QAE3B;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,MACL,MAAM,MAAM;AAAA,MACZ,aAAa,MAAM;AAAA,MACnB,aAAa,MAAM;AAAA,MACnB,cAAc,MAAM;AAAA,MACpB;AAAA,MACA,SAAS;AAAA;AAAA,MAET,kBAAkB,MAAM,WAAW,SAAS,QAAS,MAAM,UAAwD,gBAAgB;AAAA,IACrI;AAAA,EACF;AAAA;AAAA,EAGA,MAAc,gBACZ,UACA,UACA,QACkB;AAClB,UAAM,UAAU,MAAM,KAAK,OAAO,WAAW;AAE7C,UAAM,YAAY,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI;AAC9C,UAAM,UAAU,cAAc,QAAQ,IAAI,SAAS;AACnD,UAAM,YAAY,MAAM,KAAK,OAAO,YAAY,OAAO;AAEvD,UAAM,MAAM,MAAM,MAAM,UAAU;AAAA,MAChC,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,gBAAgB;AAAA,QAChB,wBAAwB;AAAA,QACxB,eAAe;AAAA,QACf,eAAe,OAAO,SAAS;AAAA,MACjC;AAAA,MACA,MAAM,KAAK,UAAU;AAAA,QACnB,QAAQ;AAAA,QACR,QAAQ;AAAA,UACN,MAAM;AAAA,UACN,WAAW;AAAA,QACb;AAAA,MACF,CAAC;AAAA,IACH,CAAC;AAED,QAAI,CAAC,IAAI,IAAI;AACX,YAAM,OAAO,MAAM,IAAI,KAAK;AAC5B,UAAI,IAAI,WAAW,KAAK;AACtB,cAAM,IAAI;AAAA;AAAA,UAER,+DAA+D,IAAI;AAAA,QACrE;AAAA,MACF;AACA,YAAM,IAAI;AAAA;AAAA,QAER,aAAa,QAAQ,kBAAkB,IAAI,MAAM,MAAM,IAAI;AAAA,MAC7D;AAAA,IACF;AAEA,UAAM,OAAO,MAAM,IAAI,KAAK;AAC5B,UAAM,UAAU,KAAK,UAAU,CAAC;AAChC,QAAI,SAAS,SAAS,UAAU,QAAQ,MAAM;AAC5C,UAAI;AACF,eAAO,KAAK,MAAM,QAAQ,IAAI;AAAA,MAChC,QAAQ;AACN,eAAO,QAAQ;AAAA,MACjB;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,MAAc,iBACZ,OACA,OACyB;AACzB,UAAM,OAAO,MAAM;AACnB,QAAI,CAAC,QAAQ,KAAK,SAAS,OAAO;AAChC,YAAM,IAAI;AAAA;AAAA,QAER,UAAU,MAAM,IAAI;AAAA,MACtB;AAAA,IACF;AAEA,UAAM,gBAAgB,KAAK;AAG3B,QAAI;AACJ,QAAI;AACF,mBAAa,MAAM,KAAK,SAAS,aAAa;AAAA,IAChD,SAAS,GAAG;AACV,YAAM,IAAI;AAAA;AAAA,QAER,6CAA6C,aAAa,KAAK,CAAC;AAAA,MAClE;AAAA,IACF;AAGA,QAAI,KAAK,eAAe,KAAK,YAAY,SAAS,GAAG;AACnD,YAAM,YAAY,IAAI,IAAI,KAAK,WAAW;AAC1C,mBAAa;AAAA,QACX,GAAG;AAAA,QACH,QAAQ,WAAW,OAAO,OAAO,OAAK,UAAU,IAAI,EAAE,IAAI,CAAC;AAAA,MAC7D;AAAA,IACF;AAGA,QAAI,KAAK,gBAAgB;AACvB,mBAAa,EAAE,GAAG,YAAY,QAAQ,KAAK,eAAe;AAAA,IAC5D;AAEA,WAAO;AAAA,MACL,SAAS;AAAA,MACT,QAAQ,WAAW;AAAA,MACnB,QAAQ,WAAW,OAAO,IAAI,QAAM;AAAA,QAClC,MAAM,EAAE;AAAA,QACR,aAAa,EAAE;AAAA,QACf,aAAa,EAAE;AAAA,MACjB,EAAE;AAAA;AAAA,MAEF,aAAa;AAAA,IACf;AAAA,EACF;AAAA,EAEA,MAAc,iBAAkC;AAC9C,QAAI,KAAK,OAAO,cAAe,QAAO,KAAK,OAAO,cAAc;AAChE,UAAM,IAAI;AAAA;AAAA,MAER;AAAA,IACF;AAAA,EACF;AACF;;;ACrWO,IAAM,eAA4C;AAAA;AAAA;AAAA,EAGvD,UAAU;AAAA,IACR,SAAS;AAAA,IACT,WAAW;AAAA,MACT,kBAAkB;AAAA,MAClB,qBAAqB;AAAA,MACrB,qBAAqB;AAAA,MACrB,oBAAoB;AAAA,MACpB,uBAAuB;AAAA,MACvB,uBAAuB;AAAA,IACzB;AAAA,IACA,cAAc,CAAC,WAAW,wBAAwB,aAAa,aAAa;AAAA,EAC9E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,OAAO;AAAA,IACL,SAAS;AAAA,IACT,WAAW;AAAA,MACT,kBAAkB;AAAA,MAClB,qBAAqB;AAAA,MACrB,qBAAqB;AAAA,MACrB,oBAAoB;AAAA,MACpB,uBAAuB;AAAA,MACvB,uBAAuB;AAAA,IACzB;AAAA,IACA,cAAc,CAAC,WAAW,wBAAwB,aAAa,aAAa;AAAA,IAC5E,QAAQ;AAAA,EACV;AACF;;;AL7DA,IAAM,wBAAwB;AAAA;AAAA,EAE5B;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,iBAAiB;AAAA,IACjB,QAAQ,CAAC,EAAE,MAAM,WAAW,MAAM,UAAU,CAAC;AAAA,IAC7C,SAAS;AAAA,MACP;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,YAAY;AAAA,UACV,EAAE,MAAM,OAAO,MAAM,SAAS;AAAA,UAC9B,EAAE,MAAM,SAAS,MAAM,QAAQ;AAAA,QACjC;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAIA,IAAM,2BAA2B;AAAA,EAC/B;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,iBAAiB;AAAA,IACjB,QAAQ;AAAA,MACN,EAAE,MAAM,cAAc,MAAM,UAAU;AAAA,MACtC,EAAE,MAAM,WAAW,MAAM,UAAU;AAAA,IACrC;AAAA,IACA,SAAS,CAAC,EAAE,MAAM,IAAI,MAAM,OAAO,CAAC;AAAA,EACtC;AACF;AAoBA,IAAM,oBAAN,MAAiD;AAAA,EAC/C,YACU,cACA,aACR;AAFQ;AACA;AAAA,EACP;AAAA,EAFO;AAAA,EACA;AAAA,EAGV,MAAM,YAAY,UAAmC;AAGnD,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,cAAc,SAAkD;AACpE,QAAI,CAAC,KAAK,aAAc,OAAM,IAAI,MAAM,6BAA6B;AAErE,UAAM,UAAW,MAAM,KAAK,aAAa,aAAa;AAAA,MACpD,SAAS,KAAK,YAAY,UAAU;AAAA,MACpC,KAAK;AAAA,MACL,cAAc;AAAA,MACd,MAAM,CAAC,OAAO,OAAO,CAAC;AAAA,IACxB,CAAC;AAED,UAAM,QAAgC,CAAC;AACvC,eAAW,SAAS,SAAS;AAE3B,YAAM,SAAS,MAAM;AACrB,UAAI,UAAU,WAAW,MAAM;AAC7B,cAAM,MAAM,GAAG,IAAI,gBAAgB,MAAM;AAAA,MAC3C,OAAO;AACL,cAAM,MAAM,GAAG,IAAI;AAAA,MACrB;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,sBAAsB,SAAiB,SAAmC;AAC9E,QAAI,CAAC,KAAK,aAAc,QAAO;AAE/B,QAAI;AACF,aAAQ,MAAM,KAAK,aAAa,aAAa;AAAA,QAC3C,SAAS,KAAK,YAAY,UAAU;AAAA,QACpC,KAAK;AAAA,QACL,cAAc;AAAA,QACd,MAAM,CAAC,SAAoB,OAAO,OAAO,CAAC;AAAA,MAC5C,CAAC;AAAA,IACH,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AACF;AAIA,SAAS,gBAAgB,KAAqB;AAC5C,MAAI,CAAC,IAAI,WAAW,IAAI,EAAG,QAAO;AAClC,QAAM,WAAW,IAAI,MAAM,CAAC;AAC5B,MAAI,SAAS,WAAW,EAAG,QAAO;AAClC,MAAI;AACF,UAAM,QAAQ,IAAI,WAAW,SAAS,SAAS,CAAC;AAChD,aAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,YAAM,CAAC,IAAI,SAAS,SAAS,UAAU,IAAI,GAAG,IAAI,IAAI,CAAC,GAAG,EAAE;AAAA,IAC9D;AACA,WAAO,IAAI,YAAY,EAAE,OAAO,KAAK;AAAA,EACvC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAIO,SAAS,eAAe,QAAoD;AACjF,QAAM,EAAE,SAAS,aAAa,qBAAqB,aAAa,IAAI;AAEpE,QAAM,eAAe,gBAAgB;AACrC,QAAM,EAAE,MAAM,aAAa,IAAI,gBAAgB;AAE/C,QAAM,CAAC,KAAK,MAAM,IAAI,SAAiC,IAAI;AAC3D,QAAM,CAAC,WAAW,YAAY,IAAI,SAAS,KAAK;AAChD,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAuB,IAAI;AACrD,QAAM,CAAC,YAAY,aAAa,IAAI,SAAS,CAAC;AAE9C,QAAM,YAAY,OAA2B,IAAI;AACjD,QAAM,aAAa,OAAO,IAAI;AAE9B,YAAU,MAAM;AACd,eAAW,UAAU;AACrB,WAAO,MAAM;AACX,iBAAW,UAAU;AAAA,IACvB;AAAA,EACF,GAAG,CAAC,CAAC;AAEL,YAAU,MAAM;AACd,QAAI,CAAC,gBAAgB,CAAC,cAAc;AAClC,eAAS,IAAI,MAAM,sBAAsB,CAAC;AAC1C;AAAA,IACF;AAEA,UAAM,cACJ,wBAAwB,aAAa,OAAO,KAAK,aAAa,aAAa,MAAM,EAAE,IAAI;AAEzF,QAAI,CAAC,aAAa;AAChB,eAAS,IAAI,MAAM,SAAS,aAAa,OAAO,EAAE,gBAAgB,CAAC;AACnE;AAAA,IACF;AAGA,UAAM,SAAS,IAAI,kBAAkB,cAAc,WAAW;AAG9D,UAAM,SAAS;AAAA,MACb,MAAM,YAAY,SAAkC;AAClD,YAAI,CAAC,aAAa,QAAS,OAAM,IAAI,MAAM,sBAAsB;AACjE,eAAO,aAAa,YAAY,EAAE,SAAS,aAAa,SAAS,QAAQ,CAAC;AAAA,MAC5E;AAAA,MACA,MAAM,aAA8B;AAClC,YAAI,CAAC,aAAa,QAAS,OAAM,IAAI,MAAM,sBAAsB;AACjE,eAAO,aAAa,QAAQ;AAAA,MAC9B;AAAA,MACA,MAAM,gBAAiC;AAGrC,cAAM,IAAI;AAAA,UACR;AAAA,QAEF;AAAA,MACF;AAAA,IACF;AAGA,UAAM,cAAc,IAAI,YAAY;AAAA,MAClC,kBAAkB,gBAAgB,YAAY,gBAAgB;AAAA,QAC5D;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF,CAAC;AAED,cAAU,UAAU,IAAI,YAAY;AAAA,MAClC;AAAA,MACA,QAAQ;AAAA,MACR;AAAA,IACF,CAAC;AAED,iBAAa,IAAI;AACjB,aAAS,IAAI;AAEb,cAAU,QACP,SAAS,OAAO,EAChB,KAAK,YAAU;AACd,UAAI,WAAW,SAAS;AACtB,eAAO,MAAM;AACb,qBAAa,KAAK;AAAA,MACpB;AAAA,IACF,CAAC,EACA,MAAM,SAAO;AACZ,UAAI,WAAW,SAAS;AACtB,iBAAS,eAAe,QAAQ,MAAM,IAAI,MAAM,OAAO,GAAG,CAAC,CAAC;AAC5D,qBAAa,KAAK;AAAA,MACpB;AAAA,IACF,CAAC;AAEH,WAAO,MAAM;AACX,iBAAW,UAAU;AAAA,IACvB;AAAA,EAEF,GAAG,CAAC,SAAS,cAAc,OAAO,IAAI,cAAc,cAAc,UAAU,CAAC;AAE7E,QAAM,UAAU,MAAM,cAAc,OAAK,IAAI,CAAC;AAE9C,SAAO,EAAE,KAAK,WAAW,OAAO,QAAQ;AAC1C;","names":[]}