@useagentpay/sdk 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.6_tsx@4.21.0_typescript@5.9.3/node_modules/tsup/assets/esm_shims.js","../src/errors.ts","../src/utils/ids.ts","../src/utils/display.ts","../src/utils/paths.ts","../src/vault/vault.ts","../src/auth/keypair.ts","../src/auth/mandate.ts","../src/budget/budget.ts","../src/transactions/manager.ts","../src/transactions/poller.ts","../src/audit/logger.ts","../src/executor/placeholder.ts","../src/executor/executor.ts","../src/agentpay.ts","../src/server/passphrase-html.ts","../src/utils/open-browser.ts","../src/server/passphrase-server.ts","../src/utils/prompt.ts","../src/commands/setup.ts","../src/commands/budget.ts","../src/commands/pending.ts","../src/commands/approve.ts","../src/commands/reject.ts","../src/commands/status.ts","../src/commands/history.ts","../src/commands/qr.ts","../src/commands/reset.ts","../src/commands/buy.ts","../src/server/html.ts","../src/server/routes.ts","../src/server/index.ts","../src/commands/dashboard.ts","../src/commands/mcp.ts","../src/cli.ts","../src/index.ts"],"sourcesContent":["// Shim globals in esm bundle\nimport path from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nconst getFilename = () => fileURLToPath(import.meta.url)\nconst getDirname = () => path.dirname(getFilename())\n\nexport const __dirname = /* @__PURE__ */ getDirname()\nexport const __filename = /* @__PURE__ */ getFilename()\n","export class NotSetupError extends Error {\n readonly code = 'NOT_SETUP';\n constructor(message = 'AgentPay has not been set up yet. Run `agentpay setup` first.') {\n super(message);\n this.name = 'NotSetupError';\n }\n}\n\nexport class DecryptError extends Error {\n readonly code = 'DECRYPT_FAILED';\n constructor(message = 'Failed to decrypt credentials. Wrong passphrase or corrupted file.') {\n super(message);\n this.name = 'DecryptError';\n }\n}\n\nexport class InsufficientBalanceError extends Error {\n readonly code = 'INSUFFICIENT_BALANCE';\n constructor(amount?: number, balance?: number) {\n const msg = amount !== undefined && balance !== undefined\n ? `Insufficient balance: requested $${amount.toFixed(2)} but only $${balance.toFixed(2)} available.`\n : 'Insufficient balance for this transaction.';\n super(msg);\n this.name = 'InsufficientBalanceError';\n }\n}\n\nexport class ExceedsTxLimitError extends Error {\n readonly code = 'EXCEEDS_TX_LIMIT';\n constructor(amount?: number, limit?: number) {\n const msg = amount !== undefined && limit !== undefined\n ? `Amount $${amount.toFixed(2)} exceeds per-transaction limit of $${limit.toFixed(2)}.`\n : 'Amount exceeds per-transaction limit.';\n super(msg);\n this.name = 'ExceedsTxLimitError';\n }\n}\n\nexport class NotApprovedError extends Error {\n readonly code = 'NOT_APPROVED';\n constructor(txId?: string) {\n super(txId ? `Transaction ${txId} has not been approved.` : 'Transaction has not been approved.');\n this.name = 'NotApprovedError';\n }\n}\n\nexport class InvalidMandateError extends Error {\n readonly code = 'INVALID_MANDATE';\n constructor(message = 'Purchase mandate signature verification failed.') {\n super(message);\n this.name = 'InvalidMandateError';\n }\n}\n\nexport class AlreadyExecutedError extends Error {\n readonly code = 'ALREADY_EXECUTED';\n constructor(txId?: string) {\n super(txId ? `Transaction ${txId} has already been executed.` : 'Transaction has already been executed.');\n this.name = 'AlreadyExecutedError';\n }\n}\n\nexport class CheckoutFailedError extends Error {\n readonly code = 'CHECKOUT_FAILED';\n constructor(message = 'Failed to complete checkout.') {\n super(message);\n this.name = 'CheckoutFailedError';\n }\n}\n\nexport class TimeoutError extends Error {\n readonly code = 'TIMEOUT';\n constructor(message = 'Operation timed out.') {\n super(message);\n this.name = 'TimeoutError';\n }\n}\n","import { randomBytes } from 'node:crypto';\n\nexport function generateTxId(): string {\n return `tx_${randomBytes(4).toString('hex')}`;\n}\n","import type { Transaction } from '../transactions/types.js';\n\nexport function formatCurrency(amount: number): string {\n return `$${amount.toFixed(2)}`;\n}\n\nexport function formatTimestamp(iso: string): string {\n const d = new Date(iso);\n return d.toLocaleString('en-US', {\n month: 'short',\n day: 'numeric',\n hour: '2-digit',\n minute: '2-digit',\n });\n}\n\nexport function formatTable(transactions: Transaction[]): string {\n if (transactions.length === 0) return 'No transactions.';\n\n const header = 'TX_ID MERCHANT AMOUNT DESCRIPTION';\n const separator = '─'.repeat(header.length);\n const rows = transactions.map((tx) => {\n const id = tx.id.padEnd(14);\n const merchant = tx.merchant.padEnd(16);\n const amount = formatCurrency(tx.amount).padStart(9);\n return `${id}${merchant}${amount} ${tx.description}`;\n });\n\n return [header, separator, ...rows].join('\\n');\n}\n\nexport function formatStatus(data: {\n balance: number;\n budget: number;\n limitPerTx: number;\n pending: Transaction[];\n recent: Transaction[];\n}): string {\n const lines = [\n 'AgentPay Status',\n '───────────────',\n `Balance: ${formatCurrency(data.balance)} / ${formatCurrency(data.budget)}`,\n `Per-tx limit: ${formatCurrency(data.limitPerTx)}`,\n `Pending purchases: ${data.pending.length}`,\n ];\n\n if (data.recent.length > 0) {\n lines.push('', 'Recent:');\n for (const tx of data.recent) {\n const status = `[${tx.status}]`.padEnd(12);\n lines.push(` ${status} ${tx.id} ${tx.merchant.padEnd(12)} ${formatCurrency(tx.amount).padStart(8)} ${tx.description}`);\n }\n }\n\n return lines.join('\\n');\n}\n","import { homedir } from 'node:os';\nimport { join } from 'node:path';\n\nexport function getHomePath(): string {\n return process.env.AGENTPAY_HOME || join(homedir(), '.agentpay');\n}\n\nexport function getCredentialsPath(): string {\n return join(getHomePath(), 'credentials.enc');\n}\n\nexport function getKeysPath(): string {\n return join(getHomePath(), 'keys');\n}\n\nexport function getPublicKeyPath(): string {\n return join(getKeysPath(), 'public.pem');\n}\n\nexport function getPrivateKeyPath(): string {\n return join(getKeysPath(), 'private.pem');\n}\n\nexport function getWalletPath(): string {\n return join(getHomePath(), 'wallet.json');\n}\n\nexport function getTransactionsPath(): string {\n return join(getHomePath(), 'transactions.json');\n}\n\nexport function getAuditPath(): string {\n return join(getHomePath(), 'audit.log');\n}\n","import { pbkdf2Sync, randomBytes, createCipheriv, createDecipheriv } from 'node:crypto';\nimport { readFileSync, writeFileSync, mkdirSync } from 'node:fs';\nimport { dirname } from 'node:path';\nimport type { BillingCredentials, EncryptedVault } from './types.js';\nimport { DecryptError, NotSetupError } from '../errors.js';\nimport { getCredentialsPath } from '../utils/paths.js';\n\nconst ALGORITHM = 'aes-256-gcm';\nconst PBKDF2_ITERATIONS = 100_000;\nconst PBKDF2_DIGEST = 'sha512';\nconst KEY_LENGTH = 32;\nconst SALT_LENGTH = 32;\nconst IV_LENGTH = 16;\n\nexport function deriveKey(passphrase: string, salt: Buffer): Buffer {\n return pbkdf2Sync(passphrase, salt, PBKDF2_ITERATIONS, KEY_LENGTH, PBKDF2_DIGEST);\n}\n\nexport function encrypt(credentials: BillingCredentials, passphrase: string): EncryptedVault {\n const salt = randomBytes(SALT_LENGTH);\n const iv = randomBytes(IV_LENGTH);\n const key = deriveKey(passphrase, salt);\n\n const cipher = createCipheriv(ALGORITHM, key, iv);\n const plaintext = JSON.stringify(credentials);\n const encrypted = Buffer.concat([cipher.update(plaintext, 'utf8'), cipher.final()]);\n const authTag = cipher.getAuthTag();\n\n return {\n ciphertext: Buffer.concat([encrypted, authTag]).toString('base64'),\n salt: salt.toString('base64'),\n iv: iv.toString('base64'),\n };\n}\n\nexport function decrypt(vault: EncryptedVault, passphrase: string): BillingCredentials {\n try {\n const salt = Buffer.from(vault.salt, 'base64');\n const iv = Buffer.from(vault.iv, 'base64');\n const data = Buffer.from(vault.ciphertext, 'base64');\n const key = deriveKey(passphrase, salt);\n\n const authTag = data.subarray(data.length - 16);\n const ciphertext = data.subarray(0, data.length - 16);\n\n const decipher = createDecipheriv(ALGORITHM, key, iv);\n decipher.setAuthTag(authTag);\n const decrypted = Buffer.concat([decipher.update(ciphertext), decipher.final()]);\n\n return JSON.parse(decrypted.toString('utf8')) as BillingCredentials;\n } catch {\n throw new DecryptError();\n }\n}\n\nexport function saveVault(vault: EncryptedVault, path?: string): void {\n const filePath = path ?? getCredentialsPath();\n mkdirSync(dirname(filePath), { recursive: true });\n writeFileSync(filePath, JSON.stringify(vault, null, 2), { mode: 0o600 });\n}\n\nexport function loadVault(path?: string): EncryptedVault {\n const filePath = path ?? getCredentialsPath();\n try {\n const data = readFileSync(filePath, 'utf8');\n return JSON.parse(data) as EncryptedVault;\n } catch {\n throw new NotSetupError();\n }\n}\n","import { generateKeyPairSync, createPublicKey } from 'node:crypto';\nimport { readFileSync, writeFileSync, mkdirSync } from 'node:fs';\nimport { dirname } from 'node:path';\nimport type { KeyPair } from './types.js';\nimport { getPublicKeyPath, getPrivateKeyPath } from '../utils/paths.js';\n\nexport function generateKeyPair(passphrase: string): KeyPair {\n const { publicKey, privateKey } = generateKeyPairSync('ed25519', {\n publicKeyEncoding: { type: 'spki', format: 'pem' },\n privateKeyEncoding: {\n type: 'pkcs8',\n format: 'pem',\n cipher: 'aes-256-cbc',\n passphrase,\n },\n });\n\n return { publicKey, privateKey };\n}\n\nexport function saveKeyPair(keys: KeyPair, publicPath?: string, privatePath?: string): void {\n const pubPath = publicPath ?? getPublicKeyPath();\n const privPath = privatePath ?? getPrivateKeyPath();\n\n mkdirSync(dirname(pubPath), { recursive: true });\n writeFileSync(pubPath, keys.publicKey, { mode: 0o644 });\n writeFileSync(privPath, keys.privateKey, { mode: 0o600 });\n}\n\nexport function loadPublicKey(path?: string): string {\n return readFileSync(path ?? getPublicKeyPath(), 'utf8');\n}\n\nexport function loadPrivateKey(path?: string): string {\n return readFileSync(path ?? getPrivateKeyPath(), 'utf8');\n}\n","import { createHash, createPrivateKey, createPublicKey, sign, verify } from 'node:crypto';\nimport type { PurchaseMandate, TransactionDetails } from './types.js';\nimport { InvalidMandateError } from '../errors.js';\n\nfunction hashTransactionDetails(details: TransactionDetails): string {\n const canonical = JSON.stringify({\n txId: details.txId,\n merchant: details.merchant,\n amount: details.amount,\n description: details.description,\n timestamp: details.timestamp,\n });\n return createHash('sha256').update(canonical).digest('hex');\n}\n\nexport function createMandate(\n txDetails: TransactionDetails,\n privateKeyPem: string,\n passphrase: string,\n): PurchaseMandate {\n const txHash = hashTransactionDetails(txDetails);\n const data = Buffer.from(txHash);\n\n const privateKey = createPrivateKey({\n key: privateKeyPem,\n format: 'pem',\n type: 'pkcs8',\n passphrase,\n });\n\n const signature = sign(null, data, privateKey);\n\n const publicKey = createPublicKey(privateKey);\n const publicKeyPem = publicKey.export({ type: 'spki', format: 'pem' }) as string;\n\n return {\n txId: txDetails.txId,\n txHash,\n signature: signature.toString('base64'),\n publicKey: publicKeyPem,\n timestamp: new Date().toISOString(),\n };\n}\n\nexport function verifyMandate(mandate: PurchaseMandate, txDetails: TransactionDetails): boolean {\n try {\n const txHash = hashTransactionDetails(txDetails);\n if (txHash !== mandate.txHash) return false;\n\n const data = Buffer.from(txHash);\n const signature = Buffer.from(mandate.signature, 'base64');\n const publicKey = createPublicKey({\n key: mandate.publicKey,\n format: 'pem',\n type: 'spki',\n });\n\n return verify(null, data, publicKey, signature);\n } catch {\n return false;\n }\n}\n","import { readFileSync, writeFileSync, mkdirSync } from 'node:fs';\nimport { dirname } from 'node:path';\nimport type { Wallet } from './types.js';\nimport { NotSetupError, InsufficientBalanceError, ExceedsTxLimitError } from '../errors.js';\nimport { getWalletPath } from '../utils/paths.js';\n\nexport class BudgetManager {\n private walletPath: string;\n\n constructor(walletPath?: string) {\n this.walletPath = walletPath ?? getWalletPath();\n }\n\n getWallet(): Wallet {\n try {\n const data = readFileSync(this.walletPath, 'utf8');\n return JSON.parse(data) as Wallet;\n } catch {\n throw new NotSetupError();\n }\n }\n\n private saveWallet(wallet: Wallet): void {\n mkdirSync(dirname(this.walletPath), { recursive: true });\n writeFileSync(this.walletPath, JSON.stringify(wallet, null, 2), { mode: 0o600 });\n }\n\n setBudget(amount: number): void {\n let wallet: Wallet;\n try {\n wallet = this.getWallet();\n } catch {\n wallet = { budget: 0, balance: 0, limitPerTx: 0, spent: 0 };\n }\n wallet.budget = amount;\n wallet.balance = amount - wallet.spent;\n this.saveWallet(wallet);\n }\n\n setLimitPerTx(limit: number): void {\n const wallet = this.getWallet();\n wallet.limitPerTx = limit;\n this.saveWallet(wallet);\n }\n\n deductBalance(amount: number): void {\n const wallet = this.getWallet();\n if (amount > wallet.balance) {\n throw new InsufficientBalanceError(amount, wallet.balance);\n }\n wallet.balance -= amount;\n wallet.spent += amount;\n this.saveWallet(wallet);\n }\n\n checkProposal(amount: number): void {\n const wallet = this.getWallet();\n if (amount > wallet.balance) {\n throw new InsufficientBalanceError(amount, wallet.balance);\n }\n if (wallet.limitPerTx > 0 && amount > wallet.limitPerTx) {\n throw new ExceedsTxLimitError(amount, wallet.limitPerTx);\n }\n }\n\n addFunds(amount: number): Wallet {\n const wallet = this.getWallet();\n wallet.budget += amount;\n wallet.balance += amount;\n this.saveWallet(wallet);\n return wallet;\n }\n\n getBalance(): { budget: number; balance: number; limitPerTx: number; spent: number } {\n const wallet = this.getWallet();\n return {\n budget: wallet.budget,\n balance: wallet.balance,\n limitPerTx: wallet.limitPerTx,\n spent: wallet.spent,\n };\n }\n\n initWallet(budget: number, limitPerTx: number = 0): void {\n const wallet: Wallet = { budget, balance: budget, limitPerTx, spent: 0 };\n this.saveWallet(wallet);\n }\n}\n","import { readFileSync, writeFileSync, mkdirSync } from 'node:fs';\nimport { dirname } from 'node:path';\nimport type { Transaction, Receipt, ProposeOptions } from './types.js';\nimport type { PurchaseMandate } from '../auth/types.js';\nimport { generateTxId } from '../utils/ids.js';\nimport { getTransactionsPath } from '../utils/paths.js';\n\nexport class TransactionManager {\n private txPath: string;\n\n constructor(txPath?: string) {\n this.txPath = txPath ?? getTransactionsPath();\n }\n\n private loadAll(): Transaction[] {\n try {\n const data = readFileSync(this.txPath, 'utf8');\n return JSON.parse(data) as Transaction[];\n } catch {\n return [];\n }\n }\n\n private saveAll(transactions: Transaction[]): void {\n mkdirSync(dirname(this.txPath), { recursive: true });\n writeFileSync(this.txPath, JSON.stringify(transactions, null, 2), { mode: 0o600 });\n }\n\n propose(options: ProposeOptions): Transaction {\n const transactions = this.loadAll();\n const tx: Transaction = {\n id: generateTxId(),\n status: 'pending',\n merchant: options.merchant,\n amount: options.amount,\n description: options.description,\n url: options.url,\n createdAt: new Date().toISOString(),\n };\n transactions.push(tx);\n this.saveAll(transactions);\n return tx;\n }\n\n get(txId: string): Transaction | undefined {\n return this.loadAll().find((tx) => tx.id === txId);\n }\n\n approve(txId: string, mandate: PurchaseMandate): void {\n const transactions = this.loadAll();\n const tx = transactions.find((t) => t.id === txId);\n if (!tx) throw new Error(`Transaction ${txId} not found.`);\n if (tx.status !== 'pending') throw new Error(`Cannot approve transaction in '${tx.status}' state.`);\n tx.status = 'approved';\n tx.mandate = mandate;\n this.saveAll(transactions);\n }\n\n reject(txId: string, reason?: string): void {\n const transactions = this.loadAll();\n const tx = transactions.find((t) => t.id === txId);\n if (!tx) throw new Error(`Transaction ${txId} not found.`);\n if (tx.status !== 'pending') throw new Error(`Cannot reject transaction in '${tx.status}' state.`);\n tx.status = 'rejected';\n tx.rejectionReason = reason;\n this.saveAll(transactions);\n }\n\n markExecuting(txId: string): void {\n const transactions = this.loadAll();\n const tx = transactions.find((t) => t.id === txId);\n if (!tx) throw new Error(`Transaction ${txId} not found.`);\n if (tx.status !== 'approved') throw new Error(`Cannot execute transaction in '${tx.status}' state.`);\n tx.status = 'executing';\n this.saveAll(transactions);\n }\n\n markCompleted(txId: string, receipt: Receipt): void {\n const transactions = this.loadAll();\n const tx = transactions.find((t) => t.id === txId);\n if (!tx) throw new Error(`Transaction ${txId} not found.`);\n if (tx.status !== 'executing') throw new Error(`Cannot complete transaction in '${tx.status}' state.`);\n tx.status = 'completed';\n tx.receipt = receipt;\n this.saveAll(transactions);\n }\n\n markFailed(txId: string, error: string): void {\n const transactions = this.loadAll();\n const tx = transactions.find((t) => t.id === txId);\n if (!tx) throw new Error(`Transaction ${txId} not found.`);\n if (tx.status !== 'executing') throw new Error(`Cannot fail transaction in '${tx.status}' state.`);\n tx.status = 'failed';\n tx.error = error;\n this.saveAll(transactions);\n }\n\n list(): Transaction[] {\n return this.loadAll();\n }\n\n getPending(): Transaction[] {\n return this.loadAll().filter((tx) => tx.status === 'pending');\n }\n\n getHistory(): Transaction[] {\n return this.loadAll().filter((tx) => tx.status !== 'pending');\n }\n}\n","import type { Transaction } from './types.js';\nimport type { TransactionManager } from './manager.js';\nimport { TimeoutError } from '../errors.js';\n\nexport interface PollOptions {\n pollInterval?: number;\n timeout?: number;\n}\n\nexport async function waitForApproval(\n txId: string,\n manager: TransactionManager,\n options?: PollOptions,\n): Promise<{ status: 'approved' | 'rejected'; reason?: string }> {\n const interval = options?.pollInterval ?? 2000;\n const timeout = options?.timeout ?? 300_000;\n const deadline = Date.now() + timeout;\n\n while (Date.now() < deadline) {\n const tx = manager.get(txId);\n if (!tx) throw new Error(`Transaction ${txId} not found.`);\n\n if (tx.status === 'approved') return { status: 'approved' };\n if (tx.status === 'rejected') return { status: 'rejected', reason: tx.rejectionReason };\n\n await new Promise((resolve) => setTimeout(resolve, interval));\n }\n\n throw new TimeoutError(`Timed out waiting for approval of ${txId}`);\n}\n","import { appendFileSync, readFileSync, mkdirSync } from 'node:fs';\nimport { dirname } from 'node:path';\nimport { getAuditPath } from '../utils/paths.js';\n\nexport class AuditLogger {\n private logPath: string;\n\n constructor(logPath?: string) {\n this.logPath = logPath ?? getAuditPath();\n }\n\n log(action: string, details: Record<string, unknown>): void {\n const timestamp = new Date().toISOString();\n const detailsStr = JSON.stringify(details);\n const entry = `${timestamp}\\t${action}\\t${detailsStr}\\n`;\n mkdirSync(dirname(this.logPath), { recursive: true });\n appendFileSync(this.logPath, entry, { mode: 0o600 });\n }\n\n getLog(): string[] {\n try {\n const data = readFileSync(this.logPath, 'utf8');\n return data.trim().split('\\n').filter(Boolean);\n } catch {\n return [];\n }\n }\n}\n","import type { BillingCredentials } from '../vault/types.js';\n\nexport const PLACEHOLDER_MAP = {\n card_number: '{{card_number}}',\n cardholder_name: '{{cardholder_name}}',\n card_expiry: '{{card_expiry}}',\n card_cvv: '{{card_cvv}}',\n billing_street: '{{billing_street}}',\n billing_city: '{{billing_city}}',\n billing_state: '{{billing_state}}',\n billing_zip: '{{billing_zip}}',\n billing_country: '{{billing_country}}',\n shipping_street: '{{shipping_street}}',\n shipping_city: '{{shipping_city}}',\n shipping_state: '{{shipping_state}}',\n shipping_zip: '{{shipping_zip}}',\n shipping_country: '{{shipping_country}}',\n email: '{{email}}',\n phone: '{{phone}}',\n} as const;\n\nexport function getPlaceholderVariables(): Record<string, string> {\n // These are the %var% placeholders used with Stagehand act() variables\n // The AI never sees the real values — only these placeholders\n return {\n card_number: '%card_number%',\n cardholder_name: '%cardholder_name%',\n card_expiry: '%card_expiry%',\n card_cvv: '%card_cvv%',\n billing_street: '%billing_street%',\n billing_city: '%billing_city%',\n billing_state: '%billing_state%',\n billing_zip: '%billing_zip%',\n billing_country: '%billing_country%',\n shipping_street: '%shipping_street%',\n shipping_city: '%shipping_city%',\n shipping_state: '%shipping_state%',\n shipping_zip: '%shipping_zip%',\n shipping_country: '%shipping_country%',\n email: '%email%',\n phone: '%phone%',\n };\n}\n\nexport function credentialsToSwapMap(creds: BillingCredentials): Record<string, string> {\n return {\n [PLACEHOLDER_MAP.card_number]: creds.card.number,\n [PLACEHOLDER_MAP.cardholder_name]: creds.name,\n [PLACEHOLDER_MAP.card_expiry]: creds.card.expiry,\n [PLACEHOLDER_MAP.card_cvv]: creds.card.cvv,\n [PLACEHOLDER_MAP.billing_street]: creds.billingAddress.street,\n [PLACEHOLDER_MAP.billing_city]: creds.billingAddress.city,\n [PLACEHOLDER_MAP.billing_state]: creds.billingAddress.state,\n [PLACEHOLDER_MAP.billing_zip]: creds.billingAddress.zip,\n [PLACEHOLDER_MAP.billing_country]: creds.billingAddress.country,\n [PLACEHOLDER_MAP.shipping_street]: creds.shippingAddress.street,\n [PLACEHOLDER_MAP.shipping_city]: creds.shippingAddress.city,\n [PLACEHOLDER_MAP.shipping_state]: creds.shippingAddress.state,\n [PLACEHOLDER_MAP.shipping_zip]: creds.shippingAddress.zip,\n [PLACEHOLDER_MAP.shipping_country]: creds.shippingAddress.country,\n [PLACEHOLDER_MAP.email]: creds.email,\n [PLACEHOLDER_MAP.phone]: creds.phone,\n };\n}\n\n/**\n * Atomically swap placeholders with real credentials in the DOM and submit.\n * This is called via page.evaluate() — credentials exist in the DOM only for milliseconds.\n */\nexport function getAtomicSwapScript(): string {\n return `\n (swapMap) => {\n const inputs = document.querySelectorAll('input, textarea, select');\n for (const input of inputs) {\n const el = input;\n for (const [placeholder, value] of Object.entries(swapMap)) {\n if (el.value === placeholder) {\n el.value = value;\n el.dispatchEvent(new Event('input', { bubbles: true }));\n el.dispatchEvent(new Event('change', { bubbles: true }));\n }\n }\n }\n // Submit the form\n const submitBtn = document.querySelector('button[type=\"submit\"], input[type=\"submit\"]');\n if (submitBtn) submitBtn.click();\n }\n `;\n}\n","import { Stagehand } from '@browserbasehq/stagehand';\nimport type { BillingCredentials } from '../vault/types.js';\nimport type { Transaction } from '../transactions/types.js';\nimport type { CheckoutResult, ExecutorConfig } from './types.js';\nimport { CheckoutFailedError } from '../errors.js';\nimport { credentialsToSwapMap, getPlaceholderVariables } from './placeholder.js';\n\nexport interface DiscoverResult {\n price: number;\n productName: string;\n}\n\nexport class PurchaseExecutor {\n private config: ExecutorConfig;\n private stagehand: Stagehand | null = null;\n\n constructor(config?: ExecutorConfig) {\n this.config = {\n browserbaseApiKey: config?.browserbaseApiKey ?? process.env.BROWSERBASE_API_KEY,\n browserbaseProjectId: config?.browserbaseProjectId ?? process.env.BROWSERBASE_PROJECT_ID,\n modelApiKey: config?.modelApiKey ?? process.env.ANTHROPIC_API_KEY,\n };\n }\n\n private createStagehand(): Stagehand {\n return new Stagehand({\n env: 'BROWSERBASE',\n apiKey: this.config.browserbaseApiKey,\n projectId: this.config.browserbaseProjectId,\n model: this.config.modelApiKey\n ? { modelName: 'claude-3-7-sonnet-latest', apiKey: this.config.modelApiKey }\n : undefined,\n browserbaseSessionCreateParams: {\n browserSettings: {\n recordSession: false,\n },\n },\n });\n }\n\n /**\n * Phase 1: Open browser, navigate to URL, extract price and product info.\n * Keeps the session alive for fillAndComplete().\n */\n async openAndDiscover(url: string, instructions?: string): Promise<DiscoverResult> {\n this.stagehand = this.createStagehand();\n await this.stagehand.init();\n const page = this.stagehand.context.activePage()!;\n\n await page.goto(url);\n\n // Let Stagehand find the product and add to cart with optional extra instructions\n const addToCartInstructions = instructions\n ? `On this product page: ${instructions}. Then add the item to the cart.`\n : 'Add this product to the cart.';\n await this.stagehand.act(addToCartInstructions);\n\n // Extract price and product name\n const extracted = await this.stagehand.extract(\n 'Extract the product name and the price (as a number without $ sign) from the page or cart. Return JSON: { \"price\": <number>, \"productName\": \"<string>\" }',\n ) as any;\n\n const price = parseFloat(extracted?.price ?? extracted?.extraction?.price ?? '0');\n const productName = extracted?.productName ?? extracted?.extraction?.productName ?? 'Unknown Product';\n\n return { price, productName };\n }\n\n /**\n * Phase 2: Proceed to checkout, fill forms, swap credentials, and submit.\n * Must be called after openAndDiscover().\n */\n async fillAndComplete(credentials: BillingCredentials): Promise<CheckoutResult> {\n if (!this.stagehand) {\n throw new CheckoutFailedError('No active session. Call openAndDiscover() first.');\n }\n\n try {\n // Proceed to checkout\n await this.stagehand.act('Proceed to checkout from the cart.');\n\n // Fill checkout form with placeholders\n const variables = getPlaceholderVariables();\n await this.stagehand.act(\n `Fill in the checkout form with these values:\n Name: ${variables.cardholder_name}\n Card Number: ${variables.card_number}\n Expiry: ${variables.card_expiry}\n CVV: ${variables.card_cvv}\n Email: ${variables.email}\n Phone: ${variables.phone}\n Billing Street: ${variables.billing_street}\n Billing City: ${variables.billing_city}\n Billing State: ${variables.billing_state}\n Billing ZIP: ${variables.billing_zip}\n Billing Country: ${variables.billing_country}\n Shipping Street: ${variables.shipping_street}\n Shipping City: ${variables.shipping_city}\n Shipping State: ${variables.shipping_state}\n Shipping ZIP: ${variables.shipping_zip}\n Shipping Country: ${variables.shipping_country}`,\n { variables },\n );\n\n // Atomic swap: replace placeholders with real credentials and submit\n const swapMap = credentialsToSwapMap(credentials);\n const page = this.stagehand.context.activePage()!;\n\n await page.evaluate((map: Record<string, string>) => {\n const inputs = document.querySelectorAll('input, textarea, select');\n for (const input of inputs) {\n const el = input as HTMLInputElement;\n for (const [placeholder, value] of Object.entries(map)) {\n if (el.value === placeholder) {\n el.value = value;\n el.dispatchEvent(new Event('input', { bubbles: true }));\n el.dispatchEvent(new Event('change', { bubbles: true }));\n }\n }\n }\n const submitBtn = document.querySelector('button[type=\"submit\"], input[type=\"submit\"]') as HTMLElement | null;\n if (submitBtn) submitBtn.click();\n }, swapMap);\n\n // Wait for confirmation page\n await page.waitForTimeout(5000);\n\n // Try to extract confirmation\n const result = await this.stagehand.extract(\n 'Extract the order confirmation number or ID from the page',\n );\n\n const confirmationId = (result as any)?.extraction;\n if (!confirmationId || confirmationId === 'null' || confirmationId === 'UNKNOWN') {\n throw new CheckoutFailedError('No order confirmation found. Checkout may not have completed.');\n }\n\n return {\n success: true,\n confirmationId,\n };\n } catch (err) {\n if (err instanceof CheckoutFailedError) throw err;\n const message = err instanceof Error ? err.message : 'Unknown checkout error';\n throw new CheckoutFailedError(message);\n }\n }\n\n /**\n * Convenience: single-shot execute (navigate + checkout in one call).\n * Used by AgentPay facade when amount is already known.\n */\n async execute(tx: Transaction, credentials: BillingCredentials): Promise<CheckoutResult> {\n this.stagehand = this.createStagehand();\n\n try {\n await this.stagehand.init();\n const page = this.stagehand.context.activePage()!;\n\n await page.goto(tx.url);\n\n const variables = getPlaceholderVariables();\n await this.stagehand.act(\n `Find the product and proceed to checkout. Fill in the checkout form with these values:\n Name: ${variables.cardholder_name}\n Card Number: ${variables.card_number}\n Expiry: ${variables.card_expiry}\n CVV: ${variables.card_cvv}\n Email: ${variables.email}\n Phone: ${variables.phone}\n Billing Street: ${variables.billing_street}\n Billing City: ${variables.billing_city}\n Billing State: ${variables.billing_state}\n Billing ZIP: ${variables.billing_zip}\n Billing Country: ${variables.billing_country}\n Shipping Street: ${variables.shipping_street}\n Shipping City: ${variables.shipping_city}\n Shipping State: ${variables.shipping_state}\n Shipping ZIP: ${variables.shipping_zip}\n Shipping Country: ${variables.shipping_country}`,\n { variables },\n );\n\n const swapMap = credentialsToSwapMap(credentials);\n await page.evaluate((map: Record<string, string>) => {\n const inputs = document.querySelectorAll('input, textarea, select');\n for (const input of inputs) {\n const el = input as HTMLInputElement;\n for (const [placeholder, value] of Object.entries(map)) {\n if (el.value === placeholder) {\n el.value = value;\n el.dispatchEvent(new Event('input', { bubbles: true }));\n el.dispatchEvent(new Event('change', { bubbles: true }));\n }\n }\n }\n const submitBtn = document.querySelector('button[type=\"submit\"], input[type=\"submit\"]') as HTMLElement | null;\n if (submitBtn) submitBtn.click();\n }, swapMap);\n\n await page.waitForTimeout(5000);\n\n const result = await this.stagehand.extract(\n 'Extract the order confirmation number or ID from the page',\n );\n\n const confirmationId = (result as any)?.extraction;\n if (!confirmationId || confirmationId === 'null' || confirmationId === 'UNKNOWN') {\n throw new CheckoutFailedError('No order confirmation found. Checkout may not have completed.');\n }\n\n return {\n success: true,\n confirmationId,\n };\n } catch (err) {\n if (err instanceof CheckoutFailedError) throw err;\n const message = err instanceof Error ? err.message : 'Unknown checkout error';\n throw new CheckoutFailedError(message);\n } finally {\n await this.close();\n }\n }\n\n async close(): Promise<void> {\n try {\n if (this.stagehand) {\n await this.stagehand.close();\n this.stagehand = null;\n }\n } catch {\n // Ignore cleanup errors\n }\n }\n}\n","import { join } from 'node:path';\nimport { BudgetManager } from './budget/budget.js';\nimport { TransactionManager } from './transactions/manager.js';\nimport { AuditLogger } from './audit/logger.js';\nimport { PurchaseExecutor } from './executor/executor.js';\nimport { verifyMandate } from './auth/mandate.js';\nimport { decrypt, loadVault } from './vault/vault.js';\nimport { getHomePath } from './utils/paths.js';\nimport {\n NotApprovedError,\n InvalidMandateError,\n InsufficientBalanceError,\n AlreadyExecutedError,\n} from './errors.js';\nimport type { Transaction, Receipt, ProposeOptions } from './transactions/types.js';\nimport type { TransactionDetails } from './auth/types.js';\nimport type { ExecutorConfig } from './executor/types.js';\n\nexport interface AgentPayOptions {\n home?: string;\n passphrase?: string;\n executor?: ExecutorConfig;\n}\n\nexport class AgentPay {\n public readonly home: string;\n private passphrase?: string;\n private budgetManager: BudgetManager;\n private txManager: TransactionManager;\n private auditLogger: AuditLogger;\n private executor: PurchaseExecutor;\n\n constructor(options?: AgentPayOptions) {\n this.home = options?.home ?? getHomePath();\n this.passphrase = options?.passphrase;\n this.budgetManager = new BudgetManager(join(this.home, 'wallet.json'));\n this.txManager = new TransactionManager(join(this.home, 'transactions.json'));\n this.auditLogger = new AuditLogger(join(this.home, 'audit.log'));\n this.executor = new PurchaseExecutor(options?.executor);\n }\n\n get wallet() {\n const bm = this.budgetManager;\n return {\n getBalance: () => bm.getBalance(),\n getHistory: () => this.txManager.getHistory(),\n getLimits: () => {\n const w = bm.getBalance();\n return { budget: w.budget, limitPerTx: w.limitPerTx, remaining: w.balance };\n },\n generateFundingQR: async (options?: { suggestedBudget?: number; message?: string }) => {\n const QRCode = await import('qrcode');\n const params = new URLSearchParams();\n if (options?.suggestedBudget) params.set('budget', String(options.suggestedBudget));\n if (options?.message) params.set('msg', options.message);\n const baseUrl = process.env.AGENTPAY_WEB_URL ?? 'http://localhost:3000';\n const url = `${baseUrl}/setup${params.toString() ? `?${params.toString()}` : ''}`;\n const qrDataUrl = await QRCode.toDataURL(url);\n return { url, qrDataUrl };\n },\n };\n }\n\n get transactions() {\n return {\n propose: (options: ProposeOptions): Transaction => {\n this.budgetManager.checkProposal(options.amount);\n const tx = this.txManager.propose(options);\n this.auditLogger.log('PROPOSE', { txId: tx.id, merchant: tx.merchant, amount: tx.amount });\n return tx;\n },\n get: (txId: string) => this.txManager.get(txId),\n waitForApproval: async (txId: string, options?: { pollInterval?: number; timeout?: number }) => {\n const { waitForApproval } = await import('./transactions/poller.js');\n return waitForApproval(txId, this.txManager, options);\n },\n execute: async (txId: string): Promise<Receipt> => {\n const tx = this.txManager.get(txId);\n if (!tx) throw new Error(`Transaction ${txId} not found.`);\n\n // Validate state\n if (tx.status === 'completed' || tx.status === 'failed') {\n throw new AlreadyExecutedError(txId);\n }\n if (tx.status !== 'approved') {\n throw new NotApprovedError(txId);\n }\n if (!tx.mandate) {\n throw new InvalidMandateError('No mandate found on approved transaction.');\n }\n\n // Verify mandate\n const txDetails: TransactionDetails = {\n txId: tx.id,\n merchant: tx.merchant,\n amount: tx.amount,\n description: tx.description,\n timestamp: tx.createdAt,\n };\n if (!verifyMandate(tx.mandate, txDetails)) {\n throw new InvalidMandateError();\n }\n\n // Check balance\n this.budgetManager.checkProposal(tx.amount);\n\n // Mark executing\n this.txManager.markExecuting(txId);\n this.auditLogger.log('EXECUTE', { txId, browserbaseSessionStarted: true });\n\n try {\n // Decrypt credentials\n if (!this.passphrase) {\n throw new Error('Passphrase required for execution. Pass it to AgentPay constructor.');\n }\n const vaultPath = join(this.home, 'credentials.enc');\n const vault = loadVault(vaultPath);\n const credentials = decrypt(vault, this.passphrase);\n\n // Execute checkout\n const result = await this.executor.execute(tx, credentials);\n\n // Mark completed and deduct balance\n const receipt: Receipt = {\n id: `rcpt_${txId.replace('tx_', '')}`,\n merchant: tx.merchant,\n amount: tx.amount,\n confirmationId: result.confirmationId ?? 'UNKNOWN',\n completedAt: new Date().toISOString(),\n };\n\n this.txManager.markCompleted(txId, receipt);\n this.budgetManager.deductBalance(tx.amount);\n this.auditLogger.log('COMPLETE', { txId, confirmationId: receipt.confirmationId });\n\n return receipt;\n } catch (err) {\n this.txManager.markFailed(txId, err instanceof Error ? err.message : 'Unknown error');\n this.auditLogger.log('FAILED', { txId, error: err instanceof Error ? err.message : 'Unknown' });\n throw err;\n }\n },\n getReceipt: (txId: string): Receipt | undefined => {\n const tx = this.txManager.get(txId);\n return tx?.receipt;\n },\n };\n }\n\n get audit() {\n return { getLog: () => this.auditLogger.getLog() };\n }\n\n status(): {\n balance: number;\n budget: number;\n limitPerTx: number;\n pending: Transaction[];\n recent: Transaction[];\n isSetup: boolean;\n } {\n try {\n const wallet = this.budgetManager.getBalance();\n const pending = this.txManager.getPending();\n const recent = this.txManager.list().slice(-5);\n return {\n balance: wallet.balance,\n budget: wallet.budget,\n limitPerTx: wallet.limitPerTx,\n pending,\n recent,\n isSetup: true,\n };\n } catch {\n return {\n balance: 0,\n budget: 0,\n limitPerTx: 0,\n pending: [],\n recent: [],\n isSetup: false,\n };\n }\n }\n}\n","export interface PassphraseContext {\n action: 'buy' | 'approve';\n merchant?: string;\n amount?: number;\n description?: string;\n txId?: string;\n}\n\nfunction esc(s: string): string {\n return s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\"/g, '&quot;');\n}\n\nfunction formatCurrency(n: number): string {\n return '$' + n.toFixed(2);\n}\n\nexport function getPassphraseHtml(token: string, context?: PassphraseContext): string {\n const actionLabel = context?.action === 'approve' ? 'Approve Transaction' : 'Approve Purchase';\n const buttonLabel = context?.action === 'approve' ? 'Unlock &amp; Approve' : 'Unlock &amp; Approve';\n\n let contextHtml = '';\n if (context) {\n const lines: string[] = [];\n if (context.merchant) lines.push(`<div class=\"detail\"><span class=\"detail-label\">Merchant</span><span class=\"detail-value\">${esc(context.merchant)}</span></div>`);\n if (context.amount !== undefined) lines.push(`<div class=\"detail\"><span class=\"detail-label\">Amount</span><span class=\"detail-value\">${formatCurrency(context.amount)}</span></div>`);\n if (context.description) lines.push(`<div class=\"detail\"><span class=\"detail-label\">Description</span><span class=\"detail-value\">${esc(context.description)}</span></div>`);\n if (context.txId) lines.push(`<div class=\"detail\"><span class=\"detail-label\">Transaction</span><span class=\"detail-value\" style=\"font-family:monospace;font-size:12px;\">${esc(context.txId)}</span></div>`);\n if (lines.length > 0) {\n contextHtml = `<div class=\"card context-card\">${lines.join('')}</div>`;\n }\n }\n\n return `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n<title>AgentPay — Passphrase Required</title>\n<style>\n *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }\n body {\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n background: #f5f5f5;\n color: #111;\n min-height: 100vh;\n display: flex;\n justify-content: center;\n padding: 40px 16px;\n }\n .container { width: 100%; max-width: 420px; }\n h1 { font-size: 24px; font-weight: 700; margin-bottom: 4px; }\n .subtitle { color: #666; font-size: 14px; margin-bottom: 24px; }\n .card {\n background: #fff;\n border-radius: 8px;\n padding: 24px;\n margin-bottom: 16px;\n border: 1px solid #e0e0e0;\n }\n .context-card { padding: 16px 20px; }\n .detail {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 8px 0;\n border-bottom: 1px solid #f0f0f0;\n }\n .detail:last-child { border-bottom: none; }\n .detail-label { font-size: 13px; color: #666; }\n .detail-value { font-size: 14px; font-weight: 600; }\n label { display: block; font-size: 13px; font-weight: 500; color: #333; margin-bottom: 6px; }\n input[type=\"password\"] {\n width: 100%;\n padding: 12px 14px;\n border: 1px solid #d0d0d0;\n border-radius: 8px;\n font-size: 15px;\n outline: none;\n transition: border-color 0.15s;\n }\n input[type=\"password\"]:focus { border-color: #111; }\n button {\n width: 100%;\n padding: 12px;\n border: none;\n border-radius: 8px;\n font-size: 14px;\n font-weight: 600;\n cursor: pointer;\n transition: opacity 0.15s;\n margin-top: 16px;\n background: #111;\n color: #fff;\n }\n button:hover { opacity: 0.85; }\n button:disabled { opacity: 0.5; cursor: not-allowed; }\n .error { color: #c62828; font-size: 13px; margin-top: 10px; }\n .success-screen {\n text-align: center;\n padding: 40px 0;\n }\n .checkmark {\n font-size: 48px;\n margin-bottom: 16px;\n }\n .success-msg {\n font-size: 16px;\n font-weight: 600;\n margin-bottom: 8px;\n }\n .success-hint {\n font-size: 13px;\n color: #666;\n }\n .hidden { display: none; }\n</style>\n</head>\n<body>\n<div class=\"container\">\n <div id=\"form-view\">\n <h1>AgentPay</h1>\n <p class=\"subtitle\">${esc(actionLabel)}</p>\n ${contextHtml}\n <div class=\"card\">\n <label for=\"passphrase\">Passphrase</label>\n <input type=\"password\" id=\"passphrase\" placeholder=\"Enter your passphrase\" autofocus>\n <div id=\"error\" class=\"error hidden\"></div>\n <button id=\"submit\">${buttonLabel}</button>\n </div>\n </div>\n <div id=\"success-view\" class=\"hidden\">\n <h1>AgentPay</h1>\n <p class=\"subtitle\">${esc(actionLabel)}</p>\n <div class=\"card\">\n <div class=\"success-screen\">\n <div class=\"checkmark\">&#10003;</div>\n <div class=\"success-msg\">Passphrase received</div>\n <div class=\"success-hint\">You can close this tab.</div>\n </div>\n </div>\n </div>\n</div>\n<script>\n(function() {\n var token = ${JSON.stringify(token)};\n var form = document.getElementById('form-view');\n var success = document.getElementById('success-view');\n var input = document.getElementById('passphrase');\n var btn = document.getElementById('submit');\n var errDiv = document.getElementById('error');\n\n function submit() {\n var passphrase = input.value;\n if (!passphrase) {\n errDiv.textContent = 'Passphrase is required.';\n errDiv.classList.remove('hidden');\n return;\n }\n btn.disabled = true;\n btn.textContent = 'Submitting...';\n errDiv.classList.add('hidden');\n\n fetch('/passphrase', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ token: token, passphrase: passphrase })\n })\n .then(function(res) { return res.json(); })\n .then(function(data) {\n if (data.error) {\n errDiv.textContent = data.error;\n errDiv.classList.remove('hidden');\n btn.disabled = false;\n btn.textContent = '${buttonLabel}';\n } else {\n form.classList.add('hidden');\n success.classList.remove('hidden');\n }\n })\n .catch(function() {\n errDiv.textContent = 'Failed to submit. Is the CLI still running?';\n errDiv.classList.remove('hidden');\n btn.disabled = false;\n btn.textContent = '${buttonLabel}';\n });\n }\n\n btn.addEventListener('click', submit);\n input.addEventListener('keydown', function(e) {\n if (e.key === 'Enter') submit();\n });\n})();\n</script>\n</body>\n</html>`;\n}\n","import { exec } from 'node:child_process';\nimport { platform } from 'node:os';\n\nexport function openBrowser(url: string): void {\n const plat = platform();\n let cmd: string;\n if (plat === 'darwin') cmd = `open \"${url}\"`;\n else if (plat === 'win32') cmd = `start \"\" \"${url}\"`;\n else cmd = `xdg-open \"${url}\"`;\n\n exec(cmd, (err) => {\n if (err) {\n console.log(`Open ${url} in your browser.`);\n }\n });\n}\n","import { createServer, type IncomingMessage, type ServerResponse } from 'node:http';\nimport { randomBytes } from 'node:crypto';\nimport { getPassphraseHtml, type PassphraseContext } from './passphrase-html.js';\nimport { openBrowser } from '../utils/open-browser.js';\nimport { TimeoutError } from '../errors.js';\n\nconst TIMEOUT_MS = 5 * 60 * 1000; // 5 minutes\nconst MAX_BODY = 4096;\n\nfunction parseBody(req: IncomingMessage): Promise<Record<string, unknown>> {\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = [];\n let size = 0;\n req.on('data', (chunk: Buffer) => {\n size += chunk.length;\n if (size > MAX_BODY) {\n req.destroy();\n reject(new Error('Request body too large'));\n return;\n }\n chunks.push(chunk);\n });\n req.on('end', () => {\n try {\n const text = Buffer.concat(chunks).toString('utf8');\n resolve(text ? JSON.parse(text) : {});\n } catch {\n reject(new Error('Invalid JSON'));\n }\n });\n req.on('error', reject);\n });\n}\n\nfunction sendJson(res: ServerResponse, status: number, body: Record<string, unknown>): void {\n const json = JSON.stringify(body);\n res.writeHead(status, {\n 'Content-Type': 'application/json',\n 'Content-Length': Buffer.byteLength(json),\n });\n res.end(json);\n}\n\nfunction sendHtml(res: ServerResponse, html: string): void {\n res.writeHead(200, {\n 'Content-Type': 'text/html; charset=utf-8',\n 'Content-Length': Buffer.byteLength(html),\n });\n res.end(html);\n}\n\nexport type { PassphraseContext } from './passphrase-html.js';\n\n/**\n * Launch an ephemeral HTTP server on localhost, open a browser page\n * where the human enters their passphrase, and return it.\n * The passphrase never appears in stdout/stderr.\n */\nexport function collectPassphrase(context?: PassphraseContext): Promise<string> {\n return new Promise((resolve, reject) => {\n const nonce = randomBytes(32).toString('hex');\n let settled = false;\n\n const server = createServer(async (req, res) => {\n const url = new URL(req.url ?? '/', `http://${req.headers.host}`);\n const method = req.method ?? 'GET';\n\n try {\n if (method === 'GET' && url.pathname === '/passphrase') {\n const token = url.searchParams.get('token');\n if (token !== nonce) {\n sendHtml(res, '<h1>Invalid or expired link.</h1>');\n return;\n }\n sendHtml(res, getPassphraseHtml(nonce, context));\n } else if (method === 'POST' && url.pathname === '/passphrase') {\n const body = await parseBody(req);\n if (body.token !== nonce) {\n sendJson(res, 403, { error: 'Invalid token.' });\n return;\n }\n const passphrase = body.passphrase;\n if (typeof passphrase !== 'string' || !passphrase) {\n sendJson(res, 400, { error: 'Passphrase is required.' });\n return;\n }\n sendJson(res, 200, { ok: true });\n\n if (!settled) {\n settled = true;\n cleanup();\n resolve(passphrase);\n }\n } else {\n sendJson(res, 404, { error: 'Not found' });\n }\n } catch (err) {\n const message = err instanceof Error ? err.message : 'Internal error';\n sendJson(res, 500, { error: message });\n }\n });\n\n const timer = setTimeout(() => {\n if (!settled) {\n settled = true;\n cleanup();\n reject(new TimeoutError('Passphrase entry timed out after 5 minutes.'));\n }\n }, TIMEOUT_MS);\n\n function cleanup(): void {\n clearTimeout(timer);\n server.close();\n }\n\n server.on('error', (err) => {\n if (!settled) {\n settled = true;\n cleanup();\n reject(err);\n }\n });\n\n // Bind to localhost on a random available port\n server.listen(0, '127.0.0.1', () => {\n const addr = server.address();\n if (!addr || typeof addr === 'string') {\n if (!settled) {\n settled = true;\n cleanup();\n reject(new Error('Failed to bind server'));\n }\n return;\n }\n const url = `http://127.0.0.1:${addr.port}/passphrase?token=${nonce}`;\n console.log('Waiting for passphrase entry in browser...');\n openBrowser(url);\n });\n });\n}\n","import { createInterface } from 'node:readline';\nimport type { PassphraseContext } from '../server/passphrase-html.js';\n\nexport type { PassphraseContext } from '../server/passphrase-html.js';\n\nfunction createRl() {\n return createInterface({ input: process.stdin, output: process.stdout });\n}\n\nexport function promptInput(question: string): Promise<string> {\n return new Promise((resolve) => {\n const rl = createRl();\n rl.question(question, (answer) => {\n rl.close();\n resolve(answer.trim());\n });\n });\n}\n\nexport async function promptPassphrase(prompt = 'Passphrase: '): Promise<string> {\n // In a real terminal we'd hide input; for simplicity use standard prompt\n return promptInput(prompt);\n}\n\nexport function promptConfirm(question: string): Promise<boolean> {\n return new Promise((resolve) => {\n const rl = createRl();\n rl.question(`${question} (y/N): `, (answer) => {\n rl.close();\n resolve(answer.trim().toLowerCase() === 'y' || answer.trim().toLowerCase() === 'yes');\n });\n });\n}\n\n/**\n * Collect passphrase safely: uses terminal prompt when stdin is a TTY,\n * otherwise opens a browser page so the human can enter it directly\n * (keeping the passphrase out of the agent's context).\n */\nexport async function promptPassphraseSafe(context?: PassphraseContext): Promise<string> {\n if (process.stdin.isTTY) {\n return promptPassphrase('Enter passphrase: ');\n }\n // Dynamic import to avoid loading server code when not needed\n const { collectPassphrase } = await import('../server/passphrase-server.js');\n return collectPassphrase(context);\n}\n","import { mkdirSync } from 'node:fs';\nimport { promptPassphrase, promptInput } from '../utils/prompt.js';\nimport { encrypt, saveVault } from '../vault/vault.js';\nimport { generateKeyPair, saveKeyPair } from '../auth/keypair.js';\nimport { BudgetManager } from '../budget/budget.js';\nimport { AuditLogger } from '../audit/logger.js';\nimport { getHomePath, getCredentialsPath, getKeysPath } from '../utils/paths.js';\nimport type { BillingCredentials } from '../vault/types.js';\n\nexport async function setupCommand(): Promise<void> {\n console.log('AgentPay Setup');\n console.log('══════════════\\n');\n\n const home = getHomePath();\n mkdirSync(home, { recursive: true });\n\n // Passphrase\n const passphrase = await promptPassphrase('Choose a passphrase: ');\n const confirm = await promptPassphrase('Confirm passphrase: ');\n if (passphrase !== confirm) {\n console.error('Passphrases do not match.');\n process.exit(1);\n }\n\n // Card info\n console.log('\\nBilling Information');\n console.log('───────────────────');\n const cardNumber = await promptInput('Card number: ');\n const cardExpiry = await promptInput('Expiry (MM/YY): ');\n const cardCvv = await promptInput('CVV: ');\n\n // Personal info\n console.log('\\nPersonal Information');\n console.log('────────────────────');\n const name = await promptInput('Full name: ');\n const email = await promptInput('Email: ');\n const phone = await promptInput('Phone: ');\n\n // Billing address\n console.log('\\nBilling Address');\n console.log('───────────────');\n const billingStreet = await promptInput('Street: ');\n const billingCity = await promptInput('City: ');\n const billingState = await promptInput('State: ');\n const billingZip = await promptInput('ZIP: ');\n const billingCountry = await promptInput('Country (e.g. US): ');\n\n // Shipping address\n console.log('\\nShipping Address');\n console.log('────────────────');\n const sameAsBilling = await promptInput('Same as billing? (y/N): ');\n let shippingStreet: string, shippingCity: string, shippingState: string, shippingZip: string, shippingCountry: string;\n\n if (sameAsBilling.toLowerCase() === 'y' || sameAsBilling.toLowerCase() === 'yes') {\n shippingStreet = billingStreet;\n shippingCity = billingCity;\n shippingState = billingState;\n shippingZip = billingZip;\n shippingCountry = billingCountry;\n } else {\n shippingStreet = await promptInput('Street: ');\n shippingCity = await promptInput('City: ');\n shippingState = await promptInput('State: ');\n shippingZip = await promptInput('ZIP: ');\n shippingCountry = await promptInput('Country (e.g. US): ');\n }\n\n const credentials: BillingCredentials = {\n card: { number: cardNumber, expiry: cardExpiry, cvv: cardCvv },\n name,\n billingAddress: { street: billingStreet, city: billingCity, state: billingState, zip: billingZip, country: billingCountry },\n shippingAddress: { street: shippingStreet, city: shippingCity, state: shippingState, zip: shippingZip, country: shippingCountry },\n email,\n phone,\n };\n\n // Encrypt and save vault\n const vault = encrypt(credentials, passphrase);\n saveVault(vault, getCredentialsPath());\n console.log('\\nCredentials encrypted and saved.');\n\n // Generate and save keypair\n const keys = generateKeyPair(passphrase);\n mkdirSync(getKeysPath(), { recursive: true });\n saveKeyPair(keys);\n console.log('Keypair generated.');\n\n // Initialize wallet\n const bm = new BudgetManager();\n bm.initWallet(0, 0);\n console.log('Wallet initialized.');\n\n // Audit\n const audit = new AuditLogger();\n audit.log('SETUP', { message: 'credentials encrypted, keypair generated, wallet initialized' });\n\n console.log('\\nSetup complete! Next steps:');\n console.log(' agentpay budget --set 200 Set your spending budget');\n console.log(' agentpay budget --limit-per-tx 50 Set per-transaction limit');\n}\n","import { BudgetManager } from '../budget/budget.js';\nimport { AuditLogger } from '../audit/logger.js';\nimport { formatCurrency } from '../utils/display.js';\n\nexport function budgetCommand(options: { set?: string; limitPerTx?: string }): void {\n const bm = new BudgetManager();\n const audit = new AuditLogger();\n\n if (options.set) {\n const amount = parseFloat(options.set);\n if (isNaN(amount) || amount < 0) {\n console.error('Invalid amount. Provide a positive number.');\n process.exit(1);\n }\n bm.setBudget(amount);\n audit.log('BUDGET_SET', { amount });\n console.log(`Budget set to ${formatCurrency(amount)}.`);\n }\n\n if (options.limitPerTx) {\n const limit = parseFloat(options.limitPerTx);\n if (isNaN(limit) || limit < 0) {\n console.error('Invalid limit. Provide a positive number.');\n process.exit(1);\n }\n bm.setLimitPerTx(limit);\n audit.log('LIMIT_SET', { limitPerTx: limit });\n console.log(`Per-transaction limit set to ${formatCurrency(limit)}.`);\n }\n\n if (!options.set && !options.limitPerTx) {\n const balance = bm.getBalance();\n console.log(`Budget: ${formatCurrency(balance.budget)}`);\n console.log(`Balance: ${formatCurrency(balance.balance)}`);\n console.log(`Spent: ${formatCurrency(balance.spent)}`);\n console.log(`Per-tx limit: ${balance.limitPerTx > 0 ? formatCurrency(balance.limitPerTx) : 'None'}`);\n }\n}\n","import { TransactionManager } from '../transactions/manager.js';\nimport { formatCurrency } from '../utils/display.js';\n\nexport function pendingCommand(): void {\n const tm = new TransactionManager();\n const pending = tm.getPending();\n\n if (pending.length === 0) {\n console.log('No pending purchases.');\n return;\n }\n\n console.log('Pending Purchases:');\n console.log('─────────────────');\n console.log('TX_ID MERCHANT AMOUNT DESCRIPTION');\n\n for (const tx of pending) {\n const id = tx.id.padEnd(14);\n const merchant = tx.merchant.padEnd(16);\n const amount = formatCurrency(tx.amount).padStart(9);\n console.log(`${id}${merchant}${amount} ${tx.description}`);\n }\n\n console.log(`\\n${pending.length} pending purchase${pending.length === 1 ? '' : 's'}. Use 'agentpay approve <txId>' or 'agentpay reject <txId>'.`);\n}\n","import { TransactionManager } from '../transactions/manager.js';\nimport { loadPrivateKey, loadPublicKey } from '../auth/keypair.js';\nimport { createMandate } from '../auth/mandate.js';\nimport { AuditLogger } from '../audit/logger.js';\nimport { promptPassphraseSafe } from '../utils/prompt.js';\nimport { formatCurrency } from '../utils/display.js';\nimport type { TransactionDetails } from '../auth/types.js';\n\nexport async function approveCommand(txId: string): Promise<void> {\n const tm = new TransactionManager();\n const audit = new AuditLogger();\n\n const tx = tm.get(txId);\n if (!tx) {\n console.error(`Transaction ${txId} not found.`);\n process.exit(1);\n }\n if (tx.status !== 'pending') {\n console.error(`Cannot approve transaction in '${tx.status}' state.`);\n process.exit(1);\n }\n\n console.log(`Approve purchase:`);\n console.log(` Merchant: ${tx.merchant}`);\n console.log(` Amount: ${formatCurrency(tx.amount)}`);\n console.log(` Description: ${tx.description}`);\n console.log();\n\n const passphrase = await promptPassphraseSafe({\n action: 'approve',\n merchant: tx.merchant,\n amount: tx.amount,\n description: tx.description,\n txId,\n });\n\n try {\n const privateKeyPem = loadPrivateKey();\n const txDetails: TransactionDetails = {\n txId: tx.id,\n merchant: tx.merchant,\n amount: tx.amount,\n description: tx.description,\n timestamp: tx.createdAt,\n };\n\n const mandate = createMandate(txDetails, privateKeyPem, passphrase);\n tm.approve(txId, mandate);\n audit.log('APPROVE', { txId, mandateSigned: true });\n\n console.log(`\\nApproved! Transaction ${txId} is now ready for execution.`);\n } catch (err) {\n console.error(`Failed to approve: ${err instanceof Error ? err.message : 'Unknown error'}`);\n process.exit(1);\n }\n}\n","import { TransactionManager } from '../transactions/manager.js';\nimport { AuditLogger } from '../audit/logger.js';\n\nexport function rejectCommand(txId: string, options: { reason?: string }): void {\n const tm = new TransactionManager();\n const audit = new AuditLogger();\n\n const tx = tm.get(txId);\n if (!tx) {\n console.error(`Transaction ${txId} not found.`);\n process.exit(1);\n }\n if (tx.status !== 'pending') {\n console.error(`Cannot reject transaction in '${tx.status}' state.`);\n process.exit(1);\n }\n\n tm.reject(txId, options.reason);\n audit.log('REJECT', { txId, reason: options.reason });\n\n console.log(`Rejected transaction ${txId}.${options.reason ? ` Reason: ${options.reason}` : ''}`);\n}\n","import { AgentPay } from '../agentpay.js';\nimport { formatStatus } from '../utils/display.js';\n\nexport function statusCommand(): void {\n const ap = new AgentPay();\n const s = ap.status();\n\n if (!s.isSetup) {\n console.log('AgentPay is not set up. Run `agentpay setup` first.');\n return;\n }\n\n console.log(formatStatus({\n balance: s.balance,\n budget: s.budget,\n limitPerTx: s.limitPerTx,\n pending: s.pending,\n recent: s.recent,\n }));\n}\n","import { TransactionManager } from '../transactions/manager.js';\nimport { formatCurrency, formatTimestamp } from '../utils/display.js';\n\nexport function historyCommand(): void {\n const tm = new TransactionManager();\n const history = tm.getHistory();\n\n if (history.length === 0) {\n console.log('No transaction history.');\n return;\n }\n\n console.log('Transaction History:');\n console.log('─────────────────────');\n console.log('STATUS TX_ID MERCHANT AMOUNT DATE DESCRIPTION');\n\n for (const tx of history) {\n const status = `[${tx.status}]`.padEnd(13);\n const id = tx.id.padEnd(14);\n const merchant = tx.merchant.padEnd(16);\n const amount = formatCurrency(tx.amount).padStart(9);\n const date = formatTimestamp(tx.createdAt).padEnd(18);\n console.log(`${status}${id}${merchant}${amount} ${date}${tx.description}`);\n }\n}\n","import QRCode from 'qrcode';\n\nexport async function qrCommand(options: { budget?: string; message?: string }): Promise<void> {\n const params = new URLSearchParams();\n if (options.budget) params.set('budget', options.budget);\n if (options.message) params.set('msg', options.message);\n\n const baseUrl = process.env.AGENTPAY_WEB_URL ?? 'http://localhost:3000';\n const url = `${baseUrl}/setup${params.toString() ? `?${params.toString()}` : ''}`;\n\n console.log('Scan this QR code to set up AgentPay:\\n');\n\n const qrString = await QRCode.toString(url, { type: 'terminal', small: true });\n console.log(qrString);\n console.log(`\\nURL: ${url}`);\n}\n","import { rmSync, existsSync } from 'node:fs';\nimport { promptInput } from '../utils/prompt.js';\nimport { getHomePath } from '../utils/paths.js';\n\nexport async function resetCommand(): Promise<void> {\n const home = getHomePath();\n\n if (!existsSync(home)) {\n console.log('Nothing to reset. AgentPay data directory does not exist.');\n return;\n }\n\n console.log(`This will permanently delete all AgentPay data at: ${home}`);\n console.log('This includes encrypted credentials, keys, wallet, transactions, and audit logs.');\n const answer = await promptInput('\\nType YES to confirm: ');\n\n if (answer !== 'YES') {\n console.log('Cancelled.');\n return;\n }\n\n rmSync(home, { recursive: true, force: true });\n console.log('All AgentPay data has been deleted.');\n}\n","import { readFileSync } from 'node:fs';\nimport { resolve } from 'node:path';\nimport { promptPassphraseSafe, promptConfirm } from '../utils/prompt.js';\nimport { formatCurrency } from '../utils/display.js';\nimport { PurchaseExecutor } from '../executor/executor.js';\nimport { BudgetManager } from '../budget/budget.js';\nimport { TransactionManager } from '../transactions/manager.js';\nimport { AuditLogger } from '../audit/logger.js';\nimport { loadPrivateKey } from '../auth/keypair.js';\nimport { createMandate } from '../auth/mandate.js';\nimport { decrypt, loadVault } from '../vault/vault.js';\nimport { getCredentialsPath } from '../utils/paths.js';\n\n// Load .env file if present (no external dependency)\nfunction loadEnv(): void {\n try {\n const envPath = resolve(process.cwd(), '.env');\n const content = readFileSync(envPath, 'utf8');\n for (const line of content.split('\\n')) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith('#')) continue;\n const eqIdx = trimmed.indexOf('=');\n if (eqIdx === -1) continue;\n const key = trimmed.slice(0, eqIdx).trim();\n const value = trimmed.slice(eqIdx + 1).trim();\n if (!process.env[key]) {\n process.env[key] = value;\n }\n }\n } catch {\n // No .env file — that's fine\n }\n}\n\ninterface BuyOptions {\n merchant: string;\n amount?: string;\n description: string;\n url: string;\n pickup?: boolean;\n}\n\nexport async function buyCommand(options: BuyOptions): Promise<void> {\n loadEnv();\n\n console.log('AgentPay Purchase');\n console.log('═════════════════\\n');\n\n const executor = new PurchaseExecutor();\n const bm = new BudgetManager();\n const tm = new TransactionManager();\n const audit = new AuditLogger();\n const isTTY = process.stdin.isTTY;\n\n // Phase 1: Discover price (no credentials needed)\n let amount: number;\n let productName: string = options.description;\n\n if (options.amount) {\n // Amount provided upfront\n amount = parseFloat(options.amount);\n if (isNaN(amount) || amount <= 0) {\n console.error('Invalid amount.');\n process.exit(1);\n }\n console.log(` Merchant: ${options.merchant}`);\n console.log(` Amount: ${formatCurrency(amount)}`);\n console.log(` Description: ${options.description}`);\n console.log(` URL: ${options.url}`);\n console.log();\n } else {\n // Phase 1: Navigate and discover price\n const pickupHint = options.pickup ? 'Select in-store pickup if available.' : '';\n const instructions = [pickupHint, options.description].filter(Boolean).join(' ');\n\n console.log('Opening browser to discover price...\\n');\n try {\n const discovered = await executor.openAndDiscover(options.url, instructions || undefined);\n amount = discovered.price;\n productName = discovered.productName || options.description;\n } catch (err) {\n console.error(`Failed to load product page: ${err instanceof Error ? err.message : 'Unknown error'}`);\n await executor.close();\n process.exit(1);\n }\n\n if (amount <= 0) {\n console.error('Could not extract price from the page.');\n await executor.close();\n process.exit(1);\n }\n\n console.log(` Product: ${productName}`);\n console.log(` Merchant: ${options.merchant}`);\n console.log(` Amount: ${formatCurrency(amount)}`);\n console.log();\n }\n\n // Check balance\n try {\n bm.checkProposal(amount);\n } catch (err) {\n console.error(err instanceof Error ? err.message : 'Budget check failed.');\n await executor.close();\n process.exit(1);\n }\n\n // Phase 3: Collect passphrase (+ confirmation)\n // In TTY mode: confirm first, then prompt passphrase in terminal.\n // In non-TTY mode: browser page shows purchase details and acts as both\n // confirmation and passphrase entry — agent never sees the passphrase.\n let passphrase: string;\n if (isTTY) {\n const confirmed = await promptConfirm('Approve this purchase?');\n if (!confirmed) {\n console.log('Purchase cancelled.');\n await executor.close();\n process.exit(0);\n }\n passphrase = await promptPassphraseSafe();\n } else {\n passphrase = await promptPassphraseSafe({\n action: 'buy',\n merchant: options.merchant,\n amount,\n description: productName,\n });\n console.log('Passphrase received. Continuing...');\n }\n\n // Phase 4: Decrypt credentials\n const vault = loadVault(getCredentialsPath());\n const credentials = decrypt(vault, passphrase);\n\n // Phase 5: Propose transaction + sign mandate\n console.log('\\nProposing transaction...');\n const tx = tm.propose({\n merchant: options.merchant,\n amount,\n description: productName,\n url: options.url,\n });\n audit.log('PROPOSE', { txId: tx.id, merchant: tx.merchant, amount: tx.amount, source: 'buy-command' });\n console.log(` Transaction ${tx.id} created.`);\n\n // Approve (self-approve — human is running the CLI directly)\n const privateKeyPem = loadPrivateKey();\n const mandate = createMandate(\n { txId: tx.id, merchant: tx.merchant, amount: tx.amount, description: tx.description, timestamp: tx.createdAt },\n privateKeyPem,\n passphrase,\n );\n tm.approve(tx.id, mandate);\n audit.log('APPROVE', { txId: tx.id, source: 'buy-command', mandateSigned: true });\n console.log(' Approved and signed.\\n');\n\n // Execute checkout\n console.log('Filling checkout...');\n tm.markExecuting(tx.id);\n audit.log('EXECUTE', { txId: tx.id, source: 'buy-command' });\n\n try {\n let result;\n if (!options.amount) {\n // Session already open from openAndDiscover — continue with fillAndComplete\n result = await executor.fillAndComplete(credentials);\n } else {\n // No session open yet — use single-shot execute\n result = await executor.execute(tx, credentials);\n }\n\n const receipt = {\n id: `rcpt_${tx.id.replace('tx_', '')}`,\n merchant: tx.merchant,\n amount: tx.amount,\n confirmationId: result.confirmationId ?? 'UNKNOWN',\n completedAt: new Date().toISOString(),\n };\n tm.markCompleted(tx.id, receipt);\n bm.deductBalance(tx.amount);\n audit.log('COMPLETE', { txId: tx.id, confirmationId: receipt.confirmationId, source: 'buy-command' });\n\n console.log(`\\nPurchase complete!`);\n console.log(` Confirmation: ${receipt.confirmationId}`);\n console.log(` Amount: ${formatCurrency(receipt.amount)}`);\n } catch (err) {\n tm.markFailed(tx.id, err instanceof Error ? err.message : 'Unknown error');\n audit.log('FAILED', { txId: tx.id, error: err instanceof Error ? err.message : 'Unknown', source: 'buy-command' });\n console.error(`\\nCheckout failed: ${err instanceof Error ? err.message : 'Unknown error'}`);\n process.exit(1);\n } finally {\n await executor.close();\n }\n}\n","export function getDashboardHtml(): string {\n return `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n<title>AgentPay Dashboard</title>\n<style>\n *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }\n body {\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n background: #f5f5f5;\n color: #111;\n min-height: 100vh;\n display: flex;\n justify-content: center;\n padding: 40px 16px;\n }\n .container { width: 100%; max-width: 480px; }\n h1 { font-size: 24px; font-weight: 700; margin-bottom: 8px; }\n h2 { font-size: 18px; font-weight: 600; margin-bottom: 12px; }\n .subtitle { color: #666; font-size: 14px; margin-bottom: 32px; }\n .card {\n background: #fff;\n border-radius: 8px;\n padding: 24px;\n margin-bottom: 16px;\n border: 1px solid #e0e0e0;\n }\n label { display: block; font-size: 13px; font-weight: 500; color: #333; margin-bottom: 4px; }\n input, select {\n width: 100%;\n padding: 10px 12px;\n border: 1px solid #d0d0d0;\n border-radius: 8px;\n font-size: 14px;\n margin-bottom: 16px;\n outline: none;\n transition: border-color 0.15s;\n }\n input:focus { border-color: #111; }\n .row { display: flex; gap: 12px; }\n .row > div { flex: 1; }\n button {\n width: 100%;\n padding: 12px;\n border: none;\n border-radius: 8px;\n font-size: 14px;\n font-weight: 600;\n cursor: pointer;\n transition: opacity 0.15s;\n }\n button:hover { opacity: 0.85; }\n button:disabled { opacity: 0.5; cursor: not-allowed; }\n .btn-primary { background: #111; color: #fff; }\n .btn-secondary { background: #e0e0e0; color: #111; }\n\n /* Progress bar for wizard */\n .progress { display: flex; gap: 6px; margin-bottom: 24px; }\n .progress .step {\n flex: 1; height: 4px; border-radius: 2px; background: #e0e0e0;\n transition: background 0.3s;\n }\n .progress .step.active { background: #111; }\n\n /* Balance display */\n .balance-display {\n text-align: center;\n padding: 32px 0;\n }\n .balance-amount {\n font-size: 48px;\n font-weight: 700;\n letter-spacing: -1px;\n }\n .balance-label { font-size: 13px; color: #666; margin-top: 4px; }\n\n /* Budget bar */\n .budget-bar-container { margin: 16px 0; }\n .budget-bar {\n height: 8px;\n background: #e0e0e0;\n border-radius: 4px;\n overflow: hidden;\n }\n .budget-bar-fill {\n height: 100%;\n background: #111;\n border-radius: 4px;\n transition: width 0.3s;\n }\n .budget-bar-labels {\n display: flex;\n justify-content: space-between;\n font-size: 12px;\n color: #666;\n margin-top: 4px;\n }\n\n /* Stats grid */\n .stats { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-bottom: 16px; }\n .stat { text-align: center; padding: 12px; background: #f9f9f9; border-radius: 8px; }\n .stat-value { font-size: 18px; font-weight: 700; }\n .stat-label { font-size: 11px; color: #666; margin-top: 2px; }\n\n /* Add funds inline */\n .add-funds-row { display: flex; gap: 8px; }\n .add-funds-row input { margin-bottom: 0; flex: 1; }\n .add-funds-row button { width: auto; padding: 10px 20px; }\n\n /* Transactions */\n .tx-list { margin-top: 12px; }\n .tx-item {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 10px 0;\n border-bottom: 1px solid #f0f0f0;\n font-size: 13px;\n }\n .tx-item:last-child { border-bottom: none; }\n .tx-merchant { font-weight: 500; }\n .tx-amount { font-weight: 600; }\n .tx-status {\n font-size: 11px;\n padding: 2px 6px;\n border-radius: 4px;\n font-weight: 500;\n }\n .tx-status.completed { background: #e6f4ea; color: #1e7e34; }\n .tx-status.pending { background: #fff8e1; color: #f57f17; }\n .tx-status.failed { background: #fde8e8; color: #c62828; }\n .tx-status.rejected { background: #fde8e8; color: #c62828; }\n .tx-status.approved { background: #e3f2fd; color: #1565c0; }\n .tx-status.executing { background: #e3f2fd; color: #1565c0; }\n\n .error { color: #c62828; font-size: 13px; margin-top: 8px; }\n .success { color: #1e7e34; font-size: 13px; margin-top: 8px; }\n .hidden { display: none; }\n\n /* Checkbox row for same-as-billing */\n .checkbox-row {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 16px;\n }\n .checkbox-row input { width: auto; margin: 0; }\n .checkbox-row label { margin: 0; }\n</style>\n</head>\n<body>\n<div class=\"container\" id=\"app\">\n <div id=\"loading\">Loading...</div>\n</div>\n\n<script>\nconst App = {\n state: { isSetup: false, wallet: null, recentTransactions: [], wizardStep: 1 },\n\n async init() {\n try {\n const res = await fetch('/api/status');\n const data = await res.json();\n this.state.isSetup = data.isSetup;\n this.state.wallet = data.wallet;\n this.state.recentTransactions = data.recentTransactions || [];\n } catch (e) {\n console.error('Failed to load status', e);\n }\n this.render();\n },\n\n render() {\n const app = document.getElementById('app');\n if (this.state.isSetup && this.state.wallet) {\n app.innerHTML = this.renderDashboard();\n this.bindDashboard();\n } else if (this.state.isSetup) {\n app.innerHTML = '<div class=\"card\"><h2>Setup detected</h2><p>Wallet data could not be loaded. Try running <code>agentpay budget --set 100</code> from the CLI.</p></div>';\n } else {\n app.innerHTML = this.renderWizard();\n this.bindWizard();\n }\n },\n\n fmt(n) {\n return '$' + Number(n).toFixed(2);\n },\n\n renderDashboard() {\n const w = this.state.wallet;\n const pct = w.budget > 0 ? Math.min(100, (w.spent / w.budget) * 100) : 0;\n const txHtml = this.state.recentTransactions.length === 0\n ? '<p style=\"color:#666;font-size:13px;\">No transactions yet.</p>'\n : this.state.recentTransactions.map(tx => \\`\n <div class=\"tx-item\">\n <div>\n <div class=\"tx-merchant\">\\${this.esc(tx.merchant)}</div>\n <div style=\"color:#999;font-size:11px;\">\\${new Date(tx.createdAt).toLocaleDateString()}</div>\n </div>\n <div style=\"text-align:right\">\n <div class=\"tx-amount\">\\${this.fmt(tx.amount)}</div>\n <span class=\"tx-status \\${tx.status}\">\\${tx.status}</span>\n </div>\n </div>\\`).join('');\n\n return \\`\n <h1>AgentPay</h1>\n <p class=\"subtitle\">Wallet Dashboard</p>\n\n <div class=\"card\">\n <div class=\"balance-display\">\n <div class=\"balance-amount\">\\${this.fmt(w.balance)}</div>\n <div class=\"balance-label\">Available Balance</div>\n </div>\n <div class=\"budget-bar-container\">\n <div class=\"budget-bar\"><div class=\"budget-bar-fill\" style=\"width:\\${pct.toFixed(1)}%\"></div></div>\n <div class=\"budget-bar-labels\">\n <span>\\${this.fmt(w.spent)} spent</span>\n <span>\\${this.fmt(w.budget)} budget</span>\n </div>\n </div>\n </div>\n\n <div class=\"card\">\n <div class=\"stats\">\n <div class=\"stat\"><div class=\"stat-value\">\\${this.fmt(w.budget)}</div><div class=\"stat-label\">Total Budget</div></div>\n <div class=\"stat\"><div class=\"stat-value\">\\${this.fmt(w.spent)}</div><div class=\"stat-label\">Total Spent</div></div>\n <div class=\"stat\"><div class=\"stat-value\">\\${this.fmt(w.balance)}</div><div class=\"stat-label\">Remaining</div></div>\n <div class=\"stat\"><div class=\"stat-value\">\\${w.limitPerTx > 0 ? this.fmt(w.limitPerTx) : 'None'}</div><div class=\"stat-label\">Per-Tx Limit</div></div>\n </div>\n </div>\n\n <div class=\"card\">\n <h2>Add Funds</h2>\n <div class=\"add-funds-row\">\n <input type=\"number\" id=\"fundAmount\" placeholder=\"Amount\" min=\"0.01\" step=\"0.01\">\n <button class=\"btn-primary\" id=\"fundBtn\">Add</button>\n </div>\n <div id=\"fundMsg\"></div>\n </div>\n\n <div class=\"card\">\n <h2>Recent Transactions</h2>\n <div class=\"tx-list\">\\${txHtml}</div>\n </div>\n \\`;\n },\n\n bindDashboard() {\n const btn = document.getElementById('fundBtn');\n const input = document.getElementById('fundAmount');\n const msg = document.getElementById('fundMsg');\n\n btn.addEventListener('click', async () => {\n const amount = parseFloat(input.value);\n if (!amount || amount <= 0) {\n msg.innerHTML = '<p class=\"error\">Enter a valid amount.</p>';\n return;\n }\n btn.disabled = true;\n btn.textContent = '...';\n try {\n const res = await fetch('/api/fund', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ amount }),\n });\n const data = await res.json();\n if (data.error) {\n msg.innerHTML = '<p class=\"error\">' + this.esc(data.error) + '</p>';\n } else {\n this.state.wallet = data.wallet;\n input.value = '';\n this.render();\n }\n } catch (e) {\n msg.innerHTML = '<p class=\"error\">Request failed.</p>';\n }\n btn.disabled = false;\n btn.textContent = 'Add';\n });\n },\n\n renderWizard() {\n const step = this.state.wizardStep;\n const steps = [1, 2, 3, 4];\n const progressHtml = '<div class=\"progress\">' + steps.map(s =>\n '<div class=\"step' + (s <= step ? ' active' : '') + '\"></div>'\n ).join('') + '</div>';\n\n const titles = ['Create Passphrase', 'Card Information', 'Personal Details', 'Budget & Limits'];\n\n let fields = '';\n if (step === 1) {\n fields = \\`\n <label for=\"w_pass\">Passphrase</label>\n <input type=\"password\" id=\"w_pass\" placeholder=\"Choose a strong passphrase\">\n <label for=\"w_pass2\">Confirm Passphrase</label>\n <input type=\"password\" id=\"w_pass2\" placeholder=\"Confirm your passphrase\">\n \\`;\n } else if (step === 2) {\n fields = \\`\n <label for=\"w_cardNum\">Card Number</label>\n <input type=\"text\" id=\"w_cardNum\" placeholder=\"4242 4242 4242 4242\">\n <div class=\"row\">\n <div><label for=\"w_expiry\">Expiry</label><input type=\"text\" id=\"w_expiry\" placeholder=\"MM/YY\"></div>\n <div><label for=\"w_cvv\">CVV</label><input type=\"text\" id=\"w_cvv\" placeholder=\"123\"></div>\n </div>\n \\`;\n } else if (step === 3) {\n fields = \\`\n <label for=\"w_name\">Full Name</label>\n <input type=\"text\" id=\"w_name\" placeholder=\"Jane Doe\">\n <div class=\"row\">\n <div><label for=\"w_email\">Email</label><input type=\"email\" id=\"w_email\" placeholder=\"jane@example.com\"></div>\n <div><label for=\"w_phone\">Phone</label><input type=\"tel\" id=\"w_phone\" placeholder=\"+1 555 0123\"></div>\n </div>\n <label for=\"w_street\">Street Address</label>\n <input type=\"text\" id=\"w_street\" placeholder=\"123 Main St\">\n <div class=\"row\">\n <div><label for=\"w_city\">City</label><input type=\"text\" id=\"w_city\" placeholder=\"San Francisco\"></div>\n <div><label for=\"w_state\">State</label><input type=\"text\" id=\"w_state\" placeholder=\"CA\"></div>\n </div>\n <div class=\"row\">\n <div><label for=\"w_zip\">ZIP</label><input type=\"text\" id=\"w_zip\" placeholder=\"94102\"></div>\n <div><label for=\"w_country\">Country</label><input type=\"text\" id=\"w_country\" placeholder=\"US\" value=\"US\"></div>\n </div>\n \\`;\n } else if (step === 4) {\n fields = \\`\n <label for=\"w_budget\">Initial Budget ($)</label>\n <input type=\"number\" id=\"w_budget\" placeholder=\"200\" min=\"0\" step=\"0.01\">\n <label for=\"w_limit\">Per-Transaction Limit ($)</label>\n <input type=\"number\" id=\"w_limit\" placeholder=\"50 (0 = no limit)\" min=\"0\" step=\"0.01\">\n \\`;\n }\n\n return \\`\n <h1>AgentPay</h1>\n <p class=\"subtitle\">Step \\${step} of 4 — \\${titles[step - 1]}</p>\n \\${progressHtml}\n <div class=\"card\">\n \\${fields}\n <div id=\"wizardError\"></div>\n <div style=\"display:flex;gap:8px;margin-top:8px;\">\n \\${step > 1 ? '<button class=\"btn-secondary\" id=\"wizBack\">Back</button>' : ''}\n <button class=\"btn-primary\" id=\"wizNext\">\\${step === 4 ? 'Complete Setup' : 'Continue'}</button>\n </div>\n </div>\n \\`;\n },\n\n // Wizard form data persisted across steps\n wizardData: {},\n\n bindWizard() {\n const step = this.state.wizardStep;\n const errDiv = document.getElementById('wizardError');\n const nextBtn = document.getElementById('wizNext');\n const backBtn = document.getElementById('wizBack');\n\n // Restore saved data into fields\n this.restoreWizardFields(step);\n\n if (backBtn) {\n backBtn.addEventListener('click', () => {\n this.saveWizardFields(step);\n this.state.wizardStep--;\n this.render();\n });\n }\n\n nextBtn.addEventListener('click', async () => {\n errDiv.innerHTML = '';\n\n if (step === 1) {\n const pass = document.getElementById('w_pass').value;\n const pass2 = document.getElementById('w_pass2').value;\n if (!pass) { errDiv.innerHTML = '<p class=\"error\">Passphrase is required.</p>'; return; }\n if (pass !== pass2) { errDiv.innerHTML = '<p class=\"error\">Passphrases do not match.</p>'; return; }\n this.wizardData.passphrase = pass;\n this.state.wizardStep = 2;\n this.render();\n } else if (step === 2) {\n this.saveWizardFields(step);\n const d = this.wizardData;\n if (!d.cardNumber) { errDiv.innerHTML = '<p class=\"error\">Card number is required.</p>'; return; }\n if (!d.expiry) { errDiv.innerHTML = '<p class=\"error\">Expiry is required.</p>'; return; }\n if (!d.cvv) { errDiv.innerHTML = '<p class=\"error\">CVV is required.</p>'; return; }\n this.state.wizardStep = 3;\n this.render();\n } else if (step === 3) {\n this.saveWizardFields(step);\n const d = this.wizardData;\n if (!d.name) { errDiv.innerHTML = '<p class=\"error\">Full name is required.</p>'; return; }\n this.state.wizardStep = 4;\n this.render();\n } else if (step === 4) {\n this.saveWizardFields(step);\n const d = this.wizardData;\n\n nextBtn.disabled = true;\n nextBtn.textContent = 'Setting up...';\n\n try {\n const res = await fetch('/api/setup', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n passphrase: d.passphrase,\n credentials: {\n card: { number: d.cardNumber, expiry: d.expiry, cvv: d.cvv },\n name: d.name,\n billingAddress: { street: d.street || '', city: d.city || '', state: d.state || '', zip: d.zip || '', country: d.country || 'US' },\n shippingAddress: { street: d.street || '', city: d.city || '', state: d.state || '', zip: d.zip || '', country: d.country || 'US' },\n email: d.email || '',\n phone: d.phone || '',\n },\n budget: parseFloat(d.budget) || 0,\n limitPerTx: parseFloat(d.limit) || 0,\n }),\n });\n const result = await res.json();\n if (result.error) {\n errDiv.innerHTML = '<p class=\"error\">' + this.esc(result.error) + '</p>';\n nextBtn.disabled = false;\n nextBtn.textContent = 'Complete Setup';\n } else {\n this.state.isSetup = true;\n this.state.wallet = result.wallet;\n this.state.recentTransactions = [];\n this.wizardData = {};\n this.render();\n }\n } catch (e) {\n errDiv.innerHTML = '<p class=\"error\">Setup request failed.</p>';\n nextBtn.disabled = false;\n nextBtn.textContent = 'Complete Setup';\n }\n }\n });\n },\n\n saveWizardFields(step) {\n const val = (id) => { const el = document.getElementById(id); return el ? el.value : ''; };\n if (step === 2) {\n this.wizardData.cardNumber = val('w_cardNum');\n this.wizardData.expiry = val('w_expiry');\n this.wizardData.cvv = val('w_cvv');\n } else if (step === 3) {\n this.wizardData.name = val('w_name');\n this.wizardData.email = val('w_email');\n this.wizardData.phone = val('w_phone');\n this.wizardData.street = val('w_street');\n this.wizardData.city = val('w_city');\n this.wizardData.state = val('w_state');\n this.wizardData.zip = val('w_zip');\n this.wizardData.country = val('w_country');\n } else if (step === 4) {\n this.wizardData.budget = val('w_budget');\n this.wizardData.limit = val('w_limit');\n }\n },\n\n restoreWizardFields(step) {\n const set = (id, val) => { const el = document.getElementById(id); if (el && val) el.value = val; };\n if (step === 2) {\n set('w_cardNum', this.wizardData.cardNumber);\n set('w_expiry', this.wizardData.expiry);\n set('w_cvv', this.wizardData.cvv);\n } else if (step === 3) {\n set('w_name', this.wizardData.name);\n set('w_email', this.wizardData.email);\n set('w_phone', this.wizardData.phone);\n set('w_street', this.wizardData.street);\n set('w_city', this.wizardData.city);\n set('w_state', this.wizardData.state);\n set('w_zip', this.wizardData.zip);\n set('w_country', this.wizardData.country);\n } else if (step === 4) {\n set('w_budget', this.wizardData.budget);\n set('w_limit', this.wizardData.limit);\n }\n },\n\n esc(s) {\n const d = document.createElement('div');\n d.textContent = s;\n return d.innerHTML;\n },\n};\n\nApp.init();\n</script>\n</body>\n</html>`;\n}\n","import { existsSync, mkdirSync } from 'node:fs';\nimport { encrypt, saveVault } from '../vault/vault.js';\nimport { generateKeyPair, saveKeyPair } from '../auth/keypair.js';\nimport { BudgetManager } from '../budget/budget.js';\nimport { TransactionManager } from '../transactions/manager.js';\nimport { AuditLogger } from '../audit/logger.js';\nimport { getCredentialsPath, getHomePath, getKeysPath } from '../utils/paths.js';\nimport type { BillingCredentials } from '../vault/types.js';\n\ninterface RouteResult {\n status: number;\n body: Record<string, unknown>;\n}\n\nexport function handleGetStatus(): RouteResult {\n const isSetup = existsSync(getCredentialsPath());\n\n if (!isSetup) {\n return { status: 200, body: { isSetup: false } };\n }\n\n try {\n const bm = new BudgetManager();\n const wallet = bm.getBalance();\n const tm = new TransactionManager();\n const recent = tm.list().slice(-10).reverse();\n\n return {\n status: 200,\n body: { isSetup: true, wallet, recentTransactions: recent },\n };\n } catch {\n return { status: 200, body: { isSetup: true, wallet: null, recentTransactions: [] } };\n }\n}\n\ninterface SetupBody {\n passphrase: string;\n credentials: BillingCredentials;\n budget: number;\n limitPerTx: number;\n}\n\nexport function handlePostSetup(body: SetupBody): RouteResult {\n if (!body.passphrase || !body.credentials) {\n return { status: 400, body: { error: 'Missing passphrase or credentials' } };\n }\n\n try {\n const home = getHomePath();\n mkdirSync(home, { recursive: true });\n\n // Encrypt and save vault\n const vault = encrypt(body.credentials, body.passphrase);\n saveVault(vault, getCredentialsPath());\n\n // Generate and save keypair\n const keys = generateKeyPair(body.passphrase);\n mkdirSync(getKeysPath(), { recursive: true });\n saveKeyPair(keys);\n\n // Initialize wallet\n const bm = new BudgetManager();\n bm.initWallet(body.budget || 0, body.limitPerTx || 0);\n\n // Audit\n const audit = new AuditLogger();\n audit.log('SETUP', { source: 'dashboard', message: 'credentials encrypted, keypair generated, wallet initialized' });\n\n const wallet = bm.getBalance();\n return { status: 200, body: { success: true, wallet } };\n } catch (err) {\n const message = err instanceof Error ? err.message : 'Setup failed';\n return { status: 500, body: { error: message } };\n }\n}\n\ninterface FundBody {\n amount: number;\n}\n\nexport function handlePostFund(body: FundBody): RouteResult {\n if (!body.amount || body.amount <= 0) {\n return { status: 400, body: { error: 'Amount must be positive' } };\n }\n\n try {\n const bm = new BudgetManager();\n const wallet = bm.addFunds(body.amount);\n\n const audit = new AuditLogger();\n audit.log('ADD_FUNDS', { source: 'dashboard', amount: body.amount });\n\n return { status: 200, body: { success: true, wallet } };\n } catch (err) {\n const message = err instanceof Error ? err.message : 'Failed to add funds';\n return { status: 500, body: { error: message } };\n }\n}\n","import { createServer, type IncomingMessage, type ServerResponse } from 'node:http';\nimport { getDashboardHtml } from './html.js';\nimport { handleGetStatus, handlePostSetup, handlePostFund } from './routes.js';\n\nconst MAX_BODY = 1_048_576; // 1 MB\n\nfunction parseBody(req: IncomingMessage): Promise<Record<string, unknown>> {\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = [];\n let size = 0;\n req.on('data', (chunk: Buffer) => {\n size += chunk.length;\n if (size > MAX_BODY) {\n req.destroy();\n reject(new Error('Request body too large'));\n return;\n }\n chunks.push(chunk);\n });\n req.on('end', () => {\n try {\n const text = Buffer.concat(chunks).toString('utf8');\n resolve(text ? JSON.parse(text) : {});\n } catch {\n reject(new Error('Invalid JSON'));\n }\n });\n req.on('error', reject);\n });\n}\n\nfunction sendJson(res: ServerResponse, status: number, body: Record<string, unknown>): void {\n const json = JSON.stringify(body);\n res.writeHead(status, {\n 'Content-Type': 'application/json',\n 'Content-Length': Buffer.byteLength(json),\n });\n res.end(json);\n}\n\nfunction sendHtml(res: ServerResponse, html: string): void {\n res.writeHead(200, {\n 'Content-Type': 'text/html; charset=utf-8',\n 'Content-Length': Buffer.byteLength(html),\n });\n res.end(html);\n}\n\nexport function startServer(port: number): Promise<ReturnType<typeof createServer>> {\n return new Promise((resolve, reject) => {\n const server = createServer(async (req, res) => {\n const url = req.url ?? '/';\n const method = req.method ?? 'GET';\n\n try {\n if (method === 'GET' && url === '/api/status') {\n const result = handleGetStatus();\n sendJson(res, result.status, result.body);\n } else if (method === 'POST' && url === '/api/setup') {\n const body = await parseBody(req);\n const result = handlePostSetup(body as unknown as Parameters<typeof handlePostSetup>[0]);\n sendJson(res, result.status, result.body);\n } else if (method === 'POST' && url === '/api/fund') {\n const body = await parseBody(req);\n const result = handlePostFund(body as unknown as Parameters<typeof handlePostFund>[0]);\n sendJson(res, result.status, result.body);\n } else if (method === 'GET' && (url === '/' || url === '/index.html')) {\n sendHtml(res, getDashboardHtml());\n } else {\n sendJson(res, 404, { error: 'Not found' });\n }\n } catch (err) {\n const message = err instanceof Error ? err.message : 'Internal error';\n sendJson(res, 500, { error: message });\n }\n });\n\n server.on('error', (err: NodeJS.ErrnoException) => {\n if (err.code === 'EADDRINUSE') {\n reject(new Error(`Port ${port} is already in use. Try a different port with --port <number>.`));\n } else {\n reject(err);\n }\n });\n\n server.listen(port, '127.0.0.1', () => {\n resolve(server);\n });\n });\n}\n","import { startServer } from '../server/index.js';\nimport { openBrowser } from '../utils/open-browser.js';\n\nexport async function dashboardCommand(options: { port: string }): Promise<void> {\n const port = parseInt(options.port, 10) || 3141;\n const url = `http://127.0.0.1:${port}`;\n\n try {\n const server = await startServer(port);\n\n console.log(`AgentPay Dashboard running at ${url}`);\n console.log('Press Ctrl+C to stop.\\n');\n\n openBrowser(url);\n\n const shutdown = () => {\n console.log('\\nShutting down dashboard...');\n server.close(() => process.exit(0));\n // Force exit after 3 seconds if connections linger\n setTimeout(() => process.exit(0), 3000);\n };\n\n process.on('SIGINT', shutdown);\n process.on('SIGTERM', shutdown);\n } catch (err) {\n const message = err instanceof Error ? err.message : 'Failed to start server';\n console.error(message);\n process.exit(1);\n }\n}\n","export async function mcpCommand(options: { http?: boolean }) {\n try {\n // @ts-expect-error — optional peer dependency, may not be installed\n const { startServer } = await import('@useagentpay/mcp-server');\n await (startServer as (opts: { http?: boolean }) => Promise<void>)({ http: options.http });\n } catch (err) {\n if (err instanceof Error && 'code' in err && (err as NodeJS.ErrnoException).code === 'ERR_MODULE_NOT_FOUND') {\n console.error('MCP server package not installed.');\n console.error('Run: pnpm add @useagentpay/mcp-server');\n process.exit(1);\n }\n throw err;\n }\n}\n","#!/usr/bin/env node\nimport { Command } from 'commander';\nimport { VERSION } from './index.js';\n\nconst program = new Command();\n\nprogram\n .name('agentpay')\n .description('Local-first payments SDK for AI agents')\n .version(VERSION);\n\nprogram\n .command('setup')\n .description('Set up AgentPay with your billing credentials')\n .action(async () => {\n const { setupCommand } = await import('./commands/setup.js');\n await setupCommand();\n });\n\nprogram\n .command('budget')\n .description('View or configure spending budget')\n .option('--set <amount>', 'Set total budget')\n .option('--limit-per-tx <amount>', 'Set per-transaction limit')\n .action(async (options) => {\n const { budgetCommand } = await import('./commands/budget.js');\n budgetCommand(options);\n });\n\nprogram\n .command('pending')\n .description('List pending purchase proposals')\n .action(async () => {\n const { pendingCommand } = await import('./commands/pending.js');\n pendingCommand();\n });\n\nprogram\n .command('approve <txId>')\n .description('Approve a pending purchase')\n .action(async (txId: string) => {\n const { approveCommand } = await import('./commands/approve.js');\n await approveCommand(txId);\n });\n\nprogram\n .command('reject <txId>')\n .description('Reject a pending purchase')\n .option('--reason <reason>', 'Reason for rejection')\n .action(async (txId: string, options: { reason?: string }) => {\n const { rejectCommand } = await import('./commands/reject.js');\n rejectCommand(txId, options);\n });\n\nprogram\n .command('status')\n .description('Show wallet status and recent transactions')\n .action(async () => {\n const { statusCommand } = await import('./commands/status.js');\n statusCommand();\n });\n\nprogram\n .command('history')\n .description('Show full transaction history')\n .action(async () => {\n const { historyCommand } = await import('./commands/history.js');\n historyCommand();\n });\n\nprogram\n .command('qr')\n .description('Display QR code for web-based setup')\n .option('--budget <amount>', 'Suggested budget amount')\n .option('--message <msg>', 'Message to display on setup page')\n .action(async (options: { budget?: string; message?: string }) => {\n const { qrCommand } = await import('./commands/qr.js');\n await qrCommand(options);\n });\n\nprogram\n .command('reset')\n .description('Delete all AgentPay data')\n .action(async () => {\n const { resetCommand } = await import('./commands/reset.js');\n await resetCommand();\n });\n\nprogram\n .command('buy')\n .description('Propose, approve, and execute a purchase')\n .requiredOption('--merchant <name>', 'Merchant name')\n .requiredOption('--description <desc>', 'Purchase description')\n .requiredOption('--url <url>', 'Product/checkout URL')\n .option('--amount <amount>', 'Purchase amount (auto-detected from page if omitted)')\n .option('--pickup', 'Select in-store pickup')\n .action(async (options: { merchant: string; description: string; url: string; amount?: string; pickup?: boolean }) => {\n const { buyCommand } = await import('./commands/buy.js');\n await buyCommand(options);\n });\n\nprogram\n .command('dashboard')\n .description('Open the AgentPay dashboard in your browser')\n .option('--port <port>', 'Port for dashboard server', '3141')\n .action(async (options: { port: string }) => {\n const { dashboardCommand } = await import('./commands/dashboard.js');\n await dashboardCommand(options);\n });\n\nprogram\n .command('mcp')\n .description('Start AgentPay MCP server (stdio transport)')\n .option('--http', 'Use HTTP transport instead of stdio')\n .action(async (options: { http?: boolean }) => {\n const { mcpCommand } = await import('./commands/mcp.js');\n await mcpCommand(options);\n });\n\nprogram.parse();\n","export const VERSION = '0.1.0';\n\n// Types\nexport type { BillingCredentials, EncryptedVault } from './vault/types.js';\nexport type { KeyPair, PurchaseMandate, TransactionDetails } from './auth/types.js';\nexport type { Wallet } from './budget/types.js';\nexport type { Transaction, TransactionStatus, Receipt, ProposeOptions } from './transactions/types.js';\nexport type { CheckoutResult, ExecutorConfig } from './executor/types.js';\n\n// Errors\nexport {\n NotSetupError,\n DecryptError,\n InsufficientBalanceError,\n ExceedsTxLimitError,\n NotApprovedError,\n InvalidMandateError,\n AlreadyExecutedError,\n CheckoutFailedError,\n TimeoutError,\n} from './errors.js';\n\n// Utilities\nexport { generateTxId } from './utils/ids.js';\nexport { formatCurrency, formatTimestamp, formatTable, formatStatus } from './utils/display.js';\nexport { getHomePath, getCredentialsPath, getKeysPath, getWalletPath, getTransactionsPath, getAuditPath } from './utils/paths.js';\n\n// Vault\nexport { encrypt, decrypt, saveVault, loadVault } from './vault/vault.js';\n\n// Auth\nexport { generateKeyPair, saveKeyPair, loadPublicKey, loadPrivateKey } from './auth/keypair.js';\nexport { createMandate, verifyMandate } from './auth/mandate.js';\n\n// Budget\nexport { BudgetManager } from './budget/budget.js';\n\n// Transactions\nexport { TransactionManager } from './transactions/manager.js';\nexport { waitForApproval } from './transactions/poller.js';\n\n// Audit\nexport { AuditLogger } from './audit/logger.js';\n\n// Executor\nexport { PurchaseExecutor } from './executor/executor.js';\nexport { PLACEHOLDER_MAP, getPlaceholderVariables, credentialsToSwapMap } from './executor/placeholder.js';\n\n// AgentPay\nexport { AgentPay } from './agentpay.js';\nexport type { AgentPayOptions } from './agentpay.js';\n"],"mappings":";;;;;;;;;;;;AACA,OAAO,UAAU;AACjB,SAAS,qBAAqB;AAF9B;AAAA;AAAA;AAAA;AAAA;;;ACAA,IAAa,eAQA,cAQA,0BAWA,qBAWA,kBAQA,qBAQA,sBAQA,qBAQA;AAtEb;AAAA;AAAA;AAAA;AAAO,IAAM,gBAAN,cAA4B,MAAM;AAAA,MAC9B,OAAO;AAAA,MAChB,YAAY,UAAU,iEAAiE;AACrF,cAAM,OAAO;AACb,aAAK,OAAO;AAAA,MACd;AAAA,IACF;AAEO,IAAM,eAAN,cAA2B,MAAM;AAAA,MAC7B,OAAO;AAAA,MAChB,YAAY,UAAU,sEAAsE;AAC1F,cAAM,OAAO;AACb,aAAK,OAAO;AAAA,MACd;AAAA,IACF;AAEO,IAAM,2BAAN,cAAuC,MAAM;AAAA,MACzC,OAAO;AAAA,MAChB,YAAY,QAAiB,SAAkB;AAC7C,cAAM,MAAM,WAAW,UAAa,YAAY,SAC5C,oCAAoC,OAAO,QAAQ,CAAC,CAAC,cAAc,QAAQ,QAAQ,CAAC,CAAC,gBACrF;AACJ,cAAM,GAAG;AACT,aAAK,OAAO;AAAA,MACd;AAAA,IACF;AAEO,IAAM,sBAAN,cAAkC,MAAM;AAAA,MACpC,OAAO;AAAA,MAChB,YAAY,QAAiB,OAAgB;AAC3C,cAAM,MAAM,WAAW,UAAa,UAAU,SAC1C,WAAW,OAAO,QAAQ,CAAC,CAAC,sCAAsC,MAAM,QAAQ,CAAC,CAAC,MAClF;AACJ,cAAM,GAAG;AACT,aAAK,OAAO;AAAA,MACd;AAAA,IACF;AAEO,IAAM,mBAAN,cAA+B,MAAM;AAAA,MACjC,OAAO;AAAA,MAChB,YAAY,MAAe;AACzB,cAAM,OAAO,eAAe,IAAI,4BAA4B,oCAAoC;AAChG,aAAK,OAAO;AAAA,MACd;AAAA,IACF;AAEO,IAAM,sBAAN,cAAkC,MAAM;AAAA,MACpC,OAAO;AAAA,MAChB,YAAY,UAAU,mDAAmD;AACvE,cAAM,OAAO;AACb,aAAK,OAAO;AAAA,MACd;AAAA,IACF;AAEO,IAAM,uBAAN,cAAmC,MAAM;AAAA,MACrC,OAAO;AAAA,MAChB,YAAY,MAAe;AACzB,cAAM,OAAO,eAAe,IAAI,gCAAgC,wCAAwC;AACxG,aAAK,OAAO;AAAA,MACd;AAAA,IACF;AAEO,IAAM,sBAAN,cAAkC,MAAM;AAAA,MACpC,OAAO;AAAA,MAChB,YAAY,UAAU,gCAAgC;AACpD,cAAM,OAAO;AACb,aAAK,OAAO;AAAA,MACd;AAAA,IACF;AAEO,IAAM,eAAN,cAA2B,MAAM;AAAA,MAC7B,OAAO;AAAA,MAChB,YAAY,UAAU,wBAAwB;AAC5C,cAAM,OAAO;AACb,aAAK,OAAO;AAAA,MACd;AAAA,IACF;AAAA;AAAA;;;AC5EA,SAAS,mBAAmB;AAErB,SAAS,eAAuB;AACrC,SAAO,MAAM,YAAY,CAAC,EAAE,SAAS,KAAK,CAAC;AAC7C;AAJA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACEO,SAAS,eAAe,QAAwB;AACrD,SAAO,IAAI,OAAO,QAAQ,CAAC,CAAC;AAC9B;AAEO,SAAS,gBAAgB,KAAqB;AACnD,QAAM,IAAI,IAAI,KAAK,GAAG;AACtB,SAAO,EAAE,eAAe,SAAS;AAAA,IAC/B,OAAO;AAAA,IACP,KAAK;AAAA,IACL,MAAM;AAAA,IACN,QAAQ;AAAA,EACV,CAAC;AACH;AAiBO,SAAS,aAAa,MAMlB;AACT,QAAM,QAAQ;AAAA,IACZ;AAAA,IACA;AAAA,IACA,uBAAuB,eAAe,KAAK,OAAO,CAAC,MAAM,eAAe,KAAK,MAAM,CAAC;AAAA,IACpF,uBAAuB,eAAe,KAAK,UAAU,CAAC;AAAA,IACtD,uBAAuB,KAAK,QAAQ,MAAM;AAAA,EAC5C;AAEA,MAAI,KAAK,OAAO,SAAS,GAAG;AAC1B,UAAM,KAAK,IAAI,SAAS;AACxB,eAAW,MAAM,KAAK,QAAQ;AAC5B,YAAM,SAAS,IAAI,GAAG,MAAM,IAAI,OAAO,EAAE;AACzC,YAAM,KAAK,KAAK,MAAM,IAAI,GAAG,EAAE,KAAK,GAAG,SAAS,OAAO,EAAE,CAAC,IAAI,eAAe,GAAG,MAAM,EAAE,SAAS,CAAC,CAAC,KAAK,GAAG,WAAW,EAAE;AAAA,IAC1H;AAAA,EACF;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;AAvDA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,SAAS,eAAe;AACxB,SAAS,YAAY;AAEd,SAAS,cAAsB;AACpC,SAAO,QAAQ,IAAI,iBAAiB,KAAK,QAAQ,GAAG,WAAW;AACjE;AAEO,SAAS,qBAA6B;AAC3C,SAAO,KAAK,YAAY,GAAG,iBAAiB;AAC9C;AAEO,SAAS,cAAsB;AACpC,SAAO,KAAK,YAAY,GAAG,MAAM;AACnC;AAEO,SAAS,mBAA2B;AACzC,SAAO,KAAK,YAAY,GAAG,YAAY;AACzC;AAEO,SAAS,oBAA4B;AAC1C,SAAO,KAAK,YAAY,GAAG,aAAa;AAC1C;AAEO,SAAS,gBAAwB;AACtC,SAAO,KAAK,YAAY,GAAG,aAAa;AAC1C;AAEO,SAAS,sBAA8B;AAC5C,SAAO,KAAK,YAAY,GAAG,mBAAmB;AAChD;AAEO,SAAS,eAAuB;AACrC,SAAO,KAAK,YAAY,GAAG,WAAW;AACxC;AAjCA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,SAAS,YAAY,eAAAA,cAAa,gBAAgB,wBAAwB;AAC1E,SAAS,cAAc,eAAe,iBAAiB;AACvD,SAAS,eAAe;AAYjB,SAAS,UAAU,YAAoB,MAAsB;AAClE,SAAO,WAAW,YAAY,MAAM,mBAAmB,YAAY,aAAa;AAClF;AAEO,SAAS,QAAQ,aAAiC,YAAoC;AAC3F,QAAM,OAAOA,aAAY,WAAW;AACpC,QAAM,KAAKA,aAAY,SAAS;AAChC,QAAM,MAAM,UAAU,YAAY,IAAI;AAEtC,QAAM,SAAS,eAAe,WAAW,KAAK,EAAE;AAChD,QAAM,YAAY,KAAK,UAAU,WAAW;AAC5C,QAAM,YAAY,OAAO,OAAO,CAAC,OAAO,OAAO,WAAW,MAAM,GAAG,OAAO,MAAM,CAAC,CAAC;AAClF,QAAM,UAAU,OAAO,WAAW;AAElC,SAAO;AAAA,IACL,YAAY,OAAO,OAAO,CAAC,WAAW,OAAO,CAAC,EAAE,SAAS,QAAQ;AAAA,IACjE,MAAM,KAAK,SAAS,QAAQ;AAAA,IAC5B,IAAI,GAAG,SAAS,QAAQ;AAAA,EAC1B;AACF;AAEO,SAAS,QAAQ,OAAuB,YAAwC;AACrF,MAAI;AACF,UAAM,OAAO,OAAO,KAAK,MAAM,MAAM,QAAQ;AAC7C,UAAM,KAAK,OAAO,KAAK,MAAM,IAAI,QAAQ;AACzC,UAAM,OAAO,OAAO,KAAK,MAAM,YAAY,QAAQ;AACnD,UAAM,MAAM,UAAU,YAAY,IAAI;AAEtC,UAAM,UAAU,KAAK,SAAS,KAAK,SAAS,EAAE;AAC9C,UAAM,aAAa,KAAK,SAAS,GAAG,KAAK,SAAS,EAAE;AAEpD,UAAM,WAAW,iBAAiB,WAAW,KAAK,EAAE;AACpD,aAAS,WAAW,OAAO;AAC3B,UAAM,YAAY,OAAO,OAAO,CAAC,SAAS,OAAO,UAAU,GAAG,SAAS,MAAM,CAAC,CAAC;AAE/E,WAAO,KAAK,MAAM,UAAU,SAAS,MAAM,CAAC;AAAA,EAC9C,QAAQ;AACN,UAAM,IAAI,aAAa;AAAA,EACzB;AACF;AAEO,SAAS,UAAU,OAAuBC,OAAqB;AACpE,QAAM,WAAWA,SAAQ,mBAAmB;AAC5C,YAAU,QAAQ,QAAQ,GAAG,EAAE,WAAW,KAAK,CAAC;AAChD,gBAAc,UAAU,KAAK,UAAU,OAAO,MAAM,CAAC,GAAG,EAAE,MAAM,IAAM,CAAC;AACzE;AAEO,SAAS,UAAUA,OAA+B;AACvD,QAAM,WAAWA,SAAQ,mBAAmB;AAC5C,MAAI;AACF,UAAM,OAAO,aAAa,UAAU,MAAM;AAC1C,WAAO,KAAK,MAAM,IAAI;AAAA,EACxB,QAAQ;AACN,UAAM,IAAI,cAAc;AAAA,EAC1B;AACF;AArEA,IAOM,WACA,mBACA,eACA,YACA,aACA;AAZN;AAAA;AAAA;AAAA;AAIA;AACA;AAEA,IAAM,YAAY;AAClB,IAAM,oBAAoB;AAC1B,IAAM,gBAAgB;AACtB,IAAM,aAAa;AACnB,IAAM,cAAc;AACpB,IAAM,YAAY;AAAA;AAAA;;;ACZlB,SAAS,2BAA4C;AACrD,SAAS,gBAAAC,eAAc,iBAAAC,gBAAe,aAAAC,kBAAiB;AACvD,SAAS,WAAAC,gBAAe;AAIjB,SAAS,gBAAgB,YAA6B;AAC3D,QAAM,EAAE,WAAW,WAAW,IAAI,oBAAoB,WAAW;AAAA,IAC/D,mBAAmB,EAAE,MAAM,QAAQ,QAAQ,MAAM;AAAA,IACjD,oBAAoB;AAAA,MAClB,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR;AAAA,IACF;AAAA,EACF,CAAC;AAED,SAAO,EAAE,WAAW,WAAW;AACjC;AAEO,SAAS,YAAY,MAAe,YAAqB,aAA4B;AAC1F,QAAM,UAAU,cAAc,iBAAiB;AAC/C,QAAM,WAAW,eAAe,kBAAkB;AAElD,EAAAD,WAAUC,SAAQ,OAAO,GAAG,EAAE,WAAW,KAAK,CAAC;AAC/C,EAAAF,eAAc,SAAS,KAAK,WAAW,EAAE,MAAM,IAAM,CAAC;AACtD,EAAAA,eAAc,UAAU,KAAK,YAAY,EAAE,MAAM,IAAM,CAAC;AAC1D;AAMO,SAAS,eAAeG,OAAuB;AACpD,SAAOJ,cAAaI,SAAQ,kBAAkB,GAAG,MAAM;AACzD;AAnCA;AAAA;AAAA;AAAA;AAIA;AAAA;AAAA;;;ACJA,SAAS,YAAY,kBAAkB,mBAAAC,kBAAiB,MAAM,cAAc;AAI5E,SAAS,uBAAuB,SAAqC;AACnE,QAAM,YAAY,KAAK,UAAU;AAAA,IAC/B,MAAM,QAAQ;AAAA,IACd,UAAU,QAAQ;AAAA,IAClB,QAAQ,QAAQ;AAAA,IAChB,aAAa,QAAQ;AAAA,IACrB,WAAW,QAAQ;AAAA,EACrB,CAAC;AACD,SAAO,WAAW,QAAQ,EAAE,OAAO,SAAS,EAAE,OAAO,KAAK;AAC5D;AAEO,SAAS,cACd,WACA,eACA,YACiB;AACjB,QAAM,SAAS,uBAAuB,SAAS;AAC/C,QAAM,OAAO,OAAO,KAAK,MAAM;AAE/B,QAAM,aAAa,iBAAiB;AAAA,IAClC,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,MAAM;AAAA,IACN;AAAA,EACF,CAAC;AAED,QAAM,YAAY,KAAK,MAAM,MAAM,UAAU;AAE7C,QAAM,YAAYA,iBAAgB,UAAU;AAC5C,QAAM,eAAe,UAAU,OAAO,EAAE,MAAM,QAAQ,QAAQ,MAAM,CAAC;AAErE,SAAO;AAAA,IACL,MAAM,UAAU;AAAA,IAChB;AAAA,IACA,WAAW,UAAU,SAAS,QAAQ;AAAA,IACtC,WAAW;AAAA,IACX,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,EACpC;AACF;AAEO,SAAS,cAAc,SAA0B,WAAwC;AAC9F,MAAI;AACF,UAAM,SAAS,uBAAuB,SAAS;AAC/C,QAAI,WAAW,QAAQ,OAAQ,QAAO;AAEtC,UAAM,OAAO,OAAO,KAAK,MAAM;AAC/B,UAAM,YAAY,OAAO,KAAK,QAAQ,WAAW,QAAQ;AACzD,UAAM,YAAYA,iBAAgB;AAAA,MAChC,KAAK,QAAQ;AAAA,MACb,QAAQ;AAAA,MACR,MAAM;AAAA,IACR,CAAC;AAED,WAAO,OAAO,MAAM,MAAM,WAAW,SAAS;AAAA,EAChD,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AA7DA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,SAAS,gBAAAC,eAAc,iBAAAC,gBAAe,aAAAC,kBAAiB;AACvD,SAAS,WAAAC,gBAAe;AADxB,IAMa;AANb;AAAA;AAAA;AAAA;AAGA;AACA;AAEO,IAAM,gBAAN,MAAoB;AAAA,MACjB;AAAA,MAER,YAAY,YAAqB;AAC/B,aAAK,aAAa,cAAc,cAAc;AAAA,MAChD;AAAA,MAEA,YAAoB;AAClB,YAAI;AACF,gBAAM,OAAOH,cAAa,KAAK,YAAY,MAAM;AACjD,iBAAO,KAAK,MAAM,IAAI;AAAA,QACxB,QAAQ;AACN,gBAAM,IAAI,cAAc;AAAA,QAC1B;AAAA,MACF;AAAA,MAEQ,WAAW,QAAsB;AACvC,QAAAE,WAAUC,SAAQ,KAAK,UAAU,GAAG,EAAE,WAAW,KAAK,CAAC;AACvD,QAAAF,eAAc,KAAK,YAAY,KAAK,UAAU,QAAQ,MAAM,CAAC,GAAG,EAAE,MAAM,IAAM,CAAC;AAAA,MACjF;AAAA,MAEA,UAAU,QAAsB;AAC9B,YAAI;AACJ,YAAI;AACF,mBAAS,KAAK,UAAU;AAAA,QAC1B,QAAQ;AACN,mBAAS,EAAE,QAAQ,GAAG,SAAS,GAAG,YAAY,GAAG,OAAO,EAAE;AAAA,QAC5D;AACA,eAAO,SAAS;AAChB,eAAO,UAAU,SAAS,OAAO;AACjC,aAAK,WAAW,MAAM;AAAA,MACxB;AAAA,MAEA,cAAc,OAAqB;AACjC,cAAM,SAAS,KAAK,UAAU;AAC9B,eAAO,aAAa;AACpB,aAAK,WAAW,MAAM;AAAA,MACxB;AAAA,MAEA,cAAc,QAAsB;AAClC,cAAM,SAAS,KAAK,UAAU;AAC9B,YAAI,SAAS,OAAO,SAAS;AAC3B,gBAAM,IAAI,yBAAyB,QAAQ,OAAO,OAAO;AAAA,QAC3D;AACA,eAAO,WAAW;AAClB,eAAO,SAAS;AAChB,aAAK,WAAW,MAAM;AAAA,MACxB;AAAA,MAEA,cAAc,QAAsB;AAClC,cAAM,SAAS,KAAK,UAAU;AAC9B,YAAI,SAAS,OAAO,SAAS;AAC3B,gBAAM,IAAI,yBAAyB,QAAQ,OAAO,OAAO;AAAA,QAC3D;AACA,YAAI,OAAO,aAAa,KAAK,SAAS,OAAO,YAAY;AACvD,gBAAM,IAAI,oBAAoB,QAAQ,OAAO,UAAU;AAAA,QACzD;AAAA,MACF;AAAA,MAEA,SAAS,QAAwB;AAC/B,cAAM,SAAS,KAAK,UAAU;AAC9B,eAAO,UAAU;AACjB,eAAO,WAAW;AAClB,aAAK,WAAW,MAAM;AACtB,eAAO;AAAA,MACT;AAAA,MAEA,aAAqF;AACnF,cAAM,SAAS,KAAK,UAAU;AAC9B,eAAO;AAAA,UACL,QAAQ,OAAO;AAAA,UACf,SAAS,OAAO;AAAA,UAChB,YAAY,OAAO;AAAA,UACnB,OAAO,OAAO;AAAA,QAChB;AAAA,MACF;AAAA,MAEA,WAAW,QAAgB,aAAqB,GAAS;AACvD,cAAM,SAAiB,EAAE,QAAQ,SAAS,QAAQ,YAAY,OAAO,EAAE;AACvE,aAAK,WAAW,MAAM;AAAA,MACxB;AAAA,IACF;AAAA;AAAA;;;ACvFA,SAAS,gBAAAG,eAAc,iBAAAC,gBAAe,aAAAC,kBAAiB;AACvD,SAAS,WAAAC,gBAAe;AADxB,IAOa;AAPb;AAAA;AAAA;AAAA;AAIA;AACA;AAEO,IAAM,qBAAN,MAAyB;AAAA,MACtB;AAAA,MAER,YAAY,QAAiB;AAC3B,aAAK,SAAS,UAAU,oBAAoB;AAAA,MAC9C;AAAA,MAEQ,UAAyB;AAC/B,YAAI;AACF,gBAAM,OAAOH,cAAa,KAAK,QAAQ,MAAM;AAC7C,iBAAO,KAAK,MAAM,IAAI;AAAA,QACxB,QAAQ;AACN,iBAAO,CAAC;AAAA,QACV;AAAA,MACF;AAAA,MAEQ,QAAQ,cAAmC;AACjD,QAAAE,WAAUC,SAAQ,KAAK,MAAM,GAAG,EAAE,WAAW,KAAK,CAAC;AACnD,QAAAF,eAAc,KAAK,QAAQ,KAAK,UAAU,cAAc,MAAM,CAAC,GAAG,EAAE,MAAM,IAAM,CAAC;AAAA,MACnF;AAAA,MAEA,QAAQ,SAAsC;AAC5C,cAAM,eAAe,KAAK,QAAQ;AAClC,cAAM,KAAkB;AAAA,UACtB,IAAI,aAAa;AAAA,UACjB,QAAQ;AAAA,UACR,UAAU,QAAQ;AAAA,UAClB,QAAQ,QAAQ;AAAA,UAChB,aAAa,QAAQ;AAAA,UACrB,KAAK,QAAQ;AAAA,UACb,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,QACpC;AACA,qBAAa,KAAK,EAAE;AACpB,aAAK,QAAQ,YAAY;AACzB,eAAO;AAAA,MACT;AAAA,MAEA,IAAI,MAAuC;AACzC,eAAO,KAAK,QAAQ,EAAE,KAAK,CAAC,OAAO,GAAG,OAAO,IAAI;AAAA,MACnD;AAAA,MAEA,QAAQ,MAAc,SAAgC;AACpD,cAAM,eAAe,KAAK,QAAQ;AAClC,cAAM,KAAK,aAAa,KAAK,CAAC,MAAM,EAAE,OAAO,IAAI;AACjD,YAAI,CAAC,GAAI,OAAM,IAAI,MAAM,eAAe,IAAI,aAAa;AACzD,YAAI,GAAG,WAAW,UAAW,OAAM,IAAI,MAAM,kCAAkC,GAAG,MAAM,UAAU;AAClG,WAAG,SAAS;AACZ,WAAG,UAAU;AACb,aAAK,QAAQ,YAAY;AAAA,MAC3B;AAAA,MAEA,OAAO,MAAc,QAAuB;AAC1C,cAAM,eAAe,KAAK,QAAQ;AAClC,cAAM,KAAK,aAAa,KAAK,CAAC,MAAM,EAAE,OAAO,IAAI;AACjD,YAAI,CAAC,GAAI,OAAM,IAAI,MAAM,eAAe,IAAI,aAAa;AACzD,YAAI,GAAG,WAAW,UAAW,OAAM,IAAI,MAAM,iCAAiC,GAAG,MAAM,UAAU;AACjG,WAAG,SAAS;AACZ,WAAG,kBAAkB;AACrB,aAAK,QAAQ,YAAY;AAAA,MAC3B;AAAA,MAEA,cAAc,MAAoB;AAChC,cAAM,eAAe,KAAK,QAAQ;AAClC,cAAM,KAAK,aAAa,KAAK,CAAC,MAAM,EAAE,OAAO,IAAI;AACjD,YAAI,CAAC,GAAI,OAAM,IAAI,MAAM,eAAe,IAAI,aAAa;AACzD,YAAI,GAAG,WAAW,WAAY,OAAM,IAAI,MAAM,kCAAkC,GAAG,MAAM,UAAU;AACnG,WAAG,SAAS;AACZ,aAAK,QAAQ,YAAY;AAAA,MAC3B;AAAA,MAEA,cAAc,MAAc,SAAwB;AAClD,cAAM,eAAe,KAAK,QAAQ;AAClC,cAAM,KAAK,aAAa,KAAK,CAAC,MAAM,EAAE,OAAO,IAAI;AACjD,YAAI,CAAC,GAAI,OAAM,IAAI,MAAM,eAAe,IAAI,aAAa;AACzD,YAAI,GAAG,WAAW,YAAa,OAAM,IAAI,MAAM,mCAAmC,GAAG,MAAM,UAAU;AACrG,WAAG,SAAS;AACZ,WAAG,UAAU;AACb,aAAK,QAAQ,YAAY;AAAA,MAC3B;AAAA,MAEA,WAAW,MAAc,OAAqB;AAC5C,cAAM,eAAe,KAAK,QAAQ;AAClC,cAAM,KAAK,aAAa,KAAK,CAAC,MAAM,EAAE,OAAO,IAAI;AACjD,YAAI,CAAC,GAAI,OAAM,IAAI,MAAM,eAAe,IAAI,aAAa;AACzD,YAAI,GAAG,WAAW,YAAa,OAAM,IAAI,MAAM,+BAA+B,GAAG,MAAM,UAAU;AACjG,WAAG,SAAS;AACZ,WAAG,QAAQ;AACX,aAAK,QAAQ,YAAY;AAAA,MAC3B;AAAA,MAEA,OAAsB;AACpB,eAAO,KAAK,QAAQ;AAAA,MACtB;AAAA,MAEA,aAA4B;AAC1B,eAAO,KAAK,QAAQ,EAAE,OAAO,CAAC,OAAO,GAAG,WAAW,SAAS;AAAA,MAC9D;AAAA,MAEA,aAA4B;AAC1B,eAAO,KAAK,QAAQ,EAAE,OAAO,CAAC,OAAO,GAAG,WAAW,SAAS;AAAA,MAC9D;AAAA,IACF;AAAA;AAAA;;;AC5GA;AAAA;AAAA;AAAA;AASA,eAAsB,gBACpB,MACA,SACA,SAC+D;AAC/D,QAAM,WAAW,SAAS,gBAAgB;AAC1C,QAAM,UAAU,SAAS,WAAW;AACpC,QAAM,WAAW,KAAK,IAAI,IAAI;AAE9B,SAAO,KAAK,IAAI,IAAI,UAAU;AAC5B,UAAM,KAAK,QAAQ,IAAI,IAAI;AAC3B,QAAI,CAAC,GAAI,OAAM,IAAI,MAAM,eAAe,IAAI,aAAa;AAEzD,QAAI,GAAG,WAAW,WAAY,QAAO,EAAE,QAAQ,WAAW;AAC1D,QAAI,GAAG,WAAW,WAAY,QAAO,EAAE,QAAQ,YAAY,QAAQ,GAAG,gBAAgB;AAEtF,UAAM,IAAI,QAAQ,CAACG,aAAY,WAAWA,UAAS,QAAQ,CAAC;AAAA,EAC9D;AAEA,QAAM,IAAI,aAAa,qCAAqC,IAAI,EAAE;AACpE;AA7BA;AAAA;AAAA;AAAA;AAEA;AAAA;AAAA;;;ACFA,SAAS,gBAAgB,gBAAAC,eAAc,aAAAC,kBAAiB;AACxD,SAAS,WAAAC,gBAAe;AADxB,IAIa;AAJb;AAAA;AAAA;AAAA;AAEA;AAEO,IAAM,cAAN,MAAkB;AAAA,MACf;AAAA,MAER,YAAY,SAAkB;AAC5B,aAAK,UAAU,WAAW,aAAa;AAAA,MACzC;AAAA,MAEA,IAAI,QAAgB,SAAwC;AAC1D,cAAM,aAAY,oBAAI,KAAK,GAAE,YAAY;AACzC,cAAM,aAAa,KAAK,UAAU,OAAO;AACzC,cAAM,QAAQ,GAAG,SAAS,IAAK,MAAM,IAAK,UAAU;AAAA;AACpD,QAAAD,WAAUC,SAAQ,KAAK,OAAO,GAAG,EAAE,WAAW,KAAK,CAAC;AACpD,uBAAe,KAAK,SAAS,OAAO,EAAE,MAAM,IAAM,CAAC;AAAA,MACrD;AAAA,MAEA,SAAmB;AACjB,YAAI;AACF,gBAAM,OAAOF,cAAa,KAAK,SAAS,MAAM;AAC9C,iBAAO,KAAK,KAAK,EAAE,MAAM,IAAI,EAAE,OAAO,OAAO;AAAA,QAC/C,QAAQ;AACN,iBAAO,CAAC;AAAA,QACV;AAAA,MACF;AAAA,IACF;AAAA;AAAA;;;ACNO,SAAS,0BAAkD;AAGhE,SAAO;AAAA,IACL,aAAa;AAAA,IACb,iBAAiB;AAAA,IACjB,aAAa;AAAA,IACb,UAAU;AAAA,IACV,gBAAgB;AAAA,IAChB,cAAc;AAAA,IACd,eAAe;AAAA,IACf,aAAa;AAAA,IACb,iBAAiB;AAAA,IACjB,iBAAiB;AAAA,IACjB,eAAe;AAAA,IACf,gBAAgB;AAAA,IAChB,cAAc;AAAA,IACd,kBAAkB;AAAA,IAClB,OAAO;AAAA,IACP,OAAO;AAAA,EACT;AACF;AAEO,SAAS,qBAAqB,OAAmD;AACtF,SAAO;AAAA,IACL,CAAC,gBAAgB,WAAW,GAAG,MAAM,KAAK;AAAA,IAC1C,CAAC,gBAAgB,eAAe,GAAG,MAAM;AAAA,IACzC,CAAC,gBAAgB,WAAW,GAAG,MAAM,KAAK;AAAA,IAC1C,CAAC,gBAAgB,QAAQ,GAAG,MAAM,KAAK;AAAA,IACvC,CAAC,gBAAgB,cAAc,GAAG,MAAM,eAAe;AAAA,IACvD,CAAC,gBAAgB,YAAY,GAAG,MAAM,eAAe;AAAA,IACrD,CAAC,gBAAgB,aAAa,GAAG,MAAM,eAAe;AAAA,IACtD,CAAC,gBAAgB,WAAW,GAAG,MAAM,eAAe;AAAA,IACpD,CAAC,gBAAgB,eAAe,GAAG,MAAM,eAAe;AAAA,IACxD,CAAC,gBAAgB,eAAe,GAAG,MAAM,gBAAgB;AAAA,IACzD,CAAC,gBAAgB,aAAa,GAAG,MAAM,gBAAgB;AAAA,IACvD,CAAC,gBAAgB,cAAc,GAAG,MAAM,gBAAgB;AAAA,IACxD,CAAC,gBAAgB,YAAY,GAAG,MAAM,gBAAgB;AAAA,IACtD,CAAC,gBAAgB,gBAAgB,GAAG,MAAM,gBAAgB;AAAA,IAC1D,CAAC,gBAAgB,KAAK,GAAG,MAAM;AAAA,IAC/B,CAAC,gBAAgB,KAAK,GAAG,MAAM;AAAA,EACjC;AACF;AA/DA,IAEa;AAFb;AAAA;AAAA;AAAA;AAEO,IAAM,kBAAkB;AAAA,MAC7B,aAAa;AAAA,MACb,iBAAiB;AAAA,MACjB,aAAa;AAAA,MACb,UAAU;AAAA,MACV,gBAAgB;AAAA,MAChB,cAAc;AAAA,MACd,eAAe;AAAA,MACf,aAAa;AAAA,MACb,iBAAiB;AAAA,MACjB,iBAAiB;AAAA,MACjB,eAAe;AAAA,MACf,gBAAgB;AAAA,MAChB,cAAc;AAAA,MACd,kBAAkB;AAAA,MAClB,OAAO;AAAA,MACP,OAAO;AAAA,IACT;AAAA;AAAA;;;ACnBA,SAAS,iBAAiB;AAA1B,IAYa;AAZb;AAAA;AAAA;AAAA;AAIA;AACA;AAOO,IAAM,mBAAN,MAAuB;AAAA,MACpB;AAAA,MACA,YAA8B;AAAA,MAEtC,YAAY,QAAyB;AACnC,aAAK,SAAS;AAAA,UACZ,mBAAmB,QAAQ,qBAAqB,QAAQ,IAAI;AAAA,UAC5D,sBAAsB,QAAQ,wBAAwB,QAAQ,IAAI;AAAA,UAClE,aAAa,QAAQ,eAAe,QAAQ,IAAI;AAAA,QAClD;AAAA,MACF;AAAA,MAEQ,kBAA6B;AACnC,eAAO,IAAI,UAAU;AAAA,UACnB,KAAK;AAAA,UACL,QAAQ,KAAK,OAAO;AAAA,UACpB,WAAW,KAAK,OAAO;AAAA,UACvB,OAAO,KAAK,OAAO,cACf,EAAE,WAAW,4BAA4B,QAAQ,KAAK,OAAO,YAAY,IACzE;AAAA,UACJ,gCAAgC;AAAA,YAC9B,iBAAiB;AAAA,cACf,eAAe;AAAA,YACjB;AAAA,UACF;AAAA,QACF,CAAC;AAAA,MACH;AAAA;AAAA;AAAA;AAAA;AAAA,MAMA,MAAM,gBAAgB,KAAa,cAAgD;AACjF,aAAK,YAAY,KAAK,gBAAgB;AACtC,cAAM,KAAK,UAAU,KAAK;AAC1B,cAAM,OAAO,KAAK,UAAU,QAAQ,WAAW;AAE/C,cAAM,KAAK,KAAK,GAAG;AAGnB,cAAM,wBAAwB,eAC1B,yBAAyB,YAAY,qCACrC;AACJ,cAAM,KAAK,UAAU,IAAI,qBAAqB;AAG9C,cAAM,YAAY,MAAM,KAAK,UAAU;AAAA,UACrC;AAAA,QACF;AAEA,cAAM,QAAQ,WAAW,WAAW,SAAS,WAAW,YAAY,SAAS,GAAG;AAChF,cAAM,cAAc,WAAW,eAAe,WAAW,YAAY,eAAe;AAEpF,eAAO,EAAE,OAAO,YAAY;AAAA,MAC9B;AAAA;AAAA;AAAA;AAAA;AAAA,MAMA,MAAM,gBAAgB,aAA0D;AAC9E,YAAI,CAAC,KAAK,WAAW;AACnB,gBAAM,IAAI,oBAAoB,kDAAkD;AAAA,QAClF;AAEA,YAAI;AAEF,gBAAM,KAAK,UAAU,IAAI,oCAAoC;AAG7D,gBAAM,YAAY,wBAAwB;AAC1C,gBAAM,KAAK,UAAU;AAAA,YACnB;AAAA,kBACU,UAAU,eAAe;AAAA,yBAClB,UAAU,WAAW;AAAA,oBAC1B,UAAU,WAAW;AAAA,iBACxB,UAAU,QAAQ;AAAA,mBAChB,UAAU,KAAK;AAAA,mBACf,UAAU,KAAK;AAAA,4BACN,UAAU,cAAc;AAAA,0BAC1B,UAAU,YAAY;AAAA,2BACrB,UAAU,aAAa;AAAA,yBACzB,UAAU,WAAW;AAAA,6BACjB,UAAU,eAAe;AAAA,6BACzB,UAAU,eAAe;AAAA,2BAC3B,UAAU,aAAa;AAAA,4BACtB,UAAU,cAAc;AAAA,0BAC1B,UAAU,YAAY;AAAA,8BAClB,UAAU,gBAAgB;AAAA,YAChD,EAAE,UAAU;AAAA,UACd;AAGA,gBAAM,UAAU,qBAAqB,WAAW;AAChD,gBAAM,OAAO,KAAK,UAAU,QAAQ,WAAW;AAE/C,gBAAM,KAAK,SAAS,CAAC,QAAgC;AACnD,kBAAM,SAAS,SAAS,iBAAiB,yBAAyB;AAClE,uBAAW,SAAS,QAAQ;AAC1B,oBAAM,KAAK;AACX,yBAAW,CAAC,aAAa,KAAK,KAAK,OAAO,QAAQ,GAAG,GAAG;AACtD,oBAAI,GAAG,UAAU,aAAa;AAC5B,qBAAG,QAAQ;AACX,qBAAG,cAAc,IAAI,MAAM,SAAS,EAAE,SAAS,KAAK,CAAC,CAAC;AACtD,qBAAG,cAAc,IAAI,MAAM,UAAU,EAAE,SAAS,KAAK,CAAC,CAAC;AAAA,gBACzD;AAAA,cACF;AAAA,YACF;AACA,kBAAM,YAAY,SAAS,cAAc,6CAA6C;AACtF,gBAAI,UAAW,WAAU,MAAM;AAAA,UACjC,GAAG,OAAO;AAGV,gBAAM,KAAK,eAAe,GAAI;AAG9B,gBAAM,SAAS,MAAM,KAAK,UAAU;AAAA,YAClC;AAAA,UACF;AAEA,gBAAM,iBAAkB,QAAgB;AACxC,cAAI,CAAC,kBAAkB,mBAAmB,UAAU,mBAAmB,WAAW;AAChF,kBAAM,IAAI,oBAAoB,+DAA+D;AAAA,UAC/F;AAEA,iBAAO;AAAA,YACL,SAAS;AAAA,YACT;AAAA,UACF;AAAA,QACF,SAAS,KAAK;AACZ,cAAI,eAAe,oBAAqB,OAAM;AAC9C,gBAAM,UAAU,eAAe,QAAQ,IAAI,UAAU;AACrD,gBAAM,IAAI,oBAAoB,OAAO;AAAA,QACvC;AAAA,MACF;AAAA;AAAA;AAAA;AAAA;AAAA,MAMA,MAAM,QAAQ,IAAiB,aAA0D;AACvF,aAAK,YAAY,KAAK,gBAAgB;AAEtC,YAAI;AACF,gBAAM,KAAK,UAAU,KAAK;AAC1B,gBAAM,OAAO,KAAK,UAAU,QAAQ,WAAW;AAE/C,gBAAM,KAAK,KAAK,GAAG,GAAG;AAEtB,gBAAM,YAAY,wBAAwB;AAC1C,gBAAM,KAAK,UAAU;AAAA,YACnB;AAAA,kBACU,UAAU,eAAe;AAAA,yBAClB,UAAU,WAAW;AAAA,oBAC1B,UAAU,WAAW;AAAA,iBACxB,UAAU,QAAQ;AAAA,mBAChB,UAAU,KAAK;AAAA,mBACf,UAAU,KAAK;AAAA,4BACN,UAAU,cAAc;AAAA,0BAC1B,UAAU,YAAY;AAAA,2BACrB,UAAU,aAAa;AAAA,yBACzB,UAAU,WAAW;AAAA,6BACjB,UAAU,eAAe;AAAA,6BACzB,UAAU,eAAe;AAAA,2BAC3B,UAAU,aAAa;AAAA,4BACtB,UAAU,cAAc;AAAA,0BAC1B,UAAU,YAAY;AAAA,8BAClB,UAAU,gBAAgB;AAAA,YAChD,EAAE,UAAU;AAAA,UACd;AAEA,gBAAM,UAAU,qBAAqB,WAAW;AAChD,gBAAM,KAAK,SAAS,CAAC,QAAgC;AACnD,kBAAM,SAAS,SAAS,iBAAiB,yBAAyB;AAClE,uBAAW,SAAS,QAAQ;AAC1B,oBAAM,KAAK;AACX,yBAAW,CAAC,aAAa,KAAK,KAAK,OAAO,QAAQ,GAAG,GAAG;AACtD,oBAAI,GAAG,UAAU,aAAa;AAC5B,qBAAG,QAAQ;AACX,qBAAG,cAAc,IAAI,MAAM,SAAS,EAAE,SAAS,KAAK,CAAC,CAAC;AACtD,qBAAG,cAAc,IAAI,MAAM,UAAU,EAAE,SAAS,KAAK,CAAC,CAAC;AAAA,gBACzD;AAAA,cACF;AAAA,YACF;AACA,kBAAM,YAAY,SAAS,cAAc,6CAA6C;AACtF,gBAAI,UAAW,WAAU,MAAM;AAAA,UACjC,GAAG,OAAO;AAEV,gBAAM,KAAK,eAAe,GAAI;AAE9B,gBAAM,SAAS,MAAM,KAAK,UAAU;AAAA,YAClC;AAAA,UACF;AAEA,gBAAM,iBAAkB,QAAgB;AACxC,cAAI,CAAC,kBAAkB,mBAAmB,UAAU,mBAAmB,WAAW;AAChF,kBAAM,IAAI,oBAAoB,+DAA+D;AAAA,UAC/F;AAEA,iBAAO;AAAA,YACL,SAAS;AAAA,YACT;AAAA,UACF;AAAA,QACF,SAAS,KAAK;AACZ,cAAI,eAAe,oBAAqB,OAAM;AAC9C,gBAAM,UAAU,eAAe,QAAQ,IAAI,UAAU;AACrD,gBAAM,IAAI,oBAAoB,OAAO;AAAA,QACvC,UAAE;AACA,gBAAM,KAAK,MAAM;AAAA,QACnB;AAAA,MACF;AAAA,MAEA,MAAM,QAAuB;AAC3B,YAAI;AACF,cAAI,KAAK,WAAW;AAClB,kBAAM,KAAK,UAAU,MAAM;AAC3B,iBAAK,YAAY;AAAA,UACnB;AAAA,QACF,QAAQ;AAAA,QAER;AAAA,MACF;AAAA,IACF;AAAA;AAAA;;;AC1OA,SAAS,QAAAG,aAAY;AAArB,IAwBa;AAxBb;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAgBO,IAAM,WAAN,MAAe;AAAA,MACJ;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MAER,YAAY,SAA2B;AACrC,aAAK,OAAO,SAAS,QAAQ,YAAY;AACzC,aAAK,aAAa,SAAS;AAC3B,aAAK,gBAAgB,IAAI,cAAcA,MAAK,KAAK,MAAM,aAAa,CAAC;AACrE,aAAK,YAAY,IAAI,mBAAmBA,MAAK,KAAK,MAAM,mBAAmB,CAAC;AAC5E,aAAK,cAAc,IAAI,YAAYA,MAAK,KAAK,MAAM,WAAW,CAAC;AAC/D,aAAK,WAAW,IAAI,iBAAiB,SAAS,QAAQ;AAAA,MACxD;AAAA,MAEA,IAAI,SAAS;AACX,cAAM,KAAK,KAAK;AAChB,eAAO;AAAA,UACL,YAAY,MAAM,GAAG,WAAW;AAAA,UAChC,YAAY,MAAM,KAAK,UAAU,WAAW;AAAA,UAC5C,WAAW,MAAM;AACf,kBAAM,IAAI,GAAG,WAAW;AACxB,mBAAO,EAAE,QAAQ,EAAE,QAAQ,YAAY,EAAE,YAAY,WAAW,EAAE,QAAQ;AAAA,UAC5E;AAAA,UACA,mBAAmB,OAAO,YAA6D;AACrF,kBAAMC,UAAS,MAAM,OAAO,QAAQ;AACpC,kBAAM,SAAS,IAAI,gBAAgB;AACnC,gBAAI,SAAS,gBAAiB,QAAO,IAAI,UAAU,OAAO,QAAQ,eAAe,CAAC;AAClF,gBAAI,SAAS,QAAS,QAAO,IAAI,OAAO,QAAQ,OAAO;AACvD,kBAAM,UAAU,QAAQ,IAAI,oBAAoB;AAChD,kBAAM,MAAM,GAAG,OAAO,SAAS,OAAO,SAAS,IAAI,IAAI,OAAO,SAAS,CAAC,KAAK,EAAE;AAC/E,kBAAM,YAAY,MAAMA,QAAO,UAAU,GAAG;AAC5C,mBAAO,EAAE,KAAK,UAAU;AAAA,UAC1B;AAAA,QACF;AAAA,MACF;AAAA,MAEA,IAAI,eAAe;AACjB,eAAO;AAAA,UACL,SAAS,CAAC,YAAyC;AACjD,iBAAK,cAAc,cAAc,QAAQ,MAAM;AAC/C,kBAAM,KAAK,KAAK,UAAU,QAAQ,OAAO;AACzC,iBAAK,YAAY,IAAI,WAAW,EAAE,MAAM,GAAG,IAAI,UAAU,GAAG,UAAU,QAAQ,GAAG,OAAO,CAAC;AACzF,mBAAO;AAAA,UACT;AAAA,UACA,KAAK,CAAC,SAAiB,KAAK,UAAU,IAAI,IAAI;AAAA,UAC9C,iBAAiB,OAAO,MAAc,YAA0D;AAC9F,kBAAM,EAAE,iBAAAC,iBAAgB,IAAI,MAAM;AAClC,mBAAOA,iBAAgB,MAAM,KAAK,WAAW,OAAO;AAAA,UACtD;AAAA,UACA,SAAS,OAAO,SAAmC;AACjD,kBAAM,KAAK,KAAK,UAAU,IAAI,IAAI;AAClC,gBAAI,CAAC,GAAI,OAAM,IAAI,MAAM,eAAe,IAAI,aAAa;AAGzD,gBAAI,GAAG,WAAW,eAAe,GAAG,WAAW,UAAU;AACvD,oBAAM,IAAI,qBAAqB,IAAI;AAAA,YACrC;AACA,gBAAI,GAAG,WAAW,YAAY;AAC5B,oBAAM,IAAI,iBAAiB,IAAI;AAAA,YACjC;AACA,gBAAI,CAAC,GAAG,SAAS;AACf,oBAAM,IAAI,oBAAoB,2CAA2C;AAAA,YAC3E;AAGA,kBAAM,YAAgC;AAAA,cACpC,MAAM,GAAG;AAAA,cACT,UAAU,GAAG;AAAA,cACb,QAAQ,GAAG;AAAA,cACX,aAAa,GAAG;AAAA,cAChB,WAAW,GAAG;AAAA,YAChB;AACA,gBAAI,CAAC,cAAc,GAAG,SAAS,SAAS,GAAG;AACzC,oBAAM,IAAI,oBAAoB;AAAA,YAChC;AAGA,iBAAK,cAAc,cAAc,GAAG,MAAM;AAG1C,iBAAK,UAAU,cAAc,IAAI;AACjC,iBAAK,YAAY,IAAI,WAAW,EAAE,MAAM,2BAA2B,KAAK,CAAC;AAEzE,gBAAI;AAEF,kBAAI,CAAC,KAAK,YAAY;AACpB,sBAAM,IAAI,MAAM,qEAAqE;AAAA,cACvF;AACA,oBAAM,YAAYF,MAAK,KAAK,MAAM,iBAAiB;AACnD,oBAAM,QAAQ,UAAU,SAAS;AACjC,oBAAM,cAAc,QAAQ,OAAO,KAAK,UAAU;AAGlD,oBAAM,SAAS,MAAM,KAAK,SAAS,QAAQ,IAAI,WAAW;AAG1D,oBAAM,UAAmB;AAAA,gBACvB,IAAI,QAAQ,KAAK,QAAQ,OAAO,EAAE,CAAC;AAAA,gBACnC,UAAU,GAAG;AAAA,gBACb,QAAQ,GAAG;AAAA,gBACX,gBAAgB,OAAO,kBAAkB;AAAA,gBACzC,cAAa,oBAAI,KAAK,GAAE,YAAY;AAAA,cACtC;AAEA,mBAAK,UAAU,cAAc,MAAM,OAAO;AAC1C,mBAAK,cAAc,cAAc,GAAG,MAAM;AAC1C,mBAAK,YAAY,IAAI,YAAY,EAAE,MAAM,gBAAgB,QAAQ,eAAe,CAAC;AAEjF,qBAAO;AAAA,YACT,SAAS,KAAK;AACZ,mBAAK,UAAU,WAAW,MAAM,eAAe,QAAQ,IAAI,UAAU,eAAe;AACpF,mBAAK,YAAY,IAAI,UAAU,EAAE,MAAM,OAAO,eAAe,QAAQ,IAAI,UAAU,UAAU,CAAC;AAC9F,oBAAM;AAAA,YACR;AAAA,UACF;AAAA,UACA,YAAY,CAAC,SAAsC;AACjD,kBAAM,KAAK,KAAK,UAAU,IAAI,IAAI;AAClC,mBAAO,IAAI;AAAA,UACb;AAAA,QACF;AAAA,MACF;AAAA,MAEA,IAAI,QAAQ;AACV,eAAO,EAAE,QAAQ,MAAM,KAAK,YAAY,OAAO,EAAE;AAAA,MACnD;AAAA,MAEA,SAOE;AACA,YAAI;AACF,gBAAM,SAAS,KAAK,cAAc,WAAW;AAC7C,gBAAM,UAAU,KAAK,UAAU,WAAW;AAC1C,gBAAM,SAAS,KAAK,UAAU,KAAK,EAAE,MAAM,EAAE;AAC7C,iBAAO;AAAA,YACL,SAAS,OAAO;AAAA,YAChB,QAAQ,OAAO;AAAA,YACf,YAAY,OAAO;AAAA,YACnB;AAAA,YACA;AAAA,YACA,SAAS;AAAA,UACX;AAAA,QACF,QAAQ;AACN,iBAAO;AAAA,YACL,SAAS;AAAA,YACT,QAAQ;AAAA,YACR,YAAY;AAAA,YACZ,SAAS,CAAC;AAAA,YACV,QAAQ,CAAC;AAAA,YACT,SAAS;AAAA,UACX;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA;AAAA;;;AChLA,SAAS,IAAI,GAAmB;AAC9B,SAAO,EAAE,QAAQ,MAAM,OAAO,EAAE,QAAQ,MAAM,MAAM,EAAE,QAAQ,MAAM,MAAM,EAAE,QAAQ,MAAM,QAAQ;AACpG;AAEA,SAASG,gBAAe,GAAmB;AACzC,SAAO,MAAM,EAAE,QAAQ,CAAC;AAC1B;AAEO,SAAS,kBAAkB,OAAe,SAAqC;AACpF,QAAM,cAAc,SAAS,WAAW,YAAY,wBAAwB;AAC5E,QAAM,cAAc,SAAS,WAAW,YAAY,yBAAyB;AAE7E,MAAI,cAAc;AAClB,MAAI,SAAS;AACX,UAAM,QAAkB,CAAC;AACzB,QAAI,QAAQ,SAAU,OAAM,KAAK,4FAA4F,IAAI,QAAQ,QAAQ,CAAC,eAAe;AACjK,QAAI,QAAQ,WAAW,OAAW,OAAM,KAAK,0FAA0FA,gBAAe,QAAQ,MAAM,CAAC,eAAe;AACpL,QAAI,QAAQ,YAAa,OAAM,KAAK,+FAA+F,IAAI,QAAQ,WAAW,CAAC,eAAe;AAC1K,QAAI,QAAQ,KAAM,OAAM,KAAK,6IAA6I,IAAI,QAAQ,IAAI,CAAC,eAAe;AAC1M,QAAI,MAAM,SAAS,GAAG;AACpB,oBAAc,kCAAkC,MAAM,KAAK,EAAE,CAAC;AAAA,IAChE;AAAA,EACF;AAEA,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,0BAyFiB,IAAI,WAAW,CAAC;AAAA,MACpC,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA,4BAKW,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA,0BAKb,IAAI,WAAW,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,gBAY1B,KAAK,UAAU,KAAK,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,6BA6BR,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,2BAUb,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAYtC;AAnMA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,SAAS,YAAY;AACrB,SAAS,gBAAgB;AAElB,SAAS,YAAY,KAAmB;AAC7C,QAAM,OAAO,SAAS;AACtB,MAAI;AACJ,MAAI,SAAS,SAAU,OAAM,SAAS,GAAG;AAAA,WAChC,SAAS,QAAS,OAAM,aAAa,GAAG;AAAA,MAC5C,OAAM,aAAa,GAAG;AAE3B,OAAK,KAAK,CAAC,QAAQ;AACjB,QAAI,KAAK;AACP,cAAQ,IAAI,QAAQ,GAAG,mBAAmB;AAAA,IAC5C;AAAA,EACF,CAAC;AACH;AAfA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA;AAAA;AAAA;AAAA;AAAA,SAAS,oBAA+D;AACxE,SAAS,eAAAC,oBAAmB;AAQ5B,SAAS,UAAU,KAAwD;AACzE,SAAO,IAAI,QAAQ,CAACC,UAAS,WAAW;AACtC,UAAM,SAAmB,CAAC;AAC1B,QAAI,OAAO;AACX,QAAI,GAAG,QAAQ,CAAC,UAAkB;AAChC,cAAQ,MAAM;AACd,UAAI,OAAO,UAAU;AACnB,YAAI,QAAQ;AACZ,eAAO,IAAI,MAAM,wBAAwB,CAAC;AAC1C;AAAA,MACF;AACA,aAAO,KAAK,KAAK;AAAA,IACnB,CAAC;AACD,QAAI,GAAG,OAAO,MAAM;AAClB,UAAI;AACF,cAAM,OAAO,OAAO,OAAO,MAAM,EAAE,SAAS,MAAM;AAClD,QAAAA,SAAQ,OAAO,KAAK,MAAM,IAAI,IAAI,CAAC,CAAC;AAAA,MACtC,QAAQ;AACN,eAAO,IAAI,MAAM,cAAc,CAAC;AAAA,MAClC;AAAA,IACF,CAAC;AACD,QAAI,GAAG,SAAS,MAAM;AAAA,EACxB,CAAC;AACH;AAEA,SAAS,SAAS,KAAqB,QAAgB,MAAqC;AAC1F,QAAM,OAAO,KAAK,UAAU,IAAI;AAChC,MAAI,UAAU,QAAQ;AAAA,IACpB,gBAAgB;AAAA,IAChB,kBAAkB,OAAO,WAAW,IAAI;AAAA,EAC1C,CAAC;AACD,MAAI,IAAI,IAAI;AACd;AAEA,SAAS,SAAS,KAAqB,MAAoB;AACzD,MAAI,UAAU,KAAK;AAAA,IACjB,gBAAgB;AAAA,IAChB,kBAAkB,OAAO,WAAW,IAAI;AAAA,EAC1C,CAAC;AACD,MAAI,IAAI,IAAI;AACd;AASO,SAAS,kBAAkB,SAA8C;AAC9E,SAAO,IAAI,QAAQ,CAACA,UAAS,WAAW;AACtC,UAAM,QAAQD,aAAY,EAAE,EAAE,SAAS,KAAK;AAC5C,QAAI,UAAU;AAEd,UAAM,SAAS,aAAa,OAAO,KAAK,QAAQ;AAC9C,YAAM,MAAM,IAAI,IAAI,IAAI,OAAO,KAAK,UAAU,IAAI,QAAQ,IAAI,EAAE;AAChE,YAAM,SAAS,IAAI,UAAU;AAE7B,UAAI;AACF,YAAI,WAAW,SAAS,IAAI,aAAa,eAAe;AACtD,gBAAM,QAAQ,IAAI,aAAa,IAAI,OAAO;AAC1C,cAAI,UAAU,OAAO;AACnB,qBAAS,KAAK,mCAAmC;AACjD;AAAA,UACF;AACA,mBAAS,KAAK,kBAAkB,OAAO,OAAO,CAAC;AAAA,QACjD,WAAW,WAAW,UAAU,IAAI,aAAa,eAAe;AAC9D,gBAAM,OAAO,MAAM,UAAU,GAAG;AAChC,cAAI,KAAK,UAAU,OAAO;AACxB,qBAAS,KAAK,KAAK,EAAE,OAAO,iBAAiB,CAAC;AAC9C;AAAA,UACF;AACA,gBAAM,aAAa,KAAK;AACxB,cAAI,OAAO,eAAe,YAAY,CAAC,YAAY;AACjD,qBAAS,KAAK,KAAK,EAAE,OAAO,0BAA0B,CAAC;AACvD;AAAA,UACF;AACA,mBAAS,KAAK,KAAK,EAAE,IAAI,KAAK,CAAC;AAE/B,cAAI,CAAC,SAAS;AACZ,sBAAU;AACV,oBAAQ;AACR,YAAAC,SAAQ,UAAU;AAAA,UACpB;AAAA,QACF,OAAO;AACL,mBAAS,KAAK,KAAK,EAAE,OAAO,YAAY,CAAC;AAAA,QAC3C;AAAA,MACF,SAAS,KAAK;AACZ,cAAM,UAAU,eAAe,QAAQ,IAAI,UAAU;AACrD,iBAAS,KAAK,KAAK,EAAE,OAAO,QAAQ,CAAC;AAAA,MACvC;AAAA,IACF,CAAC;AAED,UAAM,QAAQ,WAAW,MAAM;AAC7B,UAAI,CAAC,SAAS;AACZ,kBAAU;AACV,gBAAQ;AACR,eAAO,IAAI,aAAa,6CAA6C,CAAC;AAAA,MACxE;AAAA,IACF,GAAG,UAAU;AAEb,aAAS,UAAgB;AACvB,mBAAa,KAAK;AAClB,aAAO,MAAM;AAAA,IACf;AAEA,WAAO,GAAG,SAAS,CAAC,QAAQ;AAC1B,UAAI,CAAC,SAAS;AACZ,kBAAU;AACV,gBAAQ;AACR,eAAO,GAAG;AAAA,MACZ;AAAA,IACF,CAAC;AAGD,WAAO,OAAO,GAAG,aAAa,MAAM;AAClC,YAAM,OAAO,OAAO,QAAQ;AAC5B,UAAI,CAAC,QAAQ,OAAO,SAAS,UAAU;AACrC,YAAI,CAAC,SAAS;AACZ,oBAAU;AACV,kBAAQ;AACR,iBAAO,IAAI,MAAM,uBAAuB,CAAC;AAAA,QAC3C;AACA;AAAA,MACF;AACA,YAAM,MAAM,oBAAoB,KAAK,IAAI,qBAAqB,KAAK;AACnE,cAAQ,IAAI,4CAA4C;AACxD,kBAAY,GAAG;AAAA,IACjB,CAAC;AAAA,EACH,CAAC;AACH;AA3IA,IAMM,YACA;AAPN;AAAA;AAAA;AAAA;AAEA;AACA;AACA;AAEA,IAAM,aAAa,IAAI,KAAK;AAC5B,IAAM,WAAW;AAAA;AAAA;;;ACPjB,SAAS,uBAAuB;AAKhC,SAAS,WAAW;AAClB,SAAO,gBAAgB,EAAE,OAAO,QAAQ,OAAO,QAAQ,QAAQ,OAAO,CAAC;AACzE;AAEO,SAAS,YAAY,UAAmC;AAC7D,SAAO,IAAI,QAAQ,CAACC,aAAY;AAC9B,UAAM,KAAK,SAAS;AACpB,OAAG,SAAS,UAAU,CAAC,WAAW;AAChC,SAAG,MAAM;AACT,MAAAA,SAAQ,OAAO,KAAK,CAAC;AAAA,IACvB,CAAC;AAAA,EACH,CAAC;AACH;AAEA,eAAsB,iBAAiB,SAAS,gBAAiC;AAE/E,SAAO,YAAY,MAAM;AAC3B;AAEO,SAAS,cAAc,UAAoC;AAChE,SAAO,IAAI,QAAQ,CAACA,aAAY;AAC9B,UAAM,KAAK,SAAS;AACpB,OAAG,SAAS,GAAG,QAAQ,YAAY,CAAC,WAAW;AAC7C,SAAG,MAAM;AACT,MAAAA,SAAQ,OAAO,KAAK,EAAE,YAAY,MAAM,OAAO,OAAO,KAAK,EAAE,YAAY,MAAM,KAAK;AAAA,IACtF,CAAC;AAAA,EACH,CAAC;AACH;AAOA,eAAsB,qBAAqB,SAA8C;AACvF,MAAI,QAAQ,MAAM,OAAO;AACvB,WAAO,iBAAiB,oBAAoB;AAAA,EAC9C;AAEA,QAAM,EAAE,mBAAAC,mBAAkB,IAAI,MAAM;AACpC,SAAOA,mBAAkB,OAAO;AAClC;AA9CA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA;AAAA;AAAA;AAAA;AAAA,SAAS,aAAAC,kBAAiB;AAS1B,eAAsB,eAA8B;AAClD,UAAQ,IAAI,gBAAgB;AAC5B,UAAQ,IAAI,wFAAkB;AAE9B,QAAM,OAAO,YAAY;AACzB,EAAAA,WAAU,MAAM,EAAE,WAAW,KAAK,CAAC;AAGnC,QAAM,aAAa,MAAM,iBAAiB,uBAAuB;AACjE,QAAM,UAAU,MAAM,iBAAiB,sBAAsB;AAC7D,MAAI,eAAe,SAAS;AAC1B,YAAQ,MAAM,2BAA2B;AACzC,YAAQ,KAAK,CAAC;AAAA,EAChB;AAGA,UAAQ,IAAI,uBAAuB;AACnC,UAAQ,IAAI,oHAAqB;AACjC,QAAM,aAAa,MAAM,YAAY,eAAe;AACpD,QAAM,aAAa,MAAM,YAAY,kBAAkB;AACvD,QAAM,UAAU,MAAM,YAAY,OAAO;AAGzC,UAAQ,IAAI,wBAAwB;AACpC,UAAQ,IAAI,0HAAsB;AAClC,QAAM,OAAO,MAAM,YAAY,aAAa;AAC5C,QAAM,QAAQ,MAAM,YAAY,SAAS;AACzC,QAAM,QAAQ,MAAM,YAAY,SAAS;AAGzC,UAAQ,IAAI,mBAAmB;AAC/B,UAAQ,IAAI,4FAAiB;AAC7B,QAAM,gBAAgB,MAAM,YAAY,UAAU;AAClD,QAAM,cAAc,MAAM,YAAY,QAAQ;AAC9C,QAAM,eAAe,MAAM,YAAY,SAAS;AAChD,QAAM,aAAa,MAAM,YAAY,OAAO;AAC5C,QAAM,iBAAiB,MAAM,YAAY,qBAAqB;AAG9D,UAAQ,IAAI,oBAAoB;AAChC,UAAQ,IAAI,kGAAkB;AAC9B,QAAM,gBAAgB,MAAM,YAAY,0BAA0B;AAClE,MAAI,gBAAwB,cAAsB,eAAuB,aAAqB;AAE9F,MAAI,cAAc,YAAY,MAAM,OAAO,cAAc,YAAY,MAAM,OAAO;AAChF,qBAAiB;AACjB,mBAAe;AACf,oBAAgB;AAChB,kBAAc;AACd,sBAAkB;AAAA,EACpB,OAAO;AACL,qBAAiB,MAAM,YAAY,UAAU;AAC7C,mBAAe,MAAM,YAAY,QAAQ;AACzC,oBAAgB,MAAM,YAAY,SAAS;AAC3C,kBAAc,MAAM,YAAY,OAAO;AACvC,sBAAkB,MAAM,YAAY,qBAAqB;AAAA,EAC3D;AAEA,QAAM,cAAkC;AAAA,IACtC,MAAM,EAAE,QAAQ,YAAY,QAAQ,YAAY,KAAK,QAAQ;AAAA,IAC7D;AAAA,IACA,gBAAgB,EAAE,QAAQ,eAAe,MAAM,aAAa,OAAO,cAAc,KAAK,YAAY,SAAS,eAAe;AAAA,IAC1H,iBAAiB,EAAE,QAAQ,gBAAgB,MAAM,cAAc,OAAO,eAAe,KAAK,aAAa,SAAS,gBAAgB;AAAA,IAChI;AAAA,IACA;AAAA,EACF;AAGA,QAAM,QAAQ,QAAQ,aAAa,UAAU;AAC7C,YAAU,OAAO,mBAAmB,CAAC;AACrC,UAAQ,IAAI,oCAAoC;AAGhD,QAAM,OAAO,gBAAgB,UAAU;AACvC,EAAAA,WAAU,YAAY,GAAG,EAAE,WAAW,KAAK,CAAC;AAC5C,cAAY,IAAI;AAChB,UAAQ,IAAI,oBAAoB;AAGhC,QAAM,KAAK,IAAI,cAAc;AAC7B,KAAG,WAAW,GAAG,CAAC;AAClB,UAAQ,IAAI,qBAAqB;AAGjC,QAAM,QAAQ,IAAI,YAAY;AAC9B,QAAM,IAAI,SAAS,EAAE,SAAS,+DAA+D,CAAC;AAE9F,UAAQ,IAAI,+BAA+B;AAC3C,UAAQ,IAAI,2DAA2D;AACvE,UAAQ,IAAI,gEAAgE;AAC9E;AAnGA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;;;ACNA;AAAA;AAAA;AAAA;AAIO,SAAS,cAAc,SAAsD;AAClF,QAAM,KAAK,IAAI,cAAc;AAC7B,QAAM,QAAQ,IAAI,YAAY;AAE9B,MAAI,QAAQ,KAAK;AACf,UAAM,SAAS,WAAW,QAAQ,GAAG;AACrC,QAAI,MAAM,MAAM,KAAK,SAAS,GAAG;AAC/B,cAAQ,MAAM,4CAA4C;AAC1D,cAAQ,KAAK,CAAC;AAAA,IAChB;AACA,OAAG,UAAU,MAAM;AACnB,UAAM,IAAI,cAAc,EAAE,OAAO,CAAC;AAClC,YAAQ,IAAI,iBAAiB,eAAe,MAAM,CAAC,GAAG;AAAA,EACxD;AAEA,MAAI,QAAQ,YAAY;AACtB,UAAM,QAAQ,WAAW,QAAQ,UAAU;AAC3C,QAAI,MAAM,KAAK,KAAK,QAAQ,GAAG;AAC7B,cAAQ,MAAM,2CAA2C;AACzD,cAAQ,KAAK,CAAC;AAAA,IAChB;AACA,OAAG,cAAc,KAAK;AACtB,UAAM,IAAI,aAAa,EAAE,YAAY,MAAM,CAAC;AAC5C,YAAQ,IAAI,gCAAgC,eAAe,KAAK,CAAC,GAAG;AAAA,EACtE;AAEA,MAAI,CAAC,QAAQ,OAAO,CAAC,QAAQ,YAAY;AACvC,UAAM,UAAU,GAAG,WAAW;AAC9B,YAAQ,IAAI,eAAe,eAAe,QAAQ,MAAM,CAAC,EAAE;AAC3D,YAAQ,IAAI,eAAe,eAAe,QAAQ,OAAO,CAAC,EAAE;AAC5D,YAAQ,IAAI,eAAe,eAAe,QAAQ,KAAK,CAAC,EAAE;AAC1D,YAAQ,IAAI,iBAAiB,QAAQ,aAAa,IAAI,eAAe,QAAQ,UAAU,IAAI,MAAM,EAAE;AAAA,EACrG;AACF;AArCA,IAAAC,eAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AAAA;AAAA;;;ACFA;AAAA;AAAA;AAAA;AAGO,SAAS,iBAAuB;AACrC,QAAM,KAAK,IAAI,mBAAmB;AAClC,QAAM,UAAU,GAAG,WAAW;AAE9B,MAAI,QAAQ,WAAW,GAAG;AACxB,YAAQ,IAAI,uBAAuB;AACnC;AAAA,EACF;AAEA,UAAQ,IAAI,oBAAoB;AAChC,UAAQ,IAAI,wGAAmB;AAC/B,UAAQ,IAAI,qDAAqD;AAEjE,aAAW,MAAM,SAAS;AACxB,UAAM,KAAK,GAAG,GAAG,OAAO,EAAE;AAC1B,UAAM,WAAW,GAAG,SAAS,OAAO,EAAE;AACtC,UAAM,SAAS,eAAe,GAAG,MAAM,EAAE,SAAS,CAAC;AACnD,YAAQ,IAAI,GAAG,EAAE,GAAG,QAAQ,GAAG,MAAM,OAAO,GAAG,WAAW,EAAE;AAAA,EAC9D;AAEA,UAAQ,IAAI;AAAA,EAAK,QAAQ,MAAM,oBAAoB,QAAQ,WAAW,IAAI,KAAK,GAAG,8DAA8D;AAClJ;AAxBA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;;;ACDA;AAAA;AAAA;AAAA;AAQA,eAAsB,eAAe,MAA6B;AAChE,QAAM,KAAK,IAAI,mBAAmB;AAClC,QAAM,QAAQ,IAAI,YAAY;AAE9B,QAAM,KAAK,GAAG,IAAI,IAAI;AACtB,MAAI,CAAC,IAAI;AACP,YAAQ,MAAM,eAAe,IAAI,aAAa;AAC9C,YAAQ,KAAK,CAAC;AAAA,EAChB;AACA,MAAI,GAAG,WAAW,WAAW;AAC3B,YAAQ,MAAM,kCAAkC,GAAG,MAAM,UAAU;AACnE,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,UAAQ,IAAI,mBAAmB;AAC/B,UAAQ,IAAI,kBAAkB,GAAG,QAAQ,EAAE;AAC3C,UAAQ,IAAI,kBAAkB,eAAe,GAAG,MAAM,CAAC,EAAE;AACzD,UAAQ,IAAI,kBAAkB,GAAG,WAAW,EAAE;AAC9C,UAAQ,IAAI;AAEZ,QAAM,aAAa,MAAM,qBAAqB;AAAA,IAC5C,QAAQ;AAAA,IACR,UAAU,GAAG;AAAA,IACb,QAAQ,GAAG;AAAA,IACX,aAAa,GAAG;AAAA,IAChB;AAAA,EACF,CAAC;AAED,MAAI;AACF,UAAM,gBAAgB,eAAe;AACrC,UAAM,YAAgC;AAAA,MACpC,MAAM,GAAG;AAAA,MACT,UAAU,GAAG;AAAA,MACb,QAAQ,GAAG;AAAA,MACX,aAAa,GAAG;AAAA,MAChB,WAAW,GAAG;AAAA,IAChB;AAEA,UAAM,UAAU,cAAc,WAAW,eAAe,UAAU;AAClE,OAAG,QAAQ,MAAM,OAAO;AACxB,UAAM,IAAI,WAAW,EAAE,MAAM,eAAe,KAAK,CAAC;AAElD,YAAQ,IAAI;AAAA,wBAA2B,IAAI,8BAA8B;AAAA,EAC3E,SAAS,KAAK;AACZ,YAAQ,MAAM,sBAAsB,eAAe,QAAQ,IAAI,UAAU,eAAe,EAAE;AAC1F,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF;AAvDA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;;;ACLA;AAAA;AAAA;AAAA;AAGO,SAAS,cAAc,MAAc,SAAoC;AAC9E,QAAM,KAAK,IAAI,mBAAmB;AAClC,QAAM,QAAQ,IAAI,YAAY;AAE9B,QAAM,KAAK,GAAG,IAAI,IAAI;AACtB,MAAI,CAAC,IAAI;AACP,YAAQ,MAAM,eAAe,IAAI,aAAa;AAC9C,YAAQ,KAAK,CAAC;AAAA,EAChB;AACA,MAAI,GAAG,WAAW,WAAW;AAC3B,YAAQ,MAAM,iCAAiC,GAAG,MAAM,UAAU;AAClE,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,KAAG,OAAO,MAAM,QAAQ,MAAM;AAC9B,QAAM,IAAI,UAAU,EAAE,MAAM,QAAQ,QAAQ,OAAO,CAAC;AAEpD,UAAQ,IAAI,wBAAwB,IAAI,IAAI,QAAQ,SAAS,YAAY,QAAQ,MAAM,KAAK,EAAE,EAAE;AAClG;AArBA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;;;ACDA;AAAA;AAAA;AAAA;AAGO,SAAS,gBAAsB;AACpC,QAAM,KAAK,IAAI,SAAS;AACxB,QAAM,IAAI,GAAG,OAAO;AAEpB,MAAI,CAAC,EAAE,SAAS;AACd,YAAQ,IAAI,qDAAqD;AACjE;AAAA,EACF;AAEA,UAAQ,IAAI,aAAa;AAAA,IACvB,SAAS,EAAE;AAAA,IACX,QAAQ,EAAE;AAAA,IACV,YAAY,EAAE;AAAA,IACd,SAAS,EAAE;AAAA,IACX,QAAQ,EAAE;AAAA,EACZ,CAAC,CAAC;AACJ;AAnBA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;;;ACDA;AAAA;AAAA;AAAA;AAGO,SAAS,iBAAuB;AACrC,QAAM,KAAK,IAAI,mBAAmB;AAClC,QAAM,UAAU,GAAG,WAAW;AAE9B,MAAI,QAAQ,WAAW,GAAG;AACxB,YAAQ,IAAI,yBAAyB;AACrC;AAAA,EACF;AAEA,UAAQ,IAAI,sBAAsB;AAClC,UAAQ,IAAI,gIAAuB;AACnC,UAAQ,IAAI,oFAAoF;AAEhG,aAAW,MAAM,SAAS;AACxB,UAAM,SAAS,IAAI,GAAG,MAAM,IAAI,OAAO,EAAE;AACzC,UAAM,KAAK,GAAG,GAAG,OAAO,EAAE;AAC1B,UAAM,WAAW,GAAG,SAAS,OAAO,EAAE;AACtC,UAAM,SAAS,eAAe,GAAG,MAAM,EAAE,SAAS,CAAC;AACnD,UAAM,OAAO,gBAAgB,GAAG,SAAS,EAAE,OAAO,EAAE;AACpD,YAAQ,IAAI,GAAG,MAAM,GAAG,EAAE,GAAG,QAAQ,GAAG,MAAM,OAAO,IAAI,GAAG,GAAG,WAAW,EAAE;AAAA,EAC9E;AACF;AAxBA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;;;ACDA;AAAA;AAAA;AAAA;AAAA,OAAO,YAAY;AAEnB,eAAsB,UAAU,SAA+D;AAC7F,QAAM,SAAS,IAAI,gBAAgB;AACnC,MAAI,QAAQ,OAAQ,QAAO,IAAI,UAAU,QAAQ,MAAM;AACvD,MAAI,QAAQ,QAAS,QAAO,IAAI,OAAO,QAAQ,OAAO;AAEtD,QAAM,UAAU,QAAQ,IAAI,oBAAoB;AAChD,QAAM,MAAM,GAAG,OAAO,SAAS,OAAO,SAAS,IAAI,IAAI,OAAO,SAAS,CAAC,KAAK,EAAE;AAE/E,UAAQ,IAAI,yCAAyC;AAErD,QAAM,WAAW,MAAM,OAAO,SAAS,KAAK,EAAE,MAAM,YAAY,OAAO,KAAK,CAAC;AAC7E,UAAQ,IAAI,QAAQ;AACpB,UAAQ,IAAI;AAAA,OAAU,GAAG,EAAE;AAC7B;AAfA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA;AAAA;AAAA;AAAA;AAAA,SAAS,QAAQ,kBAAkB;AAInC,eAAsB,eAA8B;AAClD,QAAM,OAAO,YAAY;AAEzB,MAAI,CAAC,WAAW,IAAI,GAAG;AACrB,YAAQ,IAAI,2DAA2D;AACvE;AAAA,EACF;AAEA,UAAQ,IAAI,sDAAsD,IAAI,EAAE;AACxE,UAAQ,IAAI,kFAAkF;AAC9F,QAAM,SAAS,MAAM,YAAY,yBAAyB;AAE1D,MAAI,WAAW,OAAO;AACpB,YAAQ,IAAI,YAAY;AACxB;AAAA,EACF;AAEA,SAAO,MAAM,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAC7C,UAAQ,IAAI,qCAAqC;AACnD;AAvBA;AAAA;AAAA;AAAA;AACA;AACA;AAAA;AAAA;;;ACFA;AAAA;AAAA;AAAA;AAAA,SAAS,gBAAAC,qBAAoB;AAC7B,SAAS,eAAe;AAaxB,SAAS,UAAgB;AACvB,MAAI;AACF,UAAM,UAAU,QAAQ,QAAQ,IAAI,GAAG,MAAM;AAC7C,UAAM,UAAUA,cAAa,SAAS,MAAM;AAC5C,eAAW,QAAQ,QAAQ,MAAM,IAAI,GAAG;AACtC,YAAM,UAAU,KAAK,KAAK;AAC1B,UAAI,CAAC,WAAW,QAAQ,WAAW,GAAG,EAAG;AACzC,YAAM,QAAQ,QAAQ,QAAQ,GAAG;AACjC,UAAI,UAAU,GAAI;AAClB,YAAM,MAAM,QAAQ,MAAM,GAAG,KAAK,EAAE,KAAK;AACzC,YAAM,QAAQ,QAAQ,MAAM,QAAQ,CAAC,EAAE,KAAK;AAC5C,UAAI,CAAC,QAAQ,IAAI,GAAG,GAAG;AACrB,gBAAQ,IAAI,GAAG,IAAI;AAAA,MACrB;AAAA,IACF;AAAA,EACF,QAAQ;AAAA,EAER;AACF;AAUA,eAAsB,WAAW,SAAoC;AACnE,UAAQ;AAER,UAAQ,IAAI,mBAAmB;AAC/B,UAAQ,IAAI,0GAAqB;AAEjC,QAAM,WAAW,IAAI,iBAAiB;AACtC,QAAM,KAAK,IAAI,cAAc;AAC7B,QAAM,KAAK,IAAI,mBAAmB;AAClC,QAAM,QAAQ,IAAI,YAAY;AAC9B,QAAM,QAAQ,QAAQ,MAAM;AAG5B,MAAI;AACJ,MAAI,cAAsB,QAAQ;AAElC,MAAI,QAAQ,QAAQ;AAElB,aAAS,WAAW,QAAQ,MAAM;AAClC,QAAI,MAAM,MAAM,KAAK,UAAU,GAAG;AAChC,cAAQ,MAAM,iBAAiB;AAC/B,cAAQ,KAAK,CAAC;AAAA,IAChB;AACA,YAAQ,IAAI,kBAAkB,QAAQ,QAAQ,EAAE;AAChD,YAAQ,IAAI,kBAAkB,eAAe,MAAM,CAAC,EAAE;AACtD,YAAQ,IAAI,kBAAkB,QAAQ,WAAW,EAAE;AACnD,YAAQ,IAAI,kBAAkB,QAAQ,GAAG,EAAE;AAC3C,YAAQ,IAAI;AAAA,EACd,OAAO;AAEL,UAAM,aAAa,QAAQ,SAAS,yCAAyC;AAC7E,UAAM,eAAe,CAAC,YAAY,QAAQ,WAAW,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAE/E,YAAQ,IAAI,wCAAwC;AACpD,QAAI;AACF,YAAM,aAAa,MAAM,SAAS,gBAAgB,QAAQ,KAAK,gBAAgB,MAAS;AACxF,eAAS,WAAW;AACpB,oBAAc,WAAW,eAAe,QAAQ;AAAA,IAClD,SAAS,KAAK;AACZ,cAAQ,MAAM,gCAAgC,eAAe,QAAQ,IAAI,UAAU,eAAe,EAAE;AACpG,YAAM,SAAS,MAAM;AACrB,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,QAAI,UAAU,GAAG;AACf,cAAQ,MAAM,wCAAwC;AACtD,YAAM,SAAS,MAAM;AACrB,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,YAAQ,IAAI,kBAAkB,WAAW,EAAE;AAC3C,YAAQ,IAAI,kBAAkB,QAAQ,QAAQ,EAAE;AAChD,YAAQ,IAAI,kBAAkB,eAAe,MAAM,CAAC,EAAE;AACtD,YAAQ,IAAI;AAAA,EACd;AAGA,MAAI;AACF,OAAG,cAAc,MAAM;AAAA,EACzB,SAAS,KAAK;AACZ,YAAQ,MAAM,eAAe,QAAQ,IAAI,UAAU,sBAAsB;AACzE,UAAM,SAAS,MAAM;AACrB,YAAQ,KAAK,CAAC;AAAA,EAChB;AAMA,MAAI;AACJ,MAAI,OAAO;AACT,UAAM,YAAY,MAAM,cAAc,wBAAwB;AAC9D,QAAI,CAAC,WAAW;AACd,cAAQ,IAAI,qBAAqB;AACjC,YAAM,SAAS,MAAM;AACrB,cAAQ,KAAK,CAAC;AAAA,IAChB;AACA,iBAAa,MAAM,qBAAqB;AAAA,EAC1C,OAAO;AACL,iBAAa,MAAM,qBAAqB;AAAA,MACtC,QAAQ;AAAA,MACR,UAAU,QAAQ;AAAA,MAClB;AAAA,MACA,aAAa;AAAA,IACf,CAAC;AACD,YAAQ,IAAI,oCAAoC;AAAA,EAClD;AAGA,QAAM,QAAQ,UAAU,mBAAmB,CAAC;AAC5C,QAAM,cAAc,QAAQ,OAAO,UAAU;AAG7C,UAAQ,IAAI,4BAA4B;AACxC,QAAM,KAAK,GAAG,QAAQ;AAAA,IACpB,UAAU,QAAQ;AAAA,IAClB;AAAA,IACA,aAAa;AAAA,IACb,KAAK,QAAQ;AAAA,EACf,CAAC;AACD,QAAM,IAAI,WAAW,EAAE,MAAM,GAAG,IAAI,UAAU,GAAG,UAAU,QAAQ,GAAG,QAAQ,QAAQ,cAAc,CAAC;AACrG,UAAQ,IAAI,iBAAiB,GAAG,EAAE,WAAW;AAG7C,QAAM,gBAAgB,eAAe;AACrC,QAAM,UAAU;AAAA,IACd,EAAE,MAAM,GAAG,IAAI,UAAU,GAAG,UAAU,QAAQ,GAAG,QAAQ,aAAa,GAAG,aAAa,WAAW,GAAG,UAAU;AAAA,IAC9G;AAAA,IACA;AAAA,EACF;AACA,KAAG,QAAQ,GAAG,IAAI,OAAO;AACzB,QAAM,IAAI,WAAW,EAAE,MAAM,GAAG,IAAI,QAAQ,eAAe,eAAe,KAAK,CAAC;AAChF,UAAQ,IAAI,0BAA0B;AAGtC,UAAQ,IAAI,qBAAqB;AACjC,KAAG,cAAc,GAAG,EAAE;AACtB,QAAM,IAAI,WAAW,EAAE,MAAM,GAAG,IAAI,QAAQ,cAAc,CAAC;AAE3D,MAAI;AACF,QAAI;AACJ,QAAI,CAAC,QAAQ,QAAQ;AAEnB,eAAS,MAAM,SAAS,gBAAgB,WAAW;AAAA,IACrD,OAAO;AAEL,eAAS,MAAM,SAAS,QAAQ,IAAI,WAAW;AAAA,IACjD;AAEA,UAAM,UAAU;AAAA,MACd,IAAI,QAAQ,GAAG,GAAG,QAAQ,OAAO,EAAE,CAAC;AAAA,MACpC,UAAU,GAAG;AAAA,MACb,QAAQ,GAAG;AAAA,MACX,gBAAgB,OAAO,kBAAkB;AAAA,MACzC,cAAa,oBAAI,KAAK,GAAE,YAAY;AAAA,IACtC;AACA,OAAG,cAAc,GAAG,IAAI,OAAO;AAC/B,OAAG,cAAc,GAAG,MAAM;AAC1B,UAAM,IAAI,YAAY,EAAE,MAAM,GAAG,IAAI,gBAAgB,QAAQ,gBAAgB,QAAQ,cAAc,CAAC;AAEpG,YAAQ,IAAI;AAAA,mBAAsB;AAClC,YAAQ,IAAI,mBAAmB,QAAQ,cAAc,EAAE;AACvD,YAAQ,IAAI,mBAAmB,eAAe,QAAQ,MAAM,CAAC,EAAE;AAAA,EACjE,SAAS,KAAK;AACZ,OAAG,WAAW,GAAG,IAAI,eAAe,QAAQ,IAAI,UAAU,eAAe;AACzE,UAAM,IAAI,UAAU,EAAE,MAAM,GAAG,IAAI,OAAO,eAAe,QAAQ,IAAI,UAAU,WAAW,QAAQ,cAAc,CAAC;AACjH,YAAQ,MAAM;AAAA,mBAAsB,eAAe,QAAQ,IAAI,UAAU,eAAe,EAAE;AAC1F,YAAQ,KAAK,CAAC;AAAA,EAChB,UAAE;AACA,UAAM,SAAS,MAAM;AAAA,EACvB;AACF;AAjMA;AAAA;AAAA;AAAA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;;;ACXO,SAAS,mBAA2B;AACzC,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA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","names":["randomBytes","path","readFileSync","writeFileSync","mkdirSync","dirname","path","createPublicKey","readFileSync","writeFileSync","mkdirSync","dirname","readFileSync","writeFileSync","mkdirSync","dirname","resolve","readFileSync","mkdirSync","dirname","join","QRCode","waitForApproval","formatCurrency","randomBytes","resolve","resolve","collectPassphrase","mkdirSync","init_budget","readFileSync","existsSync","mkdirSync","createServer","parseBody","resolve","MAX_BODY","sendJson","sendHtml","startServer","setupCommand","budgetCommand","pendingCommand","approveCommand","rejectCommand","statusCommand","historyCommand","qrCommand","resetCommand","buyCommand","dashboardCommand","mcpCommand"]}