mcp-scraper 0.2.13 → 0.2.15

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.
Files changed (47) hide show
  1. package/README.md +12 -2
  2. package/dist/bin/api-server.cjs +977 -200
  3. package/dist/bin/api-server.cjs.map +1 -1
  4. package/dist/bin/api-server.js +3 -3
  5. package/dist/bin/browser-agent-stdio-server.cjs +1 -1
  6. package/dist/bin/browser-agent-stdio-server.cjs.map +1 -1
  7. package/dist/bin/browser-agent-stdio-server.js +2 -2
  8. package/dist/bin/mcp-scraper-cli.cjs +46 -3
  9. package/dist/bin/mcp-scraper-cli.cjs.map +1 -1
  10. package/dist/bin/mcp-scraper-cli.js +42 -2
  11. package/dist/bin/mcp-scraper-cli.js.map +1 -1
  12. package/dist/bin/mcp-scraper-combined-stdio-server.cjs +135 -5
  13. package/dist/bin/mcp-scraper-combined-stdio-server.cjs.map +1 -1
  14. package/dist/bin/mcp-scraper-combined-stdio-server.js +3 -3
  15. package/dist/bin/mcp-scraper-install.cjs +4 -3
  16. package/dist/bin/mcp-scraper-install.cjs.map +1 -1
  17. package/dist/bin/mcp-scraper-install.js +4 -3
  18. package/dist/bin/mcp-scraper-install.js.map +1 -1
  19. package/dist/bin/mcp-stdio-server.cjs +135 -5
  20. package/dist/bin/mcp-stdio-server.cjs.map +1 -1
  21. package/dist/bin/mcp-stdio-server.js +2 -2
  22. package/dist/chunk-2CQXHSWC.js +7 -0
  23. package/dist/chunk-2CQXHSWC.js.map +1 -0
  24. package/dist/{chunk-ROS67BNV.js → chunk-BSYPATSM.js} +21 -2
  25. package/dist/chunk-BSYPATSM.js.map +1 -0
  26. package/dist/{chunk-AYTOCZBS.js → chunk-F44RBOJ5.js} +6 -3
  27. package/dist/chunk-F44RBOJ5.js.map +1 -0
  28. package/dist/{chunk-DKJ2XCY7.js → chunk-Q4DFONIK.js} +136 -6
  29. package/dist/chunk-Q4DFONIK.js.map +1 -0
  30. package/dist/{chunk-BQTWXY6G.js → chunk-TIPUIEJN.js} +2 -2
  31. package/dist/{chunk-7GCCOT3M.js → chunk-TL7YTFLH.js} +15 -1
  32. package/dist/chunk-TL7YTFLH.js.map +1 -0
  33. package/dist/{db-BVHYI57K.js → db-P5X6UQ3E.js} +2 -2
  34. package/dist/{server-LUNOI26E.js → server-VD2TD3AD.js} +773 -184
  35. package/dist/server-VD2TD3AD.js.map +1 -0
  36. package/dist/{worker-TDJQ6TH3.js → worker-OZSWIS3F.js} +3 -3
  37. package/package.json +1 -1
  38. package/dist/chunk-7GCCOT3M.js.map +0 -1
  39. package/dist/chunk-AYTOCZBS.js.map +0 -1
  40. package/dist/chunk-DKJ2XCY7.js.map +0 -1
  41. package/dist/chunk-RDROUQ4E.js +0 -7
  42. package/dist/chunk-RDROUQ4E.js.map +0 -1
  43. package/dist/chunk-ROS67BNV.js.map +0 -1
  44. package/dist/server-LUNOI26E.js.map +0 -1
  45. /package/dist/{chunk-BQTWXY6G.js.map → chunk-TIPUIEJN.js.map} +0 -0
  46. /package/dist/{db-BVHYI57K.js.map → db-P5X6UQ3E.js.map} +0 -0
  47. /package/dist/{worker-TDJQ6TH3.js.map → worker-OZSWIS3F.js.map} +0 -0
@@ -4,7 +4,7 @@ import {
4
4
  createHarvestAttemptRecorder,
5
5
  harvestProblemResponse,
6
6
  serializeHarvestProblem
7
- } from "./chunk-ROS67BNV.js";
7
+ } from "./chunk-BSYPATSM.js";
8
8
  import {
9
9
  claimPendingJob,
10
10
  completeJob,
@@ -12,7 +12,7 @@ import {
12
12
  debitMc,
13
13
  failJob,
14
14
  listHarvestAttempts
15
- } from "./chunk-7GCCOT3M.js";
15
+ } from "./chunk-TL7YTFLH.js";
16
16
  import {
17
17
  browserServiceApiKey,
18
18
  harvest
@@ -122,4 +122,4 @@ export {
122
122
  startWorker,
123
123
  tickOnce
124
124
  };
125
- //# sourceMappingURL=worker-TDJQ6TH3.js.map
125
+ //# sourceMappingURL=worker-OZSWIS3F.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mcp-scraper",
3
- "version": "0.2.13",
3
+ "version": "0.2.15",
4
4
  "description": "MCP server for MCP Scraper web intelligence tools",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/api/db.ts"],"sourcesContent":["import { createClient, type Client } from '@libsql/client/http'\nimport { createHash, randomBytes, randomUUID, scryptSync, timingSafeEqual } from 'node:crypto'\nimport { z } from 'zod'\n\nconst DB_URL = process.env.TURSO_DATABASE_URL ?? 'file:./paa-api.db'\nconst DB_TOKEN = process.env.TURSO_AUTH_TOKEN\n\nlet _db: Client | null = null\nlet _rateLimitSchemaReady = false\n\nexport function getDb(): Client {\n if (!_db) _db = createClient({ url: DB_URL, authToken: DB_TOKEN })\n return _db\n}\n\nexport async function migrate(): Promise<void> {\n const db = getDb()\n await db.execute(`\n CREATE TABLE IF NOT EXISTS users (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n email TEXT UNIQUE NOT NULL,\n name TEXT,\n api_key TEXT UNIQUE NOT NULL,\n password_hash TEXT,\n created_at TEXT NOT NULL DEFAULT (datetime('now')),\n active INTEGER NOT NULL DEFAULT 1\n )\n `)\n await db.execute(`\n CREATE TABLE IF NOT EXISTS jobs (\n id TEXT PRIMARY KEY,\n user_id INTEGER NOT NULL REFERENCES users(id),\n status TEXT NOT NULL DEFAULT 'pending',\n query TEXT NOT NULL,\n options TEXT NOT NULL,\n callback_url TEXT,\n result TEXT,\n error TEXT,\n created_at TEXT NOT NULL DEFAULT (datetime('now')),\n started_at TEXT,\n completed_at TEXT\n )\n `)\n await db.execute(`CREATE INDEX IF NOT EXISTS jobs_user_id ON jobs(user_id)`)\n await db.execute(`CREATE INDEX IF NOT EXISTS jobs_status ON jobs(status)`)\n await db.execute(`\n CREATE TABLE IF NOT EXISTS harvest_attempts (\n id TEXT PRIMARY KEY,\n job_id TEXT NOT NULL REFERENCES jobs(id),\n user_id INTEGER NOT NULL REFERENCES users(id),\n attempt_number INTEGER NOT NULL,\n max_attempts INTEGER NOT NULL,\n query TEXT NOT NULL,\n location TEXT,\n max_questions INTEGER NOT NULL,\n status TEXT NOT NULL,\n outcome TEXT,\n kernel_session_id TEXT,\n question_count INTEGER,\n duration_ms INTEGER,\n error TEXT,\n will_retry INTEGER,\n kernel_delete_started INTEGER NOT NULL DEFAULT 0,\n kernel_delete_succeeded INTEGER,\n kernel_delete_error TEXT,\n browser_close_succeeded INTEGER,\n browser_close_error TEXT,\n debug_json TEXT,\n created_at TEXT NOT NULL DEFAULT (datetime('now')),\n completed_at TEXT,\n UNIQUE(job_id, attempt_number)\n )\n `)\n await db.execute(`CREATE INDEX IF NOT EXISTS harvest_attempts_job_id ON harvest_attempts(job_id)`)\n await db.execute(`CREATE INDEX IF NOT EXISTS harvest_attempts_user_created_at ON harvest_attempts(user_id, created_at DESC)`)\n try { await db.execute(`ALTER TABLE harvest_attempts ADD COLUMN debug_json TEXT`) } catch {}\n try { await db.execute(`ALTER TABLE users ADD COLUMN password_hash TEXT`) } catch {}\n try { await db.execute(`ALTER TABLE users ADD COLUMN key_active INTEGER NOT NULL DEFAULT 1`) } catch {}\n\n await db.execute(`\n CREATE TABLE IF NOT EXISTS kpo_jobs (\n id TEXT PRIMARY KEY,\n user_id INTEGER NOT NULL REFERENCES users(id),\n status TEXT NOT NULL,\n entity_name TEXT NOT NULL,\n entity_type TEXT NOT NULL,\n url TEXT,\n request TEXT NOT NULL,\n result TEXT,\n error TEXT,\n created_at TEXT NOT NULL DEFAULT (datetime('now')),\n updated_at TEXT NOT NULL DEFAULT (datetime('now'))\n )\n `)\n await db.execute(`\n CREATE TABLE IF NOT EXISTS kpo_phase_log (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n job_id TEXT NOT NULL REFERENCES kpo_jobs(id),\n phase TEXT NOT NULL,\n output TEXT NOT NULL,\n created_at TEXT NOT NULL DEFAULT (datetime('now'))\n )\n `)\n await db.execute(`CREATE INDEX IF NOT EXISTS kpo_jobs_user_id ON kpo_jobs(user_id)`)\n await db.execute(`CREATE INDEX IF NOT EXISTS kpo_jobs_status ON kpo_jobs(status)`)\n await db.execute(`CREATE INDEX IF NOT EXISTS kpo_phase_log_job_id ON kpo_phase_log(job_id)`)\n try { await db.execute(`ALTER TABLE users ADD COLUMN stripe_customer_id TEXT`) } catch {}\n try { await db.execute(`ALTER TABLE users ADD COLUMN balance_mc INTEGER NOT NULL DEFAULT 0`) } catch {}\n try { await db.execute(`ALTER TABLE users ADD COLUMN extra_concurrency_slots INTEGER NOT NULL DEFAULT 0`) } catch {}\n try { await db.execute(`ALTER TABLE users ADD COLUMN concurrency_stripe_sub_id TEXT`) } catch {}\n await db.execute(`\n CREATE TABLE IF NOT EXISTS ledger (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n user_id INTEGER NOT NULL REFERENCES users(id),\n amount_mc INTEGER NOT NULL,\n operation TEXT NOT NULL,\n description TEXT,\n stripe_pi TEXT,\n created_at TEXT NOT NULL DEFAULT (datetime('now'))\n )\n `)\n await db.execute(`CREATE INDEX IF NOT EXISTS ledger_user_id ON ledger(user_id)`)\n await db.execute(`\n CREATE TABLE IF NOT EXISTS free_credit_refreshes (\n user_id INTEGER NOT NULL REFERENCES users(id),\n month TEXT NOT NULL,\n created_at TEXT NOT NULL DEFAULT (datetime('now')),\n PRIMARY KEY (user_id, month)\n )\n `)\n await db.execute(`\n CREATE TABLE IF NOT EXISTS site_audit_jobs (\n id TEXT PRIMARY KEY,\n user_id INTEGER,\n status TEXT DEFAULT 'pending',\n client_domain TEXT,\n session_path TEXT,\n request TEXT,\n result TEXT,\n error TEXT,\n created_at TEXT DEFAULT (datetime('now')),\n updated_at TEXT DEFAULT (datetime('now'))\n )\n `)\n await db.execute(`\n CREATE TABLE IF NOT EXISTS site_audit_phase_log (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n job_id TEXT REFERENCES site_audit_jobs(id),\n phase TEXT,\n completed_at TEXT DEFAULT (datetime('now')),\n output_summary TEXT\n )\n `)\n await db.execute(`CREATE INDEX IF NOT EXISTS site_audit_jobs_user_id ON site_audit_jobs(user_id)`)\n await db.execute(`CREATE INDEX IF NOT EXISTS site_audit_jobs_status ON site_audit_jobs(status)`)\n await db.execute(`CREATE INDEX IF NOT EXISTS site_audit_phase_log_job_id ON site_audit_phase_log(job_id)`)\n await db.execute(`\n CREATE TABLE IF NOT EXISTS password_reset_tokens (\n token TEXT PRIMARY KEY,\n user_id INTEGER NOT NULL REFERENCES users(id),\n expires_at TEXT NOT NULL,\n used INTEGER NOT NULL DEFAULT 0,\n created_at TEXT NOT NULL DEFAULT (datetime('now'))\n )\n `)\n await db.execute(`CREATE INDEX IF NOT EXISTS prt_user_id ON password_reset_tokens(user_id)`)\n await db.execute(`\n CREATE TABLE IF NOT EXISTS rate_limits (\n scope TEXT NOT NULL,\n key_hash TEXT NOT NULL,\n window_start INTEGER NOT NULL,\n count INTEGER NOT NULL DEFAULT 0,\n updated_at TEXT NOT NULL DEFAULT (datetime('now')),\n PRIMARY KEY (scope, key_hash, window_start)\n )\n `)\n await db.execute(`\n CREATE TABLE IF NOT EXISTS request_events (\n id TEXT PRIMARY KEY,\n user_id INTEGER NOT NULL REFERENCES users(id),\n source TEXT NOT NULL,\n status TEXT NOT NULL,\n query TEXT NOT NULL,\n location TEXT,\n result_count INTEGER,\n result TEXT,\n error TEXT,\n created_at TEXT NOT NULL DEFAULT (datetime('now'))\n )\n `)\n await db.execute(`CREATE INDEX IF NOT EXISTS request_events_user_created_at ON request_events(user_id, created_at DESC)`)\n await db.execute(`\n CREATE TABLE IF NOT EXISTS workflow_schedules (\n id TEXT PRIMARY KEY,\n user_id INTEGER NOT NULL REFERENCES users(id),\n workflow_id TEXT NOT NULL,\n name TEXT NOT NULL,\n input_json TEXT NOT NULL,\n cadence TEXT NOT NULL,\n cron_expr TEXT,\n timezone TEXT NOT NULL DEFAULT 'UTC',\n webhook_url TEXT,\n status TEXT NOT NULL DEFAULT 'active',\n next_run_at TEXT,\n last_run_at TEXT,\n created_at TEXT NOT NULL DEFAULT (datetime('now')),\n updated_at TEXT NOT NULL DEFAULT (datetime('now'))\n )\n `)\n await db.execute(`CREATE INDEX IF NOT EXISTS workflow_schedules_user_status ON workflow_schedules(user_id, status, created_at DESC)`)\n await db.execute(`CREATE INDEX IF NOT EXISTS workflow_schedules_due ON workflow_schedules(status, next_run_at)`)\n await db.execute(`\n CREATE TABLE IF NOT EXISTS workflow_runs (\n id TEXT PRIMARY KEY,\n user_id INTEGER NOT NULL REFERENCES users(id),\n schedule_id TEXT,\n workflow_id TEXT NOT NULL,\n input_json TEXT NOT NULL,\n status TEXT NOT NULL DEFAULT 'queued',\n manifest_json TEXT,\n error_message TEXT,\n queued_at TEXT NOT NULL DEFAULT (datetime('now')),\n started_at TEXT,\n completed_at TEXT,\n idempotency_key TEXT\n )\n `)\n await db.execute(`CREATE INDEX IF NOT EXISTS workflow_runs_user_created ON workflow_runs(user_id, queued_at DESC)`)\n await db.execute(`CREATE INDEX IF NOT EXISTS workflow_runs_schedule ON workflow_runs(schedule_id, queued_at DESC)`)\n await db.execute(`CREATE UNIQUE INDEX IF NOT EXISTS workflow_runs_idempotency ON workflow_runs(idempotency_key) WHERE idempotency_key IS NOT NULL`)\n await db.execute(`\n CREATE TABLE IF NOT EXISTS workflow_artifacts (\n id TEXT PRIMARY KEY,\n run_id TEXT NOT NULL REFERENCES workflow_runs(id),\n user_id INTEGER NOT NULL REFERENCES users(id),\n kind TEXT NOT NULL,\n label TEXT NOT NULL,\n path TEXT NOT NULL,\n content_type TEXT NOT NULL,\n bytes INTEGER,\n rows_count INTEGER,\n created_at TEXT NOT NULL DEFAULT (datetime('now'))\n )\n `)\n await db.execute(`CREATE INDEX IF NOT EXISTS workflow_artifacts_run ON workflow_artifacts(run_id)`)\n await db.execute(`\n CREATE TABLE IF NOT EXISTS workflow_webhook_deliveries (\n id TEXT PRIMARY KEY,\n run_id TEXT NOT NULL REFERENCES workflow_runs(id),\n schedule_id TEXT,\n user_id INTEGER NOT NULL REFERENCES users(id),\n webhook_url TEXT NOT NULL,\n status TEXT NOT NULL,\n attempts INTEGER NOT NULL DEFAULT 0,\n last_error TEXT,\n created_at TEXT NOT NULL DEFAULT (datetime('now')),\n delivered_at TEXT\n )\n `)\n await db.execute(`CREATE INDEX IF NOT EXISTS workflow_webhook_deliveries_run ON workflow_webhook_deliveries(run_id)`)\n await db.execute(`\n CREATE TABLE IF NOT EXISTS stripe_events (\n event_id TEXT PRIMARY KEY,\n processed_at TEXT NOT NULL DEFAULT (datetime('now'))\n )\n `)\n}\n\nexport async function recordStripeEvent(eventId: string): Promise<boolean> {\n const res = await getDb().execute({\n sql: 'INSERT OR IGNORE INTO stripe_events (event_id) VALUES (?)',\n args: [eventId],\n })\n return res.rowsAffected > 0\n}\n\nexport async function stripeEventAlreadyProcessed(eventId: string): Promise<boolean> {\n const res = await getDb().execute({\n sql: 'SELECT 1 FROM stripe_events WHERE event_id = ? LIMIT 1',\n args: [eventId],\n })\n return res.rows.length > 0\n}\n\nexport function generateApiKey(): string {\n return 'sk_' + randomBytes(24).toString('hex')\n}\n\nexport interface User {\n id: number\n email: string\n name: string | null\n api_key: string\n key_active: number\n password_hash: string | null\n created_at: string\n active: number\n stripe_customer_id: string | null\n balance_mc: number\n extra_concurrency_slots: number\n concurrency_stripe_sub_id: string | null\n}\n\nexport function hashPassword(password: string): string {\n const salt = randomBytes(16).toString('hex')\n const hash = scryptSync(password, salt, 64)\n return `${salt}:${hash.toString('hex')}`\n}\n\nexport function verifyPassword(password: string, stored: string): boolean {\n const [salt, hash] = stored.split(':')\n const hashBuf = Buffer.from(hash, 'hex')\n const derived = scryptSync(password, salt, 64)\n return timingSafeEqual(hashBuf, derived)\n}\n\nfunction rowToUser(row: Record<string, unknown>): User {\n return {\n id: Number(row.id),\n email: String(row.email),\n name: row.name != null ? String(row.name) : null,\n api_key: String(row.api_key),\n key_active: Number(row.key_active ?? 1),\n password_hash: row.password_hash != null ? String(row.password_hash) : null,\n created_at: String(row.created_at),\n active: Number(row.active),\n stripe_customer_id: row.stripe_customer_id != null ? String(row.stripe_customer_id) : null,\n balance_mc: Number(row.balance_mc ?? 0),\n extra_concurrency_slots: Number(row.extra_concurrency_slots ?? 0),\n concurrency_stripe_sub_id: row.concurrency_stripe_sub_id != null ? String(row.concurrency_stripe_sub_id) : null,\n }\n}\n\nexport async function getUserByEmail(email: string): Promise<User | undefined> {\n const res = await getDb().execute({ sql: 'SELECT * FROM users WHERE email = ? AND active = 1', args: [email] })\n return res.rows[0] ? rowToUser(res.rows[0] as unknown as Record<string, unknown>) : undefined\n}\n\nexport async function getUserByApiKey(api_key: string): Promise<User | undefined> {\n const res = await getDb().execute({ sql: 'SELECT * FROM users WHERE api_key = ? AND active = 1 AND key_active = 1', args: [api_key] })\n return res.rows[0] ? rowToUser(res.rows[0] as unknown as Record<string, unknown>) : undefined\n}\n\nexport async function getUserById(id: number | bigint): Promise<User | undefined> {\n const res = await getDb().execute({ sql: 'SELECT * FROM users WHERE id = ? AND active = 1', args: [id] })\n return res.rows[0] ? rowToUser(res.rows[0] as unknown as Record<string, unknown>) : undefined\n}\n\nexport async function setPassword(id: number | bigint, password: string): Promise<void> {\n await getDb().execute({ sql: 'UPDATE users SET password_hash = ? WHERE id = ?', args: [hashPassword(password), id] })\n}\n\nexport async function getUserStats(userId: number | bigint): Promise<{ total: number; done: number; failed: number; totalQuestions: number; lastUsed: string | null }> {\n const db = getDb()\n const [totR, doneR, failR, tqR, luR] = await Promise.all([\n db.execute({ sql: 'SELECT COUNT(*) as n FROM jobs WHERE user_id = ?', args: [userId] }),\n db.execute({ sql: \"SELECT COUNT(*) as n FROM jobs WHERE user_id = ? AND status = 'done'\", args: [userId] }),\n db.execute({ sql: \"SELECT COUNT(*) as n FROM jobs WHERE user_id = ? AND status = 'failed'\", args: [userId] }),\n db.execute({ sql: \"SELECT COALESCE(SUM(json_extract(result, '$.totalQuestions')), 0) as n FROM jobs WHERE user_id = ? AND status = 'done'\", args: [userId] }),\n db.execute({ sql: 'SELECT MAX(created_at) as t FROM jobs WHERE user_id = ?', args: [userId] }),\n ])\n return {\n total: Number(totR.rows[0]?.n ?? 0),\n done: Number(doneR.rows[0]?.n ?? 0),\n failed: Number(failR.rows[0]?.n ?? 0),\n totalQuestions: Number(tqR.rows[0]?.n ?? 0),\n lastUsed: luR.rows[0]?.t != null ? String(luR.rows[0].t) : null,\n }\n}\n\nexport async function createUser(email: string, name?: string, password?: string, stripeCustomerId?: string): Promise<{ id: number | bigint; email: string; name?: string; api_key: string; password?: string }> {\n const db = getDb()\n const api_key = generateApiKey()\n const plainPassword = password ?? randomBytes(6).toString('hex')\n const password_hash = hashPassword(plainPassword)\n const result = await db.execute({\n sql: 'INSERT INTO users (email, name, api_key, password_hash, stripe_customer_id) VALUES (?, ?, ?, ?, ?)',\n args: [email, name ?? null, api_key, password_hash, stripeCustomerId ?? null],\n })\n return { id: result.lastInsertRowid!, email, name, api_key, password: plainPassword }\n}\n\nexport async function checkRateLimit(\n scope: string,\n key: string,\n limit: number,\n windowSeconds: number,\n): Promise<{ allowed: boolean; count: number; remaining: number; resetSeconds: number }> {\n const nowSeconds = Math.floor(Date.now() / 1000)\n const windowStart = Math.floor(nowSeconds / windowSeconds) * windowSeconds\n const keyHash = createHash('sha256').update(key).digest('hex')\n const db = getDb()\n\n if (!_rateLimitSchemaReady) {\n await db.execute(`\n CREATE TABLE IF NOT EXISTS rate_limits (\n scope TEXT NOT NULL,\n key_hash TEXT NOT NULL,\n window_start INTEGER NOT NULL,\n count INTEGER NOT NULL DEFAULT 0,\n updated_at TEXT NOT NULL DEFAULT (datetime('now')),\n PRIMARY KEY (scope, key_hash, window_start)\n )\n `)\n _rateLimitSchemaReady = true\n }\n\n await db.execute({\n sql: `\n INSERT INTO rate_limits (scope, key_hash, window_start, count)\n VALUES (?, ?, ?, 1)\n ON CONFLICT(scope, key_hash, window_start)\n DO UPDATE SET count = count + 1, updated_at = datetime('now')\n `,\n args: [scope, keyHash, windowStart],\n })\n\n const res = await db.execute({\n sql: 'SELECT count FROM rate_limits WHERE scope = ? AND key_hash = ? AND window_start = ?',\n args: [scope, keyHash, windowStart],\n })\n const count = Number(res.rows[0]?.count ?? 1)\n return {\n allowed: count <= limit,\n count,\n remaining: Math.max(0, limit - count),\n resetSeconds: Math.max(1, windowStart + windowSeconds - nowSeconds),\n }\n}\n\nexport async function createPasswordResetToken(userId: number | bigint): Promise<string> {\n const token = randomBytes(32).toString('hex')\n const tokenHash = createHash('sha256').update(token).digest('hex')\n const expiresAt = new Date(Date.now() + 60 * 60 * 1000).toISOString()\n await getDb().execute({\n sql: 'INSERT INTO password_reset_tokens (token, user_id, expires_at) VALUES (?, ?, ?)',\n args: [tokenHash, userId, expiresAt],\n })\n return token\n}\n\nexport async function consumePasswordResetToken(token: string): Promise<number | null> {\n const db = getDb()\n const tokenHash = createHash('sha256').update(token).digest('hex')\n const res = await db.execute({\n sql: \"SELECT user_id, expires_at, used FROM password_reset_tokens WHERE token = ?\",\n args: [tokenHash],\n })\n const row = res.rows[0]\n if (!row) return null\n if (Number(row.used)) return null\n if (new Date(String(row.expires_at)) < new Date()) return null\n await db.execute({ sql: 'UPDATE password_reset_tokens SET used = 1 WHERE token = ?', args: [tokenHash] })\n return Number(row.user_id)\n}\n\nexport async function rotateApiKey(userId: number | bigint): Promise<string> {\n const newKey = generateApiKey()\n await getDb().execute({ sql: 'UPDATE users SET api_key = ?, key_active = 1 WHERE id = ?', args: [newKey, userId] })\n return newKey\n}\n\nexport async function revokeApiKey(userId: number | bigint): Promise<void> {\n await getDb().execute({ sql: 'UPDATE users SET key_active = 0 WHERE id = ?', args: [userId] })\n}\n\nexport async function listUsers(): Promise<Omit<User, 'api_key'>[]> {\n const res = await getDb().execute('SELECT id, email, name, created_at, active FROM users ORDER BY created_at DESC')\n return res.rows.map(r => rowToUser({ ...r as unknown as Record<string, unknown>, api_key: '', key_active: 1 }))\n}\n\nexport async function deactivateUser(id: number): Promise<void> {\n await getDb().execute({ sql: 'UPDATE users SET active = 0 WHERE id = ?', args: [id] })\n}\n\ninterface RawJob {\n id: string\n user_id: number\n status: string\n query: string\n options: string\n callback_url: string | null\n result: string | null\n error: string | null\n created_at: string\n started_at: string | null\n completed_at: string | null\n}\n\nexport interface Job {\n id: string\n user_id: number\n status: string\n query: string\n options: Record<string, unknown>\n callback_url: string | null\n result: unknown | null\n error: string | null\n created_at: string\n started_at: string | null\n completed_at: string | null\n}\n\nexport interface HarvestAttemptLog {\n id: string\n job_id: string\n user_id: number\n attempt_number: number\n max_attempts: number\n query: string\n location: string | null\n max_questions: number\n status: string\n outcome: string | null\n kernel_session_id: string | null\n question_count: number | null\n duration_ms: number | null\n error: string | null\n will_retry: boolean | null\n kernel_delete_started: boolean\n kernel_delete_succeeded: boolean | null\n kernel_delete_error: string | null\n browser_close_succeeded: boolean | null\n browser_close_error: string | null\n debug: unknown | null\n created_at: string\n completed_at: string | null\n}\n\nexport interface StartHarvestAttemptInput {\n jobId: string\n userId: number | bigint\n attemptNumber: number\n maxAttempts: number\n query: string\n location: string | null\n maxQuestions: number\n startedAt: string\n}\n\nexport interface FinishHarvestAttemptInput {\n jobId: string\n attemptNumber: number\n outcome: string\n kernelSessionId: string | null\n questionCount: number\n durationMs: number\n error: string | null\n willRetry: boolean\n kernelDeleteStarted: boolean\n kernelDeleteSucceeded: boolean | null\n kernelDeleteError: string | null\n browserCloseSucceeded: boolean | null\n browserCloseError: string | null\n debug: unknown | null\n completedAt: string\n}\n\nfunction rowToRawJob(row: Record<string, unknown>): RawJob {\n return {\n id: String(row.id),\n user_id: Number(row.user_id),\n status: String(row.status),\n query: String(row.query),\n options: String(row.options),\n callback_url: row.callback_url != null ? String(row.callback_url) : null,\n result: row.result != null ? String(row.result) : null,\n error: row.error != null ? String(row.error) : null,\n created_at: String(row.created_at),\n started_at: row.started_at != null ? String(row.started_at) : null,\n completed_at: row.completed_at != null ? String(row.completed_at) : null,\n }\n}\n\nfunction nullableBoolean(value: unknown): boolean | null {\n return value == null ? null : Number(value) === 1\n}\n\nfunction parseNullableJson(value: unknown): unknown | null {\n if (value == null) return null\n try {\n return JSON.parse(String(value)) as unknown\n } catch {\n return null\n }\n}\n\nfunction rowToHarvestAttemptLog(row: Record<string, unknown>): HarvestAttemptLog {\n return {\n id: String(row.id),\n job_id: String(row.job_id),\n user_id: Number(row.user_id),\n attempt_number: Number(row.attempt_number),\n max_attempts: Number(row.max_attempts),\n query: String(row.query),\n location: row.location != null ? String(row.location) : null,\n max_questions: Number(row.max_questions),\n status: String(row.status),\n outcome: row.outcome != null ? String(row.outcome) : null,\n kernel_session_id: row.kernel_session_id != null ? String(row.kernel_session_id) : null,\n question_count: row.question_count != null ? Number(row.question_count) : null,\n duration_ms: row.duration_ms != null ? Number(row.duration_ms) : null,\n error: row.error != null ? String(row.error) : null,\n will_retry: nullableBoolean(row.will_retry),\n kernel_delete_started: Number(row.kernel_delete_started ?? 0) === 1,\n kernel_delete_succeeded: nullableBoolean(row.kernel_delete_succeeded),\n kernel_delete_error: row.kernel_delete_error != null ? String(row.kernel_delete_error) : null,\n browser_close_succeeded: nullableBoolean(row.browser_close_succeeded),\n browser_close_error: row.browser_close_error != null ? String(row.browser_close_error) : null,\n debug: parseNullableJson(row.debug_json),\n created_at: String(row.created_at),\n completed_at: row.completed_at != null ? String(row.completed_at) : null,\n }\n}\n\nfunction deserialize(raw: RawJob): Job {\n return {\n ...raw,\n options: JSON.parse(raw.options) as Record<string, unknown>,\n result: raw.result ? JSON.parse(raw.result) : null,\n }\n}\n\nexport async function createJob(userId: number | bigint, query: string, options: object, callbackUrl?: string): Promise<string> {\n const id = randomUUID()\n await getDb().execute({\n sql: 'INSERT INTO jobs (id, user_id, query, options, callback_url) VALUES (?, ?, ?, ?, ?)',\n args: [id, userId, query, JSON.stringify(options), callbackUrl ?? null],\n })\n return id\n}\n\nexport async function createRunningJob(userId: number | bigint, query: string, options: object): Promise<string> {\n const id = randomUUID()\n await getDb().execute({\n sql: `INSERT INTO jobs (id, user_id, query, options, status, started_at) VALUES (?, ?, ?, ?, 'running', datetime('now'))`,\n args: [id, userId, query, JSON.stringify(options)],\n })\n return id\n}\n\nexport async function startHarvestAttempt(input: StartHarvestAttemptInput): Promise<void> {\n await getDb().execute({\n sql: `\n INSERT INTO harvest_attempts (\n id, job_id, user_id, attempt_number, max_attempts, query, location, max_questions, status, created_at\n )\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, 'running', ?)\n ON CONFLICT(job_id, attempt_number) DO UPDATE SET\n status = 'running',\n created_at = excluded.created_at,\n completed_at = NULL,\n outcome = NULL,\n error = NULL,\n debug_json = NULL\n `,\n args: [\n randomUUID(),\n input.jobId,\n input.userId,\n input.attemptNumber,\n input.maxAttempts,\n input.query,\n input.location,\n input.maxQuestions,\n input.startedAt,\n ],\n })\n}\n\nexport async function finishHarvestAttempt(input: FinishHarvestAttemptInput): Promise<void> {\n await getDb().execute({\n sql: `\n UPDATE harvest_attempts SET\n status = 'finished',\n outcome = ?,\n kernel_session_id = ?,\n question_count = ?,\n duration_ms = ?,\n error = ?,\n will_retry = ?,\n kernel_delete_started = ?,\n kernel_delete_succeeded = ?,\n kernel_delete_error = ?,\n browser_close_succeeded = ?,\n browser_close_error = ?,\n debug_json = ?,\n completed_at = ?\n WHERE job_id = ? AND attempt_number = ?\n `,\n args: [\n input.outcome,\n input.kernelSessionId,\n input.questionCount,\n input.durationMs,\n input.error,\n input.willRetry ? 1 : 0,\n input.kernelDeleteStarted ? 1 : 0,\n input.kernelDeleteSucceeded == null ? null : input.kernelDeleteSucceeded ? 1 : 0,\n input.kernelDeleteError,\n input.browserCloseSucceeded == null ? null : input.browserCloseSucceeded ? 1 : 0,\n input.browserCloseError,\n input.debug == null ? null : JSON.stringify(input.debug),\n input.completedAt,\n input.jobId,\n input.attemptNumber,\n ],\n })\n}\n\nexport async function listHarvestAttempts(jobId: string, userId?: number | bigint): Promise<HarvestAttemptLog[]> {\n const res = userId == null\n ? await getDb().execute({\n sql: `SELECT * FROM harvest_attempts WHERE job_id = ? ORDER BY attempt_number ASC`,\n args: [jobId],\n })\n : await getDb().execute({\n sql: `\n SELECT ha.*\n FROM harvest_attempts ha\n INNER JOIN jobs j ON j.id = ha.job_id\n WHERE ha.job_id = ? AND j.user_id = ?\n ORDER BY ha.attempt_number ASC\n `,\n args: [jobId, userId],\n })\n return res.rows.map(r => rowToHarvestAttemptLog(r as unknown as Record<string, unknown>))\n}\n\nexport async function getJob(id: string, userId?: number | bigint): Promise<Job | undefined> {\n const db = getDb()\n const res = userId\n ? await db.execute({ sql: 'SELECT * FROM jobs WHERE id = ? AND user_id = ?', args: [id, userId] })\n : await db.execute({ sql: 'SELECT * FROM jobs WHERE id = ?', args: [id] })\n return res.rows[0] ? deserialize(rowToRawJob(res.rows[0] as unknown as Record<string, unknown>)) : undefined\n}\n\nexport async function listJobs(userId: number | bigint): Promise<Job[]> {\n const res = await getDb().execute({ sql: 'SELECT * FROM jobs WHERE user_id = ? ORDER BY created_at DESC LIMIT 50', args: [userId] })\n return res.rows.map(r => deserialize(rowToRawJob(r as unknown as Record<string, unknown>)))\n}\n\nexport interface RequestEvent {\n id: string\n user_id: number\n source: string\n status: string\n query: string\n location: string | null\n result_count: number | null\n result: unknown | null\n error: string | null\n created_at: string\n}\n\nfunction rowToRequestEvent(row: Record<string, unknown>): RequestEvent {\n const rawResult = row.result != null ? String(row.result) : null\n return {\n id: String(row.id),\n user_id: Number(row.user_id),\n source: String(row.source),\n status: String(row.status),\n query: String(row.query),\n location: row.location != null ? String(row.location) : null,\n result_count: row.result_count != null ? Number(row.result_count) : null,\n result: rawResult ? JSON.parse(rawResult) : null,\n error: row.error != null ? String(row.error) : null,\n created_at: String(row.created_at),\n }\n}\n\nexport async function logRequestEvent(input: {\n userId: number | bigint\n source: string\n status: 'done' | 'failed'\n query: string\n location?: string | null\n resultCount?: number | null\n result?: unknown\n error?: string | null\n}): Promise<string> {\n const id = randomUUID()\n await getDb().execute({\n sql: `\n INSERT INTO request_events (id, user_id, source, status, query, location, result_count, result, error)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)\n `,\n args: [\n id,\n input.userId,\n input.source,\n input.status,\n input.query,\n input.location ?? null,\n input.resultCount ?? null,\n input.result != null ? JSON.stringify(input.result) : null,\n input.error ?? null,\n ],\n })\n return id\n}\n\nexport async function listRequestEvents(userId: number | bigint, limit = 100): Promise<RequestEvent[]> {\n const res = await getDb().execute({\n sql: `\n SELECT id, user_id, source, status, query, location, result_count, result, error, created_at\n FROM request_events\n WHERE user_id = ?\n ORDER BY created_at DESC\n LIMIT ?\n `,\n args: [userId, limit],\n })\n return res.rows.map(r => rowToRequestEvent(r as unknown as Record<string, unknown>))\n}\n\nexport type WorkflowScheduleStatus = 'active' | 'paused' | 'deleted'\nexport type WorkflowCadence = 'daily' | 'weekly' | 'monthly'\nexport type WorkflowRunStatus = 'queued' | 'running' | 'succeeded' | 'partial' | 'failed' | 'cancelled'\n\nexport interface WorkflowScheduleRecord {\n id: string\n user_id: number\n workflow_id: string\n name: string\n input: Record<string, unknown>\n cadence: WorkflowCadence\n cron_expr: string | null\n timezone: string\n webhook_url: string | null\n status: WorkflowScheduleStatus\n next_run_at: string | null\n last_run_at: string | null\n created_at: string\n updated_at: string\n}\n\nexport interface WorkflowRunRecord {\n id: string\n user_id: number\n schedule_id: string | null\n workflow_id: string\n input: Record<string, unknown>\n status: WorkflowRunStatus\n manifest: unknown | null\n error_message: string | null\n queued_at: string\n started_at: string | null\n completed_at: string | null\n idempotency_key: string | null\n}\n\nexport interface WorkflowArtifactRecord {\n id: string\n run_id: string\n user_id: number\n kind: string\n label: string\n path: string\n content_type: string\n bytes: number | null\n rows_count: number | null\n created_at: string\n}\n\nfunction parseJsonRecordValue(value: unknown): Record<string, unknown> {\n if (value == null) return {}\n try {\n const parsed = JSON.parse(String(value)) as unknown\n return parsed && typeof parsed === 'object' && !Array.isArray(parsed) ? parsed as Record<string, unknown> : {}\n } catch {\n return {}\n }\n}\n\nfunction rowToWorkflowSchedule(row: Record<string, unknown>): WorkflowScheduleRecord {\n return {\n id: String(row.id),\n user_id: Number(row.user_id),\n workflow_id: String(row.workflow_id),\n name: String(row.name),\n input: parseJsonRecordValue(row.input_json),\n cadence: String(row.cadence) as WorkflowCadence,\n cron_expr: row.cron_expr != null ? String(row.cron_expr) : null,\n timezone: String(row.timezone ?? 'UTC'),\n webhook_url: row.webhook_url != null ? String(row.webhook_url) : null,\n status: String(row.status) as WorkflowScheduleStatus,\n next_run_at: row.next_run_at != null ? String(row.next_run_at) : null,\n last_run_at: row.last_run_at != null ? String(row.last_run_at) : null,\n created_at: String(row.created_at),\n updated_at: String(row.updated_at),\n }\n}\n\nfunction rowToWorkflowRun(row: Record<string, unknown>): WorkflowRunRecord {\n return {\n id: String(row.id),\n user_id: Number(row.user_id),\n schedule_id: row.schedule_id != null ? String(row.schedule_id) : null,\n workflow_id: String(row.workflow_id),\n input: parseJsonRecordValue(row.input_json),\n status: String(row.status) as WorkflowRunStatus,\n manifest: row.manifest_json != null ? parseNullableJson(row.manifest_json) : null,\n error_message: row.error_message != null ? String(row.error_message) : null,\n queued_at: String(row.queued_at),\n started_at: row.started_at != null ? String(row.started_at) : null,\n completed_at: row.completed_at != null ? String(row.completed_at) : null,\n idempotency_key: row.idempotency_key != null ? String(row.idempotency_key) : null,\n }\n}\n\nfunction rowToWorkflowArtifact(row: Record<string, unknown>): WorkflowArtifactRecord {\n return {\n id: String(row.id),\n run_id: String(row.run_id),\n user_id: Number(row.user_id),\n kind: String(row.kind),\n label: String(row.label),\n path: String(row.path),\n content_type: String(row.content_type),\n bytes: row.bytes != null ? Number(row.bytes) : null,\n rows_count: row.rows_count != null ? Number(row.rows_count) : null,\n created_at: String(row.created_at),\n }\n}\n\nexport async function createWorkflowSchedule(input: {\n userId: number | bigint\n workflowId: string\n name: string\n workflowInput: Record<string, unknown>\n cadence: WorkflowCadence\n timezone?: string\n webhookUrl?: string | null\n nextRunAt?: string | null\n}): Promise<WorkflowScheduleRecord> {\n const id = randomUUID()\n await getDb().execute({\n sql: `\n INSERT INTO workflow_schedules (\n id, user_id, workflow_id, name, input_json, cadence, timezone, webhook_url, next_run_at\n )\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)\n `,\n args: [\n id,\n input.userId,\n input.workflowId,\n input.name,\n JSON.stringify(input.workflowInput),\n input.cadence,\n input.timezone ?? 'UTC',\n input.webhookUrl ?? null,\n input.nextRunAt ?? null,\n ],\n })\n const schedule = await getWorkflowSchedule(id, input.userId)\n if (!schedule) throw new Error('Failed to create workflow schedule')\n return schedule\n}\n\nexport async function getWorkflowSchedule(id: string, userId?: number | bigint): Promise<WorkflowScheduleRecord | null> {\n const res = userId == null\n ? await getDb().execute({ sql: 'SELECT * FROM workflow_schedules WHERE id = ? AND status != ? LIMIT 1', args: [id, 'deleted'] })\n : await getDb().execute({ sql: 'SELECT * FROM workflow_schedules WHERE id = ? AND user_id = ? AND status != ? LIMIT 1', args: [id, userId, 'deleted'] })\n return res.rows[0] ? rowToWorkflowSchedule(res.rows[0] as unknown as Record<string, unknown>) : null\n}\n\nexport async function listWorkflowSchedules(userId: number | bigint): Promise<WorkflowScheduleRecord[]> {\n const res = await getDb().execute({\n sql: `SELECT * FROM workflow_schedules WHERE user_id = ? AND status != 'deleted' ORDER BY created_at DESC LIMIT 100`,\n args: [userId],\n })\n return res.rows.map(r => rowToWorkflowSchedule(r as unknown as Record<string, unknown>))\n}\n\nexport async function patchWorkflowSchedule(input: {\n id: string\n userId: number | bigint\n name?: string\n status?: WorkflowScheduleStatus\n workflowInput?: Record<string, unknown>\n cadence?: WorkflowCadence\n timezone?: string\n webhookUrl?: string | null\n nextRunAt?: string | null\n}): Promise<WorkflowScheduleRecord | null> {\n const sets: string[] = []\n const args: Array<string | number | bigint | null> = []\n if (input.name !== undefined) { sets.push('name = ?'); args.push(input.name) }\n if (input.status !== undefined) { sets.push('status = ?'); args.push(input.status) }\n if (input.workflowInput !== undefined) { sets.push('input_json = ?'); args.push(JSON.stringify(input.workflowInput)) }\n if (input.cadence !== undefined) { sets.push('cadence = ?'); args.push(input.cadence) }\n if (input.timezone !== undefined) { sets.push('timezone = ?'); args.push(input.timezone) }\n if (input.webhookUrl !== undefined) { sets.push('webhook_url = ?'); args.push(input.webhookUrl) }\n if (input.nextRunAt !== undefined) { sets.push('next_run_at = ?'); args.push(input.nextRunAt) }\n if (sets.length === 0) return getWorkflowSchedule(input.id, input.userId)\n sets.push(`updated_at = datetime('now')`)\n await getDb().execute({\n sql: `UPDATE workflow_schedules SET ${sets.join(', ')} WHERE id = ? AND user_id = ? AND status != 'deleted'`,\n args: [...args, input.id, input.userId],\n })\n return getWorkflowSchedule(input.id, input.userId)\n}\n\nexport async function deleteWorkflowSchedule(id: string, userId: number | bigint): Promise<boolean> {\n const res = await getDb().execute({\n sql: `UPDATE workflow_schedules SET status = 'deleted', updated_at = datetime('now') WHERE id = ? AND user_id = ? AND status != 'deleted'`,\n args: [id, userId],\n })\n return res.rowsAffected > 0\n}\n\nexport async function listDueWorkflowSchedules(nowIso: string, limit = 10): Promise<WorkflowScheduleRecord[]> {\n const res = await getDb().execute({\n sql: `\n SELECT * FROM workflow_schedules\n WHERE status = 'active' AND next_run_at IS NOT NULL AND next_run_at <= ?\n ORDER BY next_run_at ASC\n LIMIT ?\n `,\n args: [nowIso, limit],\n })\n return res.rows.map(r => rowToWorkflowSchedule(r as unknown as Record<string, unknown>))\n}\n\nexport async function markWorkflowScheduleRan(id: string, lastRunAt: string, nextRunAt: string | null): Promise<void> {\n await getDb().execute({\n sql: `UPDATE workflow_schedules SET last_run_at = ?, next_run_at = ?, updated_at = datetime('now') WHERE id = ?`,\n args: [lastRunAt, nextRunAt, id],\n })\n}\n\nexport async function createWorkflowRun(input: {\n id?: string\n userId: number | bigint\n workflowId: string\n workflowInput: Record<string, unknown>\n scheduleId?: string | null\n idempotencyKey?: string | null\n}): Promise<WorkflowRunRecord> {\n const id = input.id ?? randomUUID()\n const args = [\n id,\n input.userId,\n input.scheduleId ?? null,\n input.workflowId,\n JSON.stringify(input.workflowInput),\n input.idempotencyKey ?? null,\n ]\n try {\n await getDb().execute({\n sql: `\n INSERT INTO workflow_runs (id, user_id, schedule_id, workflow_id, input_json, idempotency_key)\n VALUES (?, ?, ?, ?, ?, ?)\n `,\n args,\n })\n } catch (err) {\n if (input.idempotencyKey) {\n const existing = await getWorkflowRunByIdempotencyKey(input.idempotencyKey)\n if (existing) return existing\n }\n throw err\n }\n const run = await getWorkflowRun(id, input.userId)\n if (!run) throw new Error('Failed to create workflow run')\n return run\n}\n\nexport async function getWorkflowRun(id: string, userId?: number | bigint): Promise<WorkflowRunRecord | null> {\n const res = userId == null\n ? await getDb().execute({ sql: 'SELECT * FROM workflow_runs WHERE id = ? LIMIT 1', args: [id] })\n : await getDb().execute({ sql: 'SELECT * FROM workflow_runs WHERE id = ? AND user_id = ? LIMIT 1', args: [id, userId] })\n return res.rows[0] ? rowToWorkflowRun(res.rows[0] as unknown as Record<string, unknown>) : null\n}\n\nexport async function getWorkflowRunByIdempotencyKey(idempotencyKey: string): Promise<WorkflowRunRecord | null> {\n const res = await getDb().execute({ sql: 'SELECT * FROM workflow_runs WHERE idempotency_key = ? LIMIT 1', args: [idempotencyKey] })\n return res.rows[0] ? rowToWorkflowRun(res.rows[0] as unknown as Record<string, unknown>) : null\n}\n\nexport async function listWorkflowRuns(userId: number | bigint, limit = 50): Promise<WorkflowRunRecord[]> {\n const res = await getDb().execute({\n sql: 'SELECT * FROM workflow_runs WHERE user_id = ? ORDER BY queued_at DESC LIMIT ?',\n args: [userId, limit],\n })\n return res.rows.map(r => rowToWorkflowRun(r as unknown as Record<string, unknown>))\n}\n\nexport async function markWorkflowRunRunning(id: string): Promise<void> {\n await getDb().execute({\n sql: `UPDATE workflow_runs SET status = 'running', started_at = COALESCE(started_at, datetime('now')) WHERE id = ?`,\n args: [id],\n })\n}\n\nexport async function completeWorkflowRunRecord(id: string, status: Exclude<WorkflowRunStatus, 'queued' | 'running' | 'cancelled'>, manifest: unknown): Promise<void> {\n await getDb().execute({\n sql: `UPDATE workflow_runs SET status = ?, manifest_json = ?, completed_at = datetime('now') WHERE id = ?`,\n args: [status, JSON.stringify(manifest), id],\n })\n}\n\nexport async function failWorkflowRunRecord(id: string, errorMessage: string, manifest?: unknown): Promise<void> {\n await getDb().execute({\n sql: `UPDATE workflow_runs SET status = 'failed', error_message = ?, manifest_json = ?, completed_at = datetime('now') WHERE id = ?`,\n args: [errorMessage, manifest == null ? null : JSON.stringify(manifest), id],\n })\n}\n\nfunction workflowArtifactContentType(kind: string): string {\n if (kind === 'html_report') return 'text/html; charset=utf-8'\n if (kind === 'csv') return 'text/csv; charset=utf-8'\n if (kind === 'json') return 'application/json; charset=utf-8'\n return 'text/plain; charset=utf-8'\n}\n\nexport async function replaceWorkflowArtifacts(runId: string, userId: number | bigint, artifacts: Array<{\n kind: string\n label: string\n path: string\n bytes?: number\n rows?: number\n}>): Promise<WorkflowArtifactRecord[]> {\n const db = getDb()\n await db.execute({ sql: 'DELETE FROM workflow_artifacts WHERE run_id = ? AND user_id = ?', args: [runId, userId] })\n for (const artifact of artifacts) {\n await db.execute({\n sql: `\n INSERT INTO workflow_artifacts (id, run_id, user_id, kind, label, path, content_type, bytes, rows_count)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)\n `,\n args: [\n randomUUID(),\n runId,\n userId,\n artifact.kind,\n artifact.label,\n artifact.path,\n workflowArtifactContentType(artifact.kind),\n artifact.bytes ?? null,\n artifact.rows ?? null,\n ],\n })\n }\n return listWorkflowArtifacts(runId, userId)\n}\n\nexport async function listWorkflowArtifacts(runId: string, userId: number | bigint): Promise<WorkflowArtifactRecord[]> {\n const res = await getDb().execute({\n sql: 'SELECT * FROM workflow_artifacts WHERE run_id = ? AND user_id = ? ORDER BY created_at ASC',\n args: [runId, userId],\n })\n return res.rows.map(r => rowToWorkflowArtifact(r as unknown as Record<string, unknown>))\n}\n\nexport async function getWorkflowArtifact(id: string, userId: number | bigint): Promise<WorkflowArtifactRecord | null> {\n const res = await getDb().execute({\n sql: 'SELECT * FROM workflow_artifacts WHERE id = ? AND user_id = ? LIMIT 1',\n args: [id, userId],\n })\n return res.rows[0] ? rowToWorkflowArtifact(res.rows[0] as unknown as Record<string, unknown>) : null\n}\n\nexport async function recordWorkflowWebhookDelivery(input: {\n runId: string\n scheduleId?: string | null\n userId: number | bigint\n webhookUrl: string\n status: 'delivered' | 'failed'\n attempts: number\n lastError?: string | null\n}): Promise<void> {\n await getDb().execute({\n sql: `\n INSERT INTO workflow_webhook_deliveries (\n id, run_id, schedule_id, user_id, webhook_url, status, attempts, last_error, delivered_at\n )\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)\n `,\n args: [\n randomUUID(),\n input.runId,\n input.scheduleId ?? null,\n input.userId,\n input.webhookUrl,\n input.status,\n input.attempts,\n input.lastError ?? null,\n input.status === 'delivered' ? new Date().toISOString() : null,\n ],\n })\n}\n\nexport async function countActiveUsers(): Promise<number> {\n const res = await getDb().execute(`SELECT COUNT(*) as n FROM users WHERE active = 1`)\n return Number(res.rows[0]?.n ?? 0)\n}\n\nexport async function countActiveJobsForUser(userId: number | bigint): Promise<number> {\n const res = await getDb().execute({\n sql: `SELECT COUNT(*) as n FROM jobs WHERE user_id = ? AND (status = 'pending' OR (status = 'running' AND started_at > datetime('now', '-10 minutes')))`,\n args: [userId],\n })\n return Number(res.rows[0]?.n ?? 0)\n}\n\nexport async function claimPendingJob(): Promise<RawJob | undefined> {\n const db = getDb()\n const res = await db.execute(`SELECT * FROM jobs WHERE status = 'pending' ORDER BY created_at LIMIT 1`)\n const job = res.rows[0] ? rowToRawJob(res.rows[0] as unknown as Record<string, unknown>) : undefined\n if (!job) return undefined\n const upd = await db.execute({\n sql: `UPDATE jobs SET status = 'running', started_at = datetime('now') WHERE id = ? AND status = 'pending'`,\n args: [job.id],\n })\n return upd.rowsAffected === 0 ? undefined : { ...job, status: 'running' }\n}\n\nexport async function completeJob(id: string, result: object): Promise<void> {\n await getDb().execute({ sql: `UPDATE jobs SET status = 'done', result = ?, completed_at = datetime('now') WHERE id = ?`, args: [JSON.stringify(result), id] })\n}\n\nexport async function failJob(id: string, error: string): Promise<void> {\n await getDb().execute({ sql: `UPDATE jobs SET status = 'failed', error = ?, completed_at = datetime('now') WHERE id = ?`, args: [error, id] })\n}\n\nexport async function cancelJob(id: string, reason: string): Promise<void> {\n await getDb().execute({ sql: `UPDATE jobs SET status = 'cancelled', error = ?, completed_at = datetime('now') WHERE id = ?`, args: [reason, id] })\n}\n\nexport interface KpoJobRow {\n id: string\n user_id: number\n status: string\n entity_name: string\n entity_type: string\n url: string | null\n request: string\n result: string | null\n error: string | null\n created_at: string\n updated_at: string\n}\n\nexport interface KpoPhaseLogRow {\n id: number\n job_id: string\n phase: string\n output: string\n created_at: string\n}\n\nfunction rowToKpoJob(row: Record<string, unknown>): KpoJobRow {\n return {\n id: String(row.id),\n user_id: Number(row.user_id),\n status: String(row.status),\n entity_name: String(row.entity_name),\n entity_type: String(row.entity_type),\n url: row.url != null ? String(row.url) : null,\n request: String(row.request),\n result: row.result != null ? String(row.result) : null,\n error: row.error != null ? String(row.error) : null,\n created_at: String(row.created_at),\n updated_at: String(row.updated_at),\n }\n}\n\nfunction rowToKpoPhaseLog(row: Record<string, unknown>): KpoPhaseLogRow {\n return {\n id: Number(row.id),\n job_id: String(row.job_id),\n phase: String(row.phase),\n output: String(row.output),\n created_at: String(row.created_at),\n }\n}\n\nexport async function createKpoJob(jobId: string, userId: number, entityName: string, entityType: string, request: object, url?: string): Promise<void> {\n await getDb().execute({\n sql: `INSERT INTO kpo_jobs (id, user_id, status, entity_name, entity_type, url, request) VALUES (?, ?, 'pending', ?, ?, ?, ?)`,\n args: [jobId, userId, entityName, entityType, url ?? null, JSON.stringify(request)],\n })\n}\n\nexport async function claimPendingKpoJob(): Promise<KpoJobRow | null> {\n const db = getDb()\n const upd = await db.execute(\n `UPDATE kpo_jobs SET status='running', updated_at=datetime('now') WHERE id = (SELECT id FROM kpo_jobs WHERE status='pending' ORDER BY created_at ASC LIMIT 1) RETURNING *`\n )\n if (upd.rowsAffected === 0) return null\n return upd.rows[0] ? rowToKpoJob(upd.rows[0] as unknown as Record<string, unknown>) : null\n}\n\nexport async function getKpoJob(jobId: string): Promise<KpoJobRow | null> {\n const res = await getDb().execute({ sql: `SELECT * FROM kpo_jobs WHERE id = ?`, args: [jobId] })\n return res.rows[0] ? rowToKpoJob(res.rows[0] as unknown as Record<string, unknown>) : null\n}\n\nexport async function updateKpoJobState(jobId: string, status: string): Promise<void> {\n await getDb().execute({ sql: `UPDATE kpo_jobs SET status = ?, updated_at = datetime('now') WHERE id = ?`, args: [status, jobId] })\n}\n\nexport async function completeKpoJob(jobId: string, result: object): Promise<void> {\n await getDb().execute({ sql: `UPDATE kpo_jobs SET status = 'done', result = ?, updated_at = datetime('now') WHERE id = ?`, args: [JSON.stringify(result), jobId] })\n}\n\nexport async function failKpoJob(jobId: string, error: string): Promise<void> {\n await getDb().execute({ sql: `UPDATE kpo_jobs SET status = 'failed', error = ?, updated_at = datetime('now') WHERE id = ?`, args: [error, jobId] })\n}\n\nexport async function logKpoPhaseComplete(jobId: string, phase: string, output: unknown): Promise<void> {\n await getDb().execute({\n sql: `INSERT INTO kpo_phase_log (job_id, phase, output) VALUES (?, ?, ?)`,\n args: [jobId, phase, JSON.stringify(output)],\n })\n}\n\nexport async function getKpoPhaseLog(jobId: string): Promise<KpoPhaseLogRow[]> {\n const res = await getDb().execute({ sql: `SELECT * FROM kpo_phase_log WHERE job_id = ? ORDER BY created_at ASC`, args: [jobId] })\n return res.rows.map(r => rowToKpoPhaseLog(r as unknown as Record<string, unknown>))\n}\n\nexport async function listKpoJobs(userId?: number): Promise<KpoJobRow[]> {\n const res = userId != null\n ? await getDb().execute({ sql: `SELECT * FROM kpo_jobs WHERE user_id = ? ORDER BY created_at DESC LIMIT 50`, args: [userId] })\n : await getDb().execute(`SELECT * FROM kpo_jobs ORDER BY created_at DESC LIMIT 50`)\n return res.rows.map(r => rowToKpoJob(r as unknown as Record<string, unknown>))\n}\n\nexport async function getUserByStripeCustomerId(customerId: string): Promise<User | undefined> {\n const res = await getDb().execute({\n sql: 'SELECT * FROM users WHERE stripe_customer_id = ? AND active = 1',\n args: [customerId],\n })\n return res.rows[0] ? rowToUser(res.rows[0] as unknown as Record<string, unknown>) : undefined\n}\n\nexport async function setStripeCustomerId(userId: number, customerId: string): Promise<void> {\n await getDb().execute({\n sql: 'UPDATE users SET stripe_customer_id = ? WHERE id = ?',\n args: [customerId, userId],\n })\n}\n\nexport async function setExtraConcurrencySlots(userId: number, slots: number): Promise<void> {\n await getDb().execute({\n sql: 'UPDATE users SET extra_concurrency_slots = ? WHERE id = ?',\n args: [Math.max(0, slots), userId],\n })\n}\n\nexport async function setConcurrencySubId(userId: number, subId: string | null): Promise<void> {\n await getDb().execute({\n sql: 'UPDATE users SET concurrency_stripe_sub_id = ? WHERE id = ?',\n args: [subId, userId],\n })\n}\n\nexport async function creditMc(\n userId: number,\n mc: number,\n operation: string,\n description?: string,\n stripePaymentIntent?: string,\n): Promise<number> {\n const db = getDb()\n await db.batch([\n { sql: 'UPDATE users SET balance_mc = balance_mc + ? WHERE id = ?', args: [mc, userId] },\n { sql: 'INSERT INTO ledger (user_id, amount_mc, operation, description, stripe_pi) VALUES (?, ?, ?, ?, ?)', args: [userId, mc, operation, description ?? null, stripePaymentIntent ?? null] },\n ], 'write')\n const res = await db.execute({ sql: 'SELECT balance_mc FROM users WHERE id = ?', args: [userId] })\n return Number(res.rows[0]?.balance_mc ?? 0)\n}\n\nexport async function ledgerExistsForOperation(userId: number, operation: string): Promise<boolean> {\n const res = await getDb().execute({\n sql: 'SELECT 1 FROM ledger WHERE user_id = ? AND operation = ? LIMIT 1',\n args: [userId, operation],\n })\n return res.rows.length > 0\n}\n\nexport async function claimMonthlyFreeRefresh(userId: number, month: string): Promise<boolean> {\n const res = await getDb().execute({\n sql: 'INSERT OR IGNORE INTO free_credit_refreshes (user_id, month) VALUES (?, ?)',\n args: [userId, month],\n })\n return res.rowsAffected > 0\n}\n\nexport async function debitMc(\n userId: number,\n mc: number,\n operation: string,\n description?: string,\n): Promise<{ ok: boolean; balance_mc: number }> {\n const db = getDb()\n const upd = await db.execute({\n sql: 'UPDATE users SET balance_mc = balance_mc - ? WHERE id = ? AND balance_mc >= ?',\n args: [mc, userId, mc],\n })\n if (upd.rowsAffected === 0) {\n const res = await db.execute({ sql: 'SELECT balance_mc FROM users WHERE id = ?', args: [userId] })\n return { ok: false, balance_mc: Number(res.rows[0]?.balance_mc ?? 0) }\n }\n await db.execute({\n sql: 'INSERT INTO ledger (user_id, amount_mc, operation, description) VALUES (?, ?, ?, ?)',\n args: [userId, -mc, operation, description ?? null],\n })\n const res = await db.execute({ sql: 'SELECT balance_mc FROM users WHERE id = ?', args: [userId] })\n return { ok: true, balance_mc: Number(res.rows[0]?.balance_mc ?? 0) }\n}\n\nexport async function getLedger(userId: number, limit = 50): Promise<LedgerRow[]> {\n const res = await getDb().execute({\n sql: 'SELECT * FROM ledger WHERE user_id = ? ORDER BY created_at DESC LIMIT ?',\n args: [userId, limit],\n })\n return res.rows.map(r => ({\n id: Number(r.id),\n user_id: Number(r.user_id),\n amount_mc: Number(r.amount_mc),\n operation: String(r.operation),\n description: r.description != null ? String(r.description) : null,\n stripe_pi: r.stripe_pi != null ? String(r.stripe_pi) : null,\n created_at: String(r.created_at),\n }))\n}\n\nexport async function ledgerExistsForStripePI(stripePI: string): Promise<boolean> {\n const res = await getDb().execute({\n sql: 'SELECT 1 FROM ledger WHERE stripe_pi = ? LIMIT 1',\n args: [stripePI],\n })\n return res.rows.length > 0\n}\n\nexport async function reconcileBalanceMc(userId: number | bigint): Promise<number> {\n const db = getDb()\n const res = await db.execute({\n sql: 'SELECT COALESCE(SUM(amount_mc), 0) AS balance_mc FROM ledger WHERE user_id = ?',\n args: [userId],\n })\n const balanceMc = Number(res.rows[0]?.balance_mc ?? 0)\n await db.execute({\n sql: 'UPDATE users SET balance_mc = ? WHERE id = ? AND balance_mc != ?',\n args: [balanceMc, userId, balanceMc],\n })\n return balanceMc\n}\n\nexport interface LedgerRow {\n id: number\n user_id: number\n amount_mc: number\n operation: string\n description: string | null\n stripe_pi: string | null\n created_at: string\n}\n\nexport const SiteAuditJobRowSchema = z.object({\n id: z.string(),\n user_id: z.number(),\n status: z.string().default('pending'),\n client_domain: z.string(),\n session_path: z.string(),\n request: z.string(),\n result: z.string().nullable(),\n error: z.string().nullable(),\n created_at: z.string(),\n updated_at: z.string(),\n});\nexport type SiteAuditJobRow = z.infer<typeof SiteAuditJobRowSchema>;\n\nexport const SiteAuditPhaseLogRowSchema = z.object({\n id: z.number(),\n job_id: z.string(),\n phase: z.string(),\n completed_at: z.string(),\n output_summary: z.string(),\n});\nexport type SiteAuditPhaseLogRow = z.infer<typeof SiteAuditPhaseLogRowSchema>;\n"],"mappings":"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","names":["res"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/workflows/artifact-writer.ts","../src/directory/csv.ts","../src/lib/slugify.ts","../src/workflows/registry.ts","../src/workflows/http-client.ts","../src/workflows/workflows/agent-packet.ts","../src/workflows/report-renderer.ts","../src/workflows/workflows/directory.ts","../src/workflows/workflows/local-competitive-audit.ts","../src/workflows/workflows/comparison-briefs.ts","../src/workflows/workflows/seo-workflow-utils.ts"],"sourcesContent":["import { mkdir, readFile, stat, writeFile } from 'node:fs/promises'\nimport { existsSync } from 'node:fs'\nimport { homedir, platform } from 'node:os'\nimport { dirname, join } from 'node:path'\nimport { execFile } from 'node:child_process'\nimport { rowsToCsv } from '../directory/csv.js'\nimport { slugify } from '../lib/slugify.js'\nimport type { WorkflowArtifact, WorkflowManifest, WorkflowStatus } from './types.js'\n\nexport function workflowOutputBaseDir(outputDir?: string): string {\n return outputDir?.trim() || process.env.MCP_SCRAPER_OUTPUT_DIR?.trim() || join(homedir(), 'Downloads', 'mcp-scraper')\n}\n\nfunction timestamp(): string {\n return new Date().toISOString().replace(/[:.]/g, '-')\n}\n\nfunction safeSlug(value: string): string {\n return slugify(value).replace(/^-+|-+$/g, '').slice(0, 80) || 'run'\n}\n\nexport class ArtifactWriter {\n readonly artifacts: WorkflowArtifact[] = []\n\n constructor(\n readonly workflowId: string,\n readonly title: string,\n readonly runId: string,\n readonly baseDir: string,\n readonly runDir: string,\n readonly startedAt: string,\n readonly input: Record<string, unknown>,\n ) {}\n\n static async create(workflowId: string, title: string, input: Record<string, unknown>, outputDir?: string, forcedRunId?: string): Promise<ArtifactWriter> {\n const startedAt = new Date().toISOString()\n const runId = forcedRunId?.trim() || `${timestamp()}-${safeSlug(workflowId)}-${Math.random().toString(36).slice(2, 8)}`\n const nameSource = String(input.keyword ?? input.query ?? input.domain ?? input.state ?? workflowId)\n const baseDir = workflowOutputBaseDir(outputDir)\n const runDir = join(baseDir, 'workflows', workflowId, `${timestamp()}-${safeSlug(nameSource)}-${safeSlug(runId).slice(0, 20)}`)\n await mkdir(runDir, { recursive: true })\n return new ArtifactWriter(workflowId, title, runId, baseDir, runDir, startedAt, input)\n }\n\n private async remember(kind: WorkflowArtifact['kind'], label: string, path: string, rows?: number): Promise<string> {\n const size = await stat(path).then(s => s.size).catch(() => undefined)\n this.artifacts.push({ kind, label, path, bytes: size, rows })\n return path\n }\n\n async writeJson(label: string, relativePath: string, data: unknown): Promise<string> {\n const path = join(this.runDir, relativePath)\n await mkdir(dirname(path), { recursive: true })\n await writeFile(path, JSON.stringify(data, null, 2), 'utf8')\n return this.remember('json', label, path)\n }\n\n async writeText(label: string, relativePath: string, text: string, kind: WorkflowArtifact['kind'] = 'markdown'): Promise<string> {\n const path = join(this.runDir, relativePath)\n await mkdir(dirname(path), { recursive: true })\n await writeFile(path, text, 'utf8')\n return this.remember(kind, label, path)\n }\n\n async writeCsv(label: string, relativePath: string, headers: string[], rows: Array<Record<string, unknown>>): Promise<string> {\n const path = join(this.runDir, relativePath)\n await mkdir(dirname(path), { recursive: true })\n await writeFile(path, rowsToCsv(headers, rows), 'utf8')\n return this.remember('csv', label, path, rows.length)\n }\n\n async writeHtml(label: string, relativePath: string, html: string): Promise<string> {\n return this.writeText(label, relativePath, html, 'html_report')\n }\n\n async writeManifest(status: WorkflowStatus, counts: Record<string, number>, warnings: string[], errors: string[]): Promise<string> {\n const manifest: WorkflowManifest = {\n workflow: this.workflowId,\n title: this.title,\n runId: this.runId,\n status,\n startedAt: this.startedAt,\n completedAt: status === 'running' ? null : new Date().toISOString(),\n input: this.input,\n artifacts: this.artifacts,\n warnings,\n errors,\n counts,\n }\n const path = join(this.runDir, 'manifest.json')\n await writeFile(path, JSON.stringify(manifest, null, 2), 'utf8')\n await updateWorkflowIndex(manifest, path, this.baseDir)\n return path\n }\n}\n\ninterface WorkflowIndexEntry {\n workflow: string\n runId: string\n status: string\n startedAt: string\n reportPath: string | null\n manifestPath: string\n summary: string\n}\n\ninterface WorkflowIndex {\n runs: WorkflowIndexEntry[]\n}\n\nfunction indexPath(baseDir = workflowOutputBaseDir()): string {\n return join(baseDir, 'workflows', 'index.json')\n}\n\nasync function readIndex(baseDir?: string): Promise<WorkflowIndex> {\n const path = indexPath(baseDir)\n if (!existsSync(path)) return { runs: [] }\n try {\n return JSON.parse(await readFile(path, 'utf8')) as WorkflowIndex\n } catch {\n return { runs: [] }\n }\n}\n\nasync function updateWorkflowIndex(manifest: WorkflowManifest, manifestPath: string, baseDir: string): Promise<void> {\n if (manifest.status === 'running') return\n const path = indexPath(baseDir)\n const index = await readIndex(baseDir)\n const report = manifest.artifacts.find(a => a.kind === 'html_report')?.path ?? null\n const entry: WorkflowIndexEntry = {\n workflow: manifest.workflow,\n runId: manifest.runId,\n status: manifest.status,\n startedAt: manifest.startedAt,\n reportPath: report,\n manifestPath,\n summary: `${manifest.title} (${manifest.status})`,\n }\n index.runs = [entry, ...index.runs.filter(r => r.runId !== manifest.runId)].slice(0, 200)\n await mkdir(dirname(path), { recursive: true })\n await writeFile(path, JSON.stringify(index, null, 2), 'utf8')\n}\n\nexport async function listWorkflowReports(outputDir?: string): Promise<WorkflowIndexEntry[]> {\n return (await readIndex(workflowOutputBaseDir(outputDir))).runs\n}\n\nexport async function findWorkflowReport(id: string, outputDir?: string): Promise<WorkflowIndexEntry | null> {\n const runs = await listWorkflowReports(outputDir)\n if (id === 'last') return runs[0] ?? null\n return runs.find(run => run.runId === id) ?? null\n}\n\nexport async function openWorkflowReport(id: string, outputDir?: string): Promise<string> {\n const run = await findWorkflowReport(id, outputDir)\n if (!run?.reportPath) throw new Error(`No report found for \"${id}\"`)\n if (platform() === 'darwin') {\n await new Promise<void>((resolve, reject) => {\n execFile('open', [run.reportPath!], (err) => err ? reject(err) : resolve())\n })\n }\n return run.reportPath\n}\n","export function parseCsv(text: string): string[][] {\n const rows: string[][] = []\n let row: string[] = []\n let field = ''\n let quoted = false\n\n for (let i = 0; i < text.length; i += 1) {\n const ch = text[i]\n const next = text[i + 1]\n\n if (quoted) {\n if (ch === '\"' && next === '\"') {\n field += '\"'\n i += 1\n } else if (ch === '\"') {\n quoted = false\n } else {\n field += ch\n }\n continue\n }\n\n if (ch === '\"') {\n quoted = true\n } else if (ch === ',') {\n row.push(field)\n field = ''\n } else if (ch === '\\n') {\n row.push(field)\n rows.push(row)\n row = []\n field = ''\n } else if (ch !== '\\r') {\n field += ch\n }\n }\n\n if (field.length > 0 || row.length > 0) {\n row.push(field)\n rows.push(row)\n }\n\n return rows\n}\n\nexport function csvRecords(text: string): Array<Record<string, string>> {\n const rows = parseCsv(text).filter(row => row.some(cell => cell.trim() !== ''))\n const header = rows[0]?.map(cell => cell.trim()) ?? []\n return rows.slice(1).map((row) => {\n const record: Record<string, string> = {}\n for (let i = 0; i < header.length; i += 1) {\n record[header[i]] = row[i] ?? ''\n }\n return record\n })\n}\n\nexport function csvCell(value: unknown): string {\n if (value === null || value === undefined) return ''\n const text = String(value)\n return /[\",\\n\\r]/.test(text) ? `\"${text.replace(/\"/g, '\"\"')}\"` : text\n}\n\nexport function rowsToCsv(headers: string[], rows: Array<Record<string, unknown>>): string {\n return [\n headers.join(','),\n ...rows.map(row => headers.map(header => csvCell(row[header])).join(',')),\n ].join('\\n') + '\\n'\n}\n","export function slugify(s: string): string {\n return s.toLowerCase().replace(/\\s+/g, '-').replace(/[^a-z0-9-]/g, '');\n}\n","import { z } from 'zod'\nimport { ArtifactWriter, findWorkflowReport, listWorkflowReports, openWorkflowReport } from './artifact-writer.js'\nimport { WorkflowHttpClient } from './http-client.js'\nimport type { WorkflowDefinition, WorkflowRunOptions, WorkflowRunSummary } from './types.js'\nimport { agentPacketWorkflowDefinition } from './workflows/agent-packet.js'\nimport { directoryWorkflowDefinition } from './workflows/directory.js'\nimport { localCompetitiveAuditWorkflowDefinition } from './workflows/local-competitive-audit.js'\nimport {\n aiOverviewLanguageWorkflowDefinition,\n mapComparisonWorkflowDefinition,\n paaExpansionBriefWorkflowDefinition,\n serpComparisonWorkflowDefinition,\n} from './workflows/comparison-briefs.js'\n\nconst DEFINITIONS = [\n directoryWorkflowDefinition,\n agentPacketWorkflowDefinition,\n localCompetitiveAuditWorkflowDefinition,\n mapComparisonWorkflowDefinition,\n serpComparisonWorkflowDefinition,\n paaExpansionBriefWorkflowDefinition,\n aiOverviewLanguageWorkflowDefinition,\n] satisfies WorkflowDefinition<any>[]\n\nexport function listWorkflowDefinitions(): Array<Pick<WorkflowDefinition, 'id' | 'title' | 'description'>> {\n return DEFINITIONS.map(({ id, title, description }) => ({ id, title, description }))\n}\n\nexport function workflowDefinition(id: string): WorkflowDefinition<any> {\n const definition = DEFINITIONS.find(def => def.id === id)\n if (!definition) throw new Error(`Unknown workflow \"${id}\". Available: ${DEFINITIONS.map(def => def.id).join(', ')}`)\n return definition\n}\n\nexport async function runWorkflow(id: string, rawInput: Record<string, unknown>, options: WorkflowRunOptions = {}): Promise<WorkflowRunSummary> {\n const definition = workflowDefinition(id)\n const input = definition.inputSchema.parse(rawInput)\n const apiKey = options.apiKey?.trim() || process.env.MCP_SCRAPER_API_KEY?.trim()\n if (!apiKey) throw new Error('MCP_SCRAPER_API_KEY is required for workflow runs. Pass --api-key or set the environment variable.')\n const apiUrl = options.apiUrl?.trim() || process.env.MCP_SCRAPER_API_URL?.trim() || 'https://mcpscraper.dev'\n const artifacts = await ArtifactWriter.create(definition.id, definition.title, input as Record<string, unknown>, options.outputDir, options.runId)\n const client = new WorkflowHttpClient(apiUrl, apiKey, options.fetchImpl)\n try {\n return await definition.run(input, {\n runId: artifacts.runId,\n startedAt: artifacts.startedAt,\n client,\n artifacts,\n signal: options.signal,\n })\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n await artifacts.writeText('Failure', 'summary.md', `# ${definition.title}\\n\\n${message}\\n`)\n await artifacts.writeManifest('failed', {}, [], [message])\n throw err\n }\n}\n\nexport { findWorkflowReport, listWorkflowReports, openWorkflowReport }\nexport { z }\n","import type { WorkflowApiClient } from './types.js'\n\nexport class WorkflowHttpClient implements WorkflowApiClient {\n constructor(\n private readonly apiUrl: string,\n private readonly apiKey: string,\n private readonly fetchImpl: typeof fetch = fetch,\n ) {}\n\n async post<T>(path: string, body: Record<string, unknown>, timeoutMs = 180_000): Promise<T> {\n const res = await this.fetchImpl(`${this.apiUrl.replace(/\\/$/, '')}${path}`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': this.apiKey,\n },\n body: JSON.stringify(body),\n signal: AbortSignal.timeout(timeoutMs),\n })\n const data = await res.json().catch(() => ({}))\n if (!res.ok) {\n const message = typeof (data as { error?: unknown }).error === 'string'\n ? (data as { error: string }).error\n : `Workflow API ${path} failed with ${res.status}`\n throw new Error(message)\n }\n return data as T\n }\n}\n\n","import { z } from 'zod'\nimport { rowsToCsv } from '../../directory/csv.js'\nimport { renderWorkflowReport } from '../report-renderer.js'\nimport type { WorkflowDefinition, WorkflowRunContext, WorkflowRunSummary } from '../types.js'\n\nconst AgentPacketInputSchema = z.object({\n keyword: z.string().min(1),\n domain: z.string().optional(),\n location: z.string().optional(),\n maxQuestions: z.number().int().min(1).max(200).default(40),\n includeSerp: z.boolean().default(true),\n includePaa: z.boolean().default(true),\n includeAiOverview: z.boolean().default(true),\n returnPartial: z.boolean().default(true),\n})\n\ntype AgentPacketInput = z.infer<typeof AgentPacketInputSchema>\n\ninterface OrganicResult {\n position: number\n title: string\n url: string\n domain: string\n snippet?: string | null\n}\n\ninterface PaaRow {\n question: string\n answer?: string | null\n source_title?: string | null\n source_site?: string | null\n source_cite?: string | null\n}\n\ninterface HarvestLike {\n organicResults?: OrganicResult[]\n localPack?: Array<{ position: number; name: string; rating?: string | null; reviewCount?: string | null; websiteUrl?: string | null }>\n flat?: PaaRow[]\n aiOverview?: { detected?: boolean; text?: string | null; citations?: Array<{ text?: string; href?: string }> }\n}\n\nfunction normalizeDomain(value?: string | null): string | null {\n if (!value) return null\n try {\n const url = new URL(value.includes('://') ? value : `https://${value}`)\n return url.hostname.replace(/^www\\./, '').toLowerCase()\n } catch {\n return value.replace(/^https?:\\/\\//, '').replace(/^www\\./, '').split('/')[0]?.toLowerCase() || null\n }\n}\n\nfunction domainFromUrl(url: string): string {\n return normalizeDomain(url) ?? ''\n}\n\nfunction sourceRows(input: AgentPacketInput, serp: HarvestLike | null, paa: HarvestLike | null): Array<Record<string, unknown>> {\n const target = normalizeDomain(input.domain)\n const rows: Array<Record<string, unknown>> = []\n for (const result of serp?.organicResults ?? []) {\n const domain = normalizeDomain(result.domain) ?? domainFromUrl(result.url)\n rows.push({\n surface: 'organic',\n position: result.position,\n title: result.title,\n url: result.url,\n domain,\n question: '',\n answer_excerpt: result.snippet ?? '',\n is_target: target ? domain === target : false,\n is_competitor: target ? domain !== target : true,\n })\n }\n for (const row of paa?.flat ?? []) {\n const url = row.source_cite ?? ''\n const domain = normalizeDomain(row.source_site ?? '') ?? (url ? domainFromUrl(url) : '')\n rows.push({\n surface: 'paa',\n position: '',\n title: row.source_title ?? row.source_site ?? '',\n url,\n domain,\n question: row.question,\n answer_excerpt: (row.answer ?? '').slice(0, 240),\n is_target: target ? domain === target : false,\n is_competitor: target ? Boolean(domain && domain !== target) : Boolean(domain),\n })\n }\n for (const [i, cite] of (serp?.aiOverview?.citations ?? []).entries()) {\n const url = cite.href ?? ''\n const domain = url ? domainFromUrl(url) : ''\n rows.push({\n surface: 'ai_overview',\n position: i + 1,\n title: cite.text ?? '',\n url,\n domain,\n question: '',\n answer_excerpt: '',\n is_target: target ? domain === target : false,\n is_competitor: target ? Boolean(domain && domain !== target) : Boolean(domain),\n })\n }\n return rows\n}\n\nfunction competitorRows(rows: Array<Record<string, unknown>>, targetDomain: string | null): Array<Record<string, unknown>> {\n const byDomain = new Map<string, { organic: number[]; paa: number; ai: number; urls: Set<string> }>()\n for (const row of rows) {\n const domain = String(row.domain ?? '')\n if (!domain || domain === targetDomain) continue\n const entry = byDomain.get(domain) ?? { organic: [], paa: 0, ai: 0, urls: new Set<string>() }\n if (row.surface === 'organic' && row.position) entry.organic.push(Number(row.position))\n if (row.surface === 'paa') entry.paa += 1\n if (row.surface === 'ai_overview') entry.ai += 1\n if (row.url) entry.urls.add(String(row.url))\n byDomain.set(domain, entry)\n }\n return [...byDomain.entries()]\n .map(([domain, entry]) => ({\n domain,\n organic_best_position: entry.organic.length ? Math.min(...entry.organic) : '',\n organic_count: entry.organic.length,\n paa_mentions: entry.paa,\n ai_overview_citations: entry.ai,\n source_url_count: entry.urls.size,\n }))\n .sort((a, b) => Number(a.organic_best_position || 999) - Number(b.organic_best_position || 999))\n}\n\nexport const agentPacketWorkflowDefinition: WorkflowDefinition<AgentPacketInput> = {\n id: 'agent-packet',\n title: 'Agent-Ready SEO Packet',\n description: 'Create an evidence folder for AI agents from live SERP/PAA/AI search surfaces.',\n inputSchema: AgentPacketInputSchema,\n async run(input: AgentPacketInput, ctx: WorkflowRunContext): Promise<WorkflowRunSummary> {\n await ctx.artifacts.writeManifest('running', {}, [], [])\n const warnings: string[] = []\n const errors: string[] = []\n let serp: HarvestLike | null = null\n let paa: HarvestLike | null = null\n\n if (input.includeSerp) {\n try {\n serp = await ctx.client.post<HarvestLike>('/harvest/sync', {\n query: input.keyword,\n location: input.location,\n serpOnly: true,\n maxQuestions: 1,\n format: 'json',\n }, 180_000)\n } catch (err) {\n warnings.push(`SERP evidence unavailable: ${err instanceof Error ? err.message : String(err)}`)\n }\n }\n\n if (input.includePaa) {\n try {\n paa = await ctx.client.post<HarvestLike>('/harvest/sync', {\n query: input.keyword,\n location: input.location,\n maxQuestions: input.maxQuestions,\n format: 'json',\n }, 280_000)\n } catch (err) {\n warnings.push(`PAA evidence unavailable: ${err instanceof Error ? err.message : String(err)}`)\n }\n }\n\n if (!serp && !paa && !input.returnPartial) throw new Error('No SEO evidence was collected')\n const rows = sourceRows(input, serp, paa)\n const target = normalizeDomain(input.domain)\n const competitors = competitorRows(rows, target)\n const evidence = {\n input,\n serp: serp ?? { status: 'skipped' },\n paa: paa ?? { status: 'skipped' },\n target: {\n domain: target,\n organicPositions: rows.filter(r => r.surface === 'organic' && r.is_target).map(r => Number(r.position)),\n citedInAiOverview: rows.some(r => r.surface === 'ai_overview' && r.is_target),\n citedInPaa: rows.some(r => r.surface === 'paa' && r.is_target),\n },\n competitors,\n warnings,\n }\n\n await ctx.artifacts.writeJson('Evidence JSON', 'evidence.json', evidence)\n await ctx.artifacts.writeCsv('Sources CSV', 'sources.csv', ['surface', 'position', 'title', 'url', 'domain', 'question', 'answer_excerpt', 'is_target', 'is_competitor'], rows)\n await ctx.artifacts.writeCsv('Competitors CSV', 'competitors.csv', ['domain', 'organic_best_position', 'organic_count', 'paa_mentions', 'ai_overview_citations', 'source_url_count'], competitors)\n\n const brief = [\n `# SEO Evidence Brief: ${input.keyword}`,\n '',\n `Location: ${input.location ?? 'not specified'}`,\n `Target domain: ${target ?? 'not specified'}`,\n '',\n '## Evidence Summary',\n `- Organic rows: ${rows.filter(r => r.surface === 'organic').length}`,\n `- PAA rows: ${rows.filter(r => r.surface === 'paa').length}`,\n `- AI Overview citations: ${rows.filter(r => r.surface === 'ai_overview').length}`,\n `- Competitor domains: ${competitors.length}`,\n '',\n '## Recommended Use',\n 'Use the CSV files as source of truth. Tie content recommendations to evidence rows and mark unsupported ideas as assumptions.',\n ].join('\\n')\n await ctx.artifacts.writeText('Brief', 'brief.md', brief)\n await ctx.artifacts.writeText('Agent tasks', 'tasks.md', [\n '# Agent Tasks',\n '',\n '- [ ] Read `evidence.json` before writing recommendations.',\n '- [ ] Compare the target domain against `competitors.csv`.',\n '- [ ] Use `sources.csv` for citations and source-grounded page sections.',\n '- [ ] Mark unsupported recommendations as assumptions.',\n ].join('\\n'))\n await ctx.artifacts.writeText('Agent instructions', 'agent-instructions.md', [\n '# Agent Instructions',\n '',\n 'You are working from an MCP Scraper SEO evidence packet. Use `evidence.json` and CSV files as source of truth. Do not invent citations. If a recommendation is not supported by evidence, mark it as an assumption.',\n ].join('\\n'))\n\n const summary = `${rows.length} evidence rows and ${competitors.length} competitor domains collected.`\n const reportPath = await ctx.artifacts.writeHtml('HTML report', 'report.html', renderWorkflowReport({\n title: 'Agent-Ready SEO Packet',\n subtitle: `${input.keyword}${input.location ? ` · ${input.location}` : ''}`,\n summary,\n warnings,\n tables: [\n { title: 'Competitor Domains', columns: ['domain', 'organic_best_position', 'organic_count', 'paa_mentions', 'ai_overview_citations', 'source_url_count'], rows: competitors.slice(0, 50) },\n { title: 'Evidence Sources', columns: ['surface', 'position', 'title', 'domain', 'question', 'is_target'], rows: rows.slice(0, 100) },\n ],\n }))\n const status = warnings.length ? 'partial' : 'succeeded'\n const counts = { sources: rows.length, competitors: competitors.length }\n await ctx.artifacts.writeManifest(status, counts, warnings, errors)\n return { title: 'Agent-Ready SEO Packet', summary, status, counts, warnings, errors, reportPath }\n },\n}\n\n","export interface ReportTable {\n title: string\n columns: string[]\n rows: Array<Record<string, unknown>>\n}\n\nexport interface ReportSection {\n title: string\n body: string\n}\n\nexport interface WorkflowReportInput {\n title: string\n subtitle?: string\n summary: string\n sections?: ReportSection[]\n tables?: ReportTable[]\n warnings?: string[]\n}\n\nexport function escapeHtml(value: unknown): string {\n return String(value ?? '')\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&#39;')\n}\n\nfunction renderTable(table: ReportTable): string {\n const rows = table.rows.map(row => (\n `<tr>${table.columns.map(col => `<td>${escapeHtml(row[col])}</td>`).join('')}</tr>`\n )).join('\\n')\n return [\n `<section>`,\n `<h2>${escapeHtml(table.title)}</h2>`,\n `<div class=\"table-wrap\"><table>`,\n `<thead><tr>${table.columns.map(col => `<th>${escapeHtml(col)}</th>`).join('')}</tr></thead>`,\n `<tbody>${rows || `<tr><td colspan=\"${table.columns.length}\">No rows</td></tr>`}</tbody>`,\n `</table></div>`,\n `</section>`,\n ].join('\\n')\n}\n\nexport function renderWorkflowReport(input: WorkflowReportInput): string {\n const warnings = input.warnings?.length\n ? `<section class=\"warnings\"><h2>Warnings</h2><ul>${input.warnings.map(w => `<li>${escapeHtml(w)}</li>`).join('')}</ul></section>`\n : ''\n const sections = (input.sections ?? []).map(section => (\n `<section><h2>${escapeHtml(section.title)}</h2><p>${escapeHtml(section.body)}</p></section>`\n )).join('\\n')\n const tables = (input.tables ?? []).map(renderTable).join('\\n')\n\n return [\n '<!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>${escapeHtml(input.title)}</title>`,\n '<style>',\n ':root{font-family:Inter,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,\"Segoe UI\",sans-serif;color:#172026;background:#f6f7f8}',\n 'body{margin:0;padding:32px}main{max-width:1180px;margin:0 auto;background:#fff;border:1px solid #d9dee3;border-radius:8px;padding:28px}',\n 'h1{font-size:30px;line-height:1.15;margin:0 0 8px}h2{font-size:18px;margin:28px 0 12px}p{line-height:1.55;color:#3d4952}.sub{color:#66737f;margin:0 0 20px}',\n '.summary{background:#eef6f8;border-left:4px solid #12829a;padding:14px 16px;margin:20px 0}.warnings{background:#fff7e8;border-left:4px solid #c87b00;padding:12px 16px}',\n '.table-wrap{overflow:auto;border:1px solid #dfe5ea;border-radius:8px}table{border-collapse:collapse;width:100%;font-size:13px}th,td{border-bottom:1px solid #edf0f2;padding:9px 10px;text-align:left;vertical-align:top}th{background:#f3f5f7;color:#31404c;position:sticky;top:0}tr:last-child td{border-bottom:0}',\n '</style>',\n '</head>',\n '<body><main>',\n `<h1>${escapeHtml(input.title)}</h1>`,\n input.subtitle ? `<p class=\"sub\">${escapeHtml(input.subtitle)}</p>` : '',\n `<div class=\"summary\">${escapeHtml(input.summary)}</div>`,\n warnings,\n sections,\n tables,\n '</main></body></html>',\n ].join('\\n')\n}\n\n","import { z } from 'zod'\nimport { renderWorkflowReport } from '../report-renderer.js'\nimport type { WorkflowDefinition, WorkflowRunContext, WorkflowRunSummary } from '../types.js'\n\nconst DirectoryWorkflowCliInputSchema = z.object({\n query: z.string().min(1),\n state: z.string().min(2).default('TN'),\n minPopulation: z.number().int().min(0).default(100_000),\n maxCities: z.number().int().min(1).max(100).default(25),\n maxResultsPerCity: z.number().int().min(1).max(50).default(20),\n concurrency: z.number().int().min(1).max(5).default(5),\n proxyMode: z.enum(['location', 'configured', 'none']).default('location'),\n saveCsv: z.boolean().default(true),\n})\n\ntype DirectoryWorkflowCliInput = z.infer<typeof DirectoryWorkflowCliInputSchema>\n\ninterface DirectoryBusiness {\n position: number\n name: string\n rating: string | null\n reviewCount: string | null\n category: string | null\n address: string | null\n phone: string | null\n websiteUrl: string | null\n placeUrl: string\n cid: string | null\n cidDecimal: string | null\n}\n\ninterface DirectoryCity {\n city: string\n state: string\n location: string\n population: number\n status: 'ok' | 'empty' | 'failed'\n error: string | null\n resultCount: number\n results: DirectoryBusiness[]\n}\n\nexport interface DirectoryWorkflowApiResult {\n query: string\n state: string\n selectedCityCount: number\n totalResultCount: number\n warnings: string[]\n csvPath: string | null\n cities: DirectoryCity[]\n}\n\nexport function directoryRows(result: DirectoryWorkflowApiResult): Array<Record<string, unknown>> {\n const rows: Array<Record<string, unknown>> = []\n for (const city of result.cities) {\n if (!city.results.length) {\n rows.push({\n source_query: result.query,\n source_location: city.location,\n city: city.city,\n state: city.state,\n population: city.population,\n result_position: null,\n business_name: null,\n review_stars: null,\n review_count: null,\n category: null,\n address: null,\n phone: null,\n website_url: null,\n place_url: null,\n cid: null,\n cid_decimal: null,\n result_status: city.status,\n error: city.error,\n })\n continue\n }\n for (const business of city.results) {\n rows.push({\n source_query: result.query,\n source_location: city.location,\n city: city.city,\n state: city.state,\n population: city.population,\n result_position: business.position,\n business_name: business.name,\n review_stars: business.rating,\n review_count: business.reviewCount,\n category: business.category,\n address: business.address,\n phone: business.phone,\n website_url: business.websiteUrl,\n place_url: business.placeUrl,\n cid: business.cid,\n cid_decimal: business.cidDecimal,\n result_status: city.status,\n error: city.error,\n })\n }\n }\n return rows\n}\n\nexport const DIRECTORY_CSV_HEADERS = [\n 'source_query',\n 'source_location',\n 'city',\n 'state',\n 'population',\n 'result_position',\n 'business_name',\n 'review_stars',\n 'review_count',\n 'category',\n 'address',\n 'phone',\n 'website_url',\n 'place_url',\n 'cid',\n 'cid_decimal',\n 'result_status',\n 'error',\n]\n\nexport const directoryWorkflowDefinition: WorkflowDefinition<DirectoryWorkflowCliInput> = {\n id: 'directory',\n title: 'Directory Workflow',\n description: 'Select city markets and export Google Maps business candidates.',\n inputSchema: DirectoryWorkflowCliInputSchema,\n async run(input: DirectoryWorkflowCliInput, ctx: WorkflowRunContext): Promise<WorkflowRunSummary> {\n await ctx.artifacts.writeManifest('running', {}, [], [])\n const result = await ctx.client.post<DirectoryWorkflowApiResult>('/directory/run', input as Record<string, unknown>, 900_000)\n await ctx.artifacts.writeJson('Directory evidence', 'evidence.json', result)\n const rows = directoryRows(result)\n await ctx.artifacts.writeCsv('Directory CSV', 'exports/directory.csv', DIRECTORY_CSV_HEADERS, rows)\n\n const cityRows = result.cities.map(city => ({\n city: city.city,\n state: city.state,\n population: city.population,\n status: city.status,\n result_count: city.resultCount,\n error: city.error ?? '',\n }))\n const topRows = rows\n .filter(row => row.business_name)\n .slice(0, 100)\n .map(row => ({\n city: row.city,\n position: row.result_position,\n business: row.business_name,\n rating: row.review_stars,\n reviews: row.review_count,\n category: row.category,\n website: row.website_url,\n }))\n\n const summary = `${result.selectedCityCount} cities processed with ${result.totalResultCount} Maps results.`\n await ctx.artifacts.writeText('Summary', 'summary.md', `# Directory Workflow\\n\\n${summary}\\n`)\n const reportPath = await ctx.artifacts.writeHtml('HTML report', 'report.html', renderWorkflowReport({\n title: 'Directory Workflow',\n subtitle: `${input.query} · ${input.state}`,\n summary,\n warnings: result.warnings,\n tables: [\n { title: 'Cities', columns: ['city', 'state', 'population', 'status', 'result_count', 'error'], rows: cityRows },\n { title: 'Top Results', columns: ['city', 'position', 'business', 'rating', 'reviews', 'category', 'website'], rows: topRows },\n ],\n }))\n const status = result.cities.some(city => city.status === 'failed') ? 'partial' : 'succeeded'\n const counts = { cities: result.selectedCityCount, results: result.totalResultCount, rows: rows.length }\n await ctx.artifacts.writeManifest(status, counts, result.warnings, [])\n return { title: 'Directory Workflow', summary, status, counts, warnings: result.warnings, errors: [], reportPath }\n },\n}\n\n","import { z } from 'zod'\nimport { renderWorkflowReport } from '../report-renderer.js'\nimport type { WorkflowDefinition, WorkflowRunContext, WorkflowRunSummary } from '../types.js'\nimport { DIRECTORY_CSV_HEADERS, directoryRows, type DirectoryWorkflowApiResult } from './directory.js'\n\nconst LocalCompetitiveAuditInputSchema = z.object({\n query: z.string().min(1),\n state: z.string().min(2).default('TN'),\n minPopulation: z.number().int().min(0).default(100_000),\n maxCities: z.number().int().min(1).max(100).default(25),\n maxResultsPerCity: z.number().int().min(1).max(50).default(20),\n hydrateTop: z.number().int().min(0).max(10).default(5),\n maxReviews: z.number().int().min(0).max(500).default(50),\n concurrency: z.number().int().min(1).max(5).default(5),\n proxyMode: z.enum(['location', 'configured', 'none']).default('location'),\n returnPartial: z.boolean().default(true),\n})\n\ntype LocalCompetitiveAuditInput = z.infer<typeof LocalCompetitiveAuditInputSchema>\n\ninterface MapsPlaceIntelResult {\n name: string | null\n rating: string | null\n reviewCount: string | null\n category: string | null\n website: string | null\n reviewsStatus: string\n reviewHistogram: Array<{ stars: number; count: string }>\n reviewTopics: Array<{ label: string; count: string }>\n aboutAttributes: Array<{ section: string; attribute: string }>\n reviews: Array<{ stars: string | null; text: string | null; ownerResponse: string | null }>\n}\n\nasync function mapLimit<T, R>(items: T[], limit: number, fn: (item: T, index: number) => Promise<R>): Promise<R[]> {\n const out: R[] = new Array(items.length)\n let next = 0\n async function worker(): Promise<void> {\n while (next < items.length) {\n const index = next\n next += 1\n out[index] = await fn(items[index], index)\n }\n }\n await Promise.all(Array.from({ length: Math.min(limit, items.length) }, () => worker()))\n return out\n}\n\nfunction numberFrom(value: unknown): number | null {\n if (value === null || value === undefined || value === '') return null\n const parsed = Number(String(value).replace(/[^\\d.]/g, ''))\n return Number.isFinite(parsed) ? parsed : null\n}\n\nfunction median(values: Array<number | null>): number | null {\n const nums = values.filter((v): v is number => v !== null).sort((a, b) => a - b)\n if (!nums.length) return null\n return nums[Math.floor(nums.length / 2)] ?? null\n}\n\nfunction termsFrom(texts: string[]): string {\n const stop = new Set(['the', 'and', 'for', 'with', 'that', 'this', 'was', 'were', 'are', 'you', 'our', 'they', 'had', 'have', 'not', 'but', 'from', 'very', 'great', 'good'])\n const counts = new Map<string, number>()\n for (const text of texts) {\n for (const token of text.toLowerCase().replace(/[^a-z0-9\\s]/g, ' ').split(/\\s+/)) {\n if (token.length < 4 || stop.has(token)) continue\n counts.set(token, (counts.get(token) ?? 0) + 1)\n }\n }\n return [...counts.entries()].sort((a, b) => b[1] - a[1]).slice(0, 8).map(([term, count]) => `${term} (${count})`).join('; ')\n}\n\nexport const localCompetitiveAuditWorkflowDefinition: WorkflowDefinition<LocalCompetitiveAuditInput> = {\n id: 'local-competitive-audit',\n title: 'Local Competitive Audit',\n description: 'Audit local Maps competitors, categories, review counts, and review themes across city markets.',\n inputSchema: LocalCompetitiveAuditInputSchema,\n async run(input: LocalCompetitiveAuditInput, ctx: WorkflowRunContext): Promise<WorkflowRunSummary> {\n await ctx.artifacts.writeManifest('running', {}, [], [])\n const warnings: string[] = []\n const errors: string[] = []\n const directory = await ctx.client.post<DirectoryWorkflowApiResult>('/directory/run', {\n query: input.query,\n state: input.state,\n minPopulation: input.minPopulation,\n maxCities: input.maxCities,\n maxResultsPerCity: input.maxResultsPerCity,\n concurrency: input.concurrency,\n proxyMode: input.proxyMode,\n saveCsv: true,\n }, 900_000)\n\n await ctx.artifacts.writeJson('Directory raw JSON', 'raw/directory-workflow.json', directory)\n const baseRows = directoryRows(directory)\n await ctx.artifacts.writeCsv('Base directory CSV', 'exports/directory.csv', DIRECTORY_CSV_HEADERS, baseRows)\n\n const selected = directory.cities.flatMap(city =>\n city.results.slice(0, input.hydrateTop).map(result => ({ city, result })),\n )\n const seen = new Set<string>()\n const deduped = selected.filter(({ city, result }) => {\n const key = result.cid ?? result.placeUrl ?? `${city.location}:${result.name.toLowerCase()}`\n if (seen.has(key)) return false\n seen.add(key)\n return true\n })\n\n const hydrated = await mapLimit(deduped, 3, async ({ city, result }, index) => {\n try {\n const detail = await ctx.client.post<MapsPlaceIntelResult>('/maps/place', {\n businessName: result.name,\n location: city.location,\n includeReviews: input.maxReviews > 0,\n maxReviews: Math.max(1, input.maxReviews),\n }, 180_000)\n await ctx.artifacts.writeJson(`${result.name} profile`, `raw/maps-place-intel/${index + 1}-${result.name.toLowerCase().replace(/[^a-z0-9]+/g, '-')}.json`, detail)\n return { city, result, detail, error: null as string | null }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n warnings.push(`Profile hydration failed for ${result.name} (${city.location}): ${message}`)\n return { city, result, detail: null, error: message }\n }\n })\n\n const competitorRows = hydrated.map(({ city, result, detail, error }) => {\n const reviews = detail?.reviews ?? []\n const ownerResponses = reviews.filter(r => r.ownerResponse).length\n return {\n city: city.city,\n state: city.state,\n source_location: city.location,\n result_position: result.position,\n business_name: result.name,\n category: detail?.category ?? result.category,\n review_stars: detail?.rating ?? result.rating,\n review_count: detail?.reviewCount ?? result.reviewCount,\n phone: result.phone,\n website_url: detail?.website ?? result.websiteUrl,\n place_url: result.placeUrl,\n cid: result.cid,\n cid_decimal: result.cidDecimal,\n hydrated: detail ? 'true' : 'false',\n reviews_status: detail?.reviewsStatus ?? '',\n review_topics: (detail?.reviewTopics ?? []).map(t => `${t.label} (${t.count})`).join('; '),\n owner_response_rate: reviews.length ? (ownerResponses / reviews.length).toFixed(2) : '',\n error: error ?? '',\n }\n })\n\n const reviewInsightRows = hydrated.map(({ city, result, detail }) => {\n const reviews = detail?.reviews ?? []\n const positive = reviews.filter(r => Number(r.stars) >= 5 && r.text).map(r => r.text!)\n const negative = reviews.filter(r => Number(r.stars) > 0 && Number(r.stars) <= 3 && r.text).map(r => r.text!)\n return {\n city: city.city,\n business_name: result.name,\n cid: result.cid,\n review_count: detail?.reviewCount ?? result.reviewCount,\n average_rating: detail?.rating ?? result.rating,\n topics: (detail?.reviewTopics ?? []).map(t => `${t.label} (${t.count})`).join('; '),\n praise_terms: termsFrom(positive),\n complaint_terms: termsFrom(negative),\n positive_sample: positive[0]?.slice(0, 280) ?? '',\n negative_sample: negative[0]?.slice(0, 280) ?? '',\n }\n })\n\n const citySummaryRows = directory.cities.map(city => {\n const resultReviewCounts = city.results.map(r => numberFrom(r.reviewCount))\n const resultRatings = city.results.map(r => numberFrom(r.rating))\n const topThreeReviews = city.results.slice(0, 3).map(r => numberFrom(r.reviewCount)).filter((v): v is number => v !== null)\n const categories = new Map<string, number>()\n for (const result of city.results) {\n if (!result.category) continue\n categories.set(result.category, (categories.get(result.category) ?? 0) + 1)\n }\n const medReviews = median(resultReviewCounts)\n const medRating = median(resultRatings)\n const topThreeAvg = topThreeReviews.length ? Math.round(topThreeReviews.reduce((a, b) => a + b, 0) / topThreeReviews.length) : null\n const difficulty = Math.min(100, Math.round((topThreeAvg ?? 0) / 20 + (medRating ?? 0) * 10 + city.results.filter(r => r.websiteUrl).length))\n const opportunity = Math.max(0, 100 - difficulty)\n return {\n city: city.city,\n state: city.state,\n population: city.population,\n result_count: city.resultCount,\n median_review_count: medReviews ?? '',\n median_rating: medRating ?? '',\n top_three_average_review_count: topThreeAvg ?? '',\n top_categories: [...categories.entries()].sort((a, b) => b[1] - a[1]).slice(0, 5).map(([cat, count]) => `${cat} (${count})`).join('; '),\n opportunity_score: opportunity,\n difficulty_score: difficulty,\n }\n })\n\n await ctx.artifacts.writeCsv('Competitors CSV', 'competitors.csv', ['city', 'state', 'source_location', 'result_position', 'business_name', 'category', 'review_stars', 'review_count', 'phone', 'website_url', 'place_url', 'cid', 'cid_decimal', 'hydrated', 'reviews_status', 'review_topics', 'owner_response_rate', 'error'], competitorRows)\n await ctx.artifacts.writeCsv('Review insights CSV', 'review-insights.csv', ['city', 'business_name', 'cid', 'review_count', 'average_rating', 'topics', 'praise_terms', 'complaint_terms', 'positive_sample', 'negative_sample'], reviewInsightRows)\n await ctx.artifacts.writeCsv('City summary CSV', 'city-summary.csv', ['city', 'state', 'population', 'result_count', 'median_review_count', 'median_rating', 'top_three_average_review_count', 'top_categories', 'opportunity_score', 'difficulty_score'], citySummaryRows)\n await ctx.artifacts.writeJson('Audit evidence', 'evidence.json', { input, directory, hydrated, citySummaryRows, competitorRows, reviewInsightRows })\n await ctx.artifacts.writeText('Agent tasks', 'tasks.md', [\n '# Local Competitive Audit Tasks',\n '',\n '- [ ] Review city opportunity and difficulty scores as heuristics, not absolute truth.',\n '- [ ] Use review topics and samples as customer-language evidence.',\n '- [ ] Compare target GBP category, review count, and website quality against top competitors.',\n '- [ ] Identify cities with low review-count leaders and weak website coverage.',\n ].join('\\n'))\n\n const summary = `${directory.selectedCityCount} cities, ${directory.totalResultCount} Maps results, ${hydrated.filter(h => h.detail).length} hydrated profiles.`\n await ctx.artifacts.writeText('Summary', 'summary.md', `# Local Competitive Audit\\n\\n${summary}\\n`)\n const reportPath = await ctx.artifacts.writeHtml('HTML report', 'report.html', renderWorkflowReport({\n title: 'Local Competitive Audit',\n subtitle: `${input.query} · ${input.state}`,\n summary,\n warnings,\n tables: [\n { title: 'City Opportunity', columns: ['city', 'state', 'population', 'result_count', 'median_review_count', 'median_rating', 'top_three_average_review_count', 'top_categories', 'opportunity_score', 'difficulty_score'], rows: citySummaryRows },\n { title: 'Hydrated Competitors', columns: ['city', 'result_position', 'business_name', 'category', 'review_stars', 'review_count', 'hydrated', 'review_topics'], rows: competitorRows.slice(0, 100) },\n { title: 'Review Insights', columns: ['city', 'business_name', 'topics', 'praise_terms', 'complaint_terms'], rows: reviewInsightRows.slice(0, 100) },\n ],\n }))\n\n const status = warnings.length || directory.cities.some(city => city.status === 'failed') ? 'partial' : 'succeeded'\n const counts = { cities: directory.selectedCityCount, mapsResults: directory.totalResultCount, hydratedProfiles: hydrated.filter(h => h.detail).length }\n await ctx.artifacts.writeManifest(status, counts, warnings, errors)\n return { title: 'Local Competitive Audit', summary, status, counts, warnings, errors, reportPath }\n },\n}\n\n","import { z } from 'zod'\nimport { renderWorkflowReport } from '../report-renderer.js'\nimport type { WorkflowDefinition, WorkflowRunContext, WorkflowRunSummary } from '../types.js'\nimport { DIRECTORY_CSV_HEADERS, directoryRows, type DirectoryWorkflowApiResult } from './directory.js'\nimport {\n classifySentence,\n domainFromUrl,\n mapLimit,\n median,\n normalizeDomain,\n numberFrom,\n pageSummaryRow,\n questionRows,\n sourceDomainRows,\n splitSentences,\n textTerms,\n type ExtractUrlResult,\n type HarvestLike,\n type MapsSearchBusinessLike,\n type MapsSearchResultLike,\n type OrganicResult,\n} from './seo-workflow-utils.js'\n\nconst ProxyModeSchema = z.enum(['location', 'configured', 'none'])\n\nconst MapComparisonInputSchema = z.object({\n query: z.string().min(1),\n location: z.string().optional(),\n state: z.string().optional(),\n minPopulation: z.number().int().min(0).default(100_000),\n maxCities: z.number().int().min(1).max(100).default(5),\n maxResultsPerCity: z.number().int().min(1).max(50).default(20),\n hydrateTop: z.number().int().min(0).max(10).default(5),\n maxReviews: z.number().int().min(0).max(500).default(25),\n concurrency: z.number().int().min(1).max(5).default(5),\n proxyMode: ProxyModeSchema.default('location'),\n returnPartial: z.boolean().default(true),\n}).refine(input => input.location || input.state, {\n message: 'Either location or state is required for map-comparison',\n})\n\nconst SerpComparisonInputSchema = z.object({\n keyword: z.string().min(1),\n domain: z.string().optional(),\n url: z.string().url().optional(),\n location: z.string().optional(),\n maxResults: z.number().int().min(1).max(20).default(10),\n maxQuestions: z.number().int().min(1).max(200).default(40),\n extractTop: z.number().int().min(0).max(10).default(5),\n includePaa: z.boolean().default(true),\n includeAiOverview: z.boolean().default(true),\n returnPartial: z.boolean().default(true),\n})\n\nconst PaaExpansionBriefInputSchema = z.object({\n keyword: z.string().min(1),\n location: z.string().optional(),\n maxQuestions: z.number().int().min(1).max(300).default(80),\n depth: z.number().int().min(1).max(6).default(3),\n returnPartial: z.boolean().default(true),\n})\n\nconst AiOverviewLanguageInputSchema = z.object({\n keyword: z.string().min(1),\n domain: z.string().optional(),\n url: z.string().url().optional(),\n location: z.string().optional(),\n maxQuestions: z.number().int().min(1).max(200).default(40),\n extractTop: z.number().int().min(0).max(8).default(3),\n returnPartial: z.boolean().default(true),\n})\n\ntype MapComparisonInput = z.infer<typeof MapComparisonInputSchema>\ntype SerpComparisonInput = z.infer<typeof SerpComparisonInputSchema>\ntype PaaExpansionBriefInput = z.infer<typeof PaaExpansionBriefInputSchema>\ntype AiOverviewLanguageInput = z.infer<typeof AiOverviewLanguageInputSchema>\n\ninterface MapsPlaceIntelResult {\n name?: string | null\n rating?: string | null\n reviewCount?: string | null\n category?: string | null\n website?: string | null\n reviewsStatus?: string\n reviewTopics?: Array<{ label: string; count: string }>\n aboutAttributes?: Array<{ section: string; attribute: string }>\n reviews?: Array<{ stars: string | null; text: string | null; ownerResponse: string | null }>\n}\n\nfunction businessRowsFromMaps(location: string, query: string, results: MapsSearchBusinessLike[]): Array<Record<string, unknown>> {\n return results.map(result => ({\n source_query: query,\n source_location: location,\n city: location.split(',')[0]?.trim() ?? location,\n state: location.split(',')[1]?.trim() ?? '',\n population: '',\n result_position: result.position,\n business_name: result.name,\n review_stars: result.rating ?? '',\n review_count: result.reviewCount ?? '',\n category: result.category ?? '',\n address: result.address ?? '',\n phone: result.phone ?? '',\n website_url: result.websiteUrl ?? '',\n place_url: result.placeUrl ?? '',\n cid: result.cid ?? '',\n cid_decimal: result.cidDecimal ?? '',\n result_status: 'ok',\n error: '',\n }))\n}\n\nfunction marketRows(rows: Array<Record<string, unknown>>): Array<Record<string, unknown>> {\n const byLocation = new Map<string, Array<Record<string, unknown>>>()\n for (const row of rows) {\n const key = String(row.source_location ?? row.location ?? '')\n if (!key) continue\n const list = byLocation.get(key) ?? []\n list.push(row)\n byLocation.set(key, list)\n }\n return [...byLocation.entries()].map(([location, list]) => {\n const counts = list.map(row => numberFrom(row.review_count))\n const ratings = list.map(row => numberFrom(row.review_stars))\n const topThree = list.slice(0, 3).map(row => numberFrom(row.review_count)).filter((v): v is number => v !== null)\n const categories = new Map<string, number>()\n for (const row of list) {\n const category = String(row.category ?? '')\n if (category) categories.set(category, (categories.get(category) ?? 0) + 1)\n }\n return {\n source_location: location,\n result_count: list.filter(row => row.business_name).length,\n median_review_count: median(counts) ?? '',\n median_rating: median(ratings) ?? '',\n top_three_average_review_count: topThree.length ? Math.round(topThree.reduce((a, b) => a + b, 0) / topThree.length) : '',\n top_categories: [...categories.entries()].sort((a, b) => b[1] - a[1]).slice(0, 5).map(([cat, count]) => `${cat} (${count})`).join('; '),\n websites_present: list.filter(row => row.website_url).length,\n }\n })\n}\n\nfunction comparisonRows(rows: Array<Record<string, unknown>>): Array<Record<string, unknown>> {\n const benchmarkByLocation = new Map<string, number>()\n for (const market of marketRows(rows)) {\n benchmarkByLocation.set(String(market.source_location), numberFrom(market.top_three_average_review_count) ?? 0)\n }\n return rows\n .filter(row => row.business_name)\n .map(row => {\n const reviews = numberFrom(row.review_count) ?? 0\n const benchmark = benchmarkByLocation.get(String(row.source_location)) ?? 0\n const websiteMissing = !row.website_url\n const rank = numberFrom(row.result_position) ?? 999\n return {\n source_location: row.source_location,\n result_position: row.result_position,\n business_name: row.business_name,\n category: row.category,\n review_stars: row.review_stars,\n review_count: row.review_count,\n review_gap_to_top3_average: benchmark ? Math.max(0, benchmark - reviews) : '',\n website_url: row.website_url,\n place_url: row.place_url,\n comparison_note: rank <= 3 ? 'visible leader' : websiteMissing ? 'ranking without website' : reviews < benchmark ? 'review-light competitor' : 'visible competitor',\n }\n })\n}\n\nfunction organicRows(serp: HarvestLike | null, targetDomain: string | null): Array<Record<string, unknown>> {\n return (serp?.organicResults ?? []).map(result => {\n const url = result.url ?? ''\n const domain = normalizeDomain(result.domain ?? '') ?? domainFromUrl(url)\n return {\n position: result.position ?? '',\n title: result.title ?? '',\n url,\n domain,\n snippet: result.snippet ?? '',\n is_target: targetDomain ? domain === targetDomain : false,\n }\n })\n}\n\nfunction pageGapRows(targetPage: ExtractUrlResult | null, competitorPages: Array<{ source: OrganicResult; page: ExtractUrlResult }>): Array<Record<string, unknown>> {\n const targetHeadingText = new Set((targetPage?.headings ?? []).map(h => h.text.toLowerCase().replace(/[^a-z0-9\\s]/g, ' ').trim()))\n const targetTerms = new Set((targetPage?.headings ?? []).flatMap(h => h.text.toLowerCase().replace(/[^a-z0-9\\s]/g, ' ').split(/\\s+/).filter(Boolean)))\n const rows: Array<Record<string, unknown>> = []\n for (const { source, page } of competitorPages) {\n for (const heading of page.headings ?? []) {\n if (heading.level > 3 || !heading.text) continue\n const normalized = heading.text.toLowerCase().replace(/[^a-z0-9\\s]/g, ' ').trim()\n const terms = normalized.split(/\\s+/).filter(term => term.length > 3)\n const overlap = terms.filter(term => targetTerms.has(term)).length\n const covered = targetHeadingText.has(normalized) || overlap >= Math.max(2, Math.ceil(terms.length / 2))\n if (covered && targetPage) continue\n rows.push({\n source_position: source.position ?? '',\n source_domain: normalizeDomain(source.domain ?? '') ?? domainFromUrl(source.url),\n source_url: source.url ?? '',\n heading_level: heading.level,\n competitor_heading: heading.text,\n target_coverage: targetPage ? 'not found in target headings' : 'no target page extracted',\n terms: textTerms(heading.text, 6),\n })\n }\n }\n return rows.slice(0, 150)\n}\n\nasync function extractPages(ctx: WorkflowRunContext, sources: OrganicResult[], warnings: string[], labelPrefix: string): Promise<Array<{ source: OrganicResult; page: ExtractUrlResult }>> {\n return mapLimit(sources.filter(source => source.url), 2, async (source, index) => {\n try {\n const page = await ctx.client.post<ExtractUrlResult>('/extract-url', { url: source.url }, 180_000)\n await ctx.artifacts.writeJson(`${labelPrefix} ${index + 1}`, `raw/extract-url/${labelPrefix.toLowerCase()}-${index + 1}.json`, page)\n return { source, page }\n } catch (err) {\n warnings.push(`Page extraction failed for ${source.url}: ${err instanceof Error ? err.message : String(err)}`)\n return null\n }\n }).then(items => items.filter((item): item is { source: OrganicResult; page: ExtractUrlResult } => item !== null))\n}\n\nexport const mapComparisonWorkflowDefinition: WorkflowDefinition<MapComparisonInput> = {\n id: 'map-comparison',\n title: 'Maps Comparison',\n description: 'Compare Google Maps competitors by rank, reviews, stars, categories, websites, and profile/review signals.',\n inputSchema: MapComparisonInputSchema,\n async run(input: MapComparisonInput, ctx: WorkflowRunContext): Promise<WorkflowRunSummary> {\n await ctx.artifacts.writeManifest('running', {}, [], [])\n const warnings: string[] = []\n let rows: Array<Record<string, unknown>>\n let directory: DirectoryWorkflowApiResult | null = null\n let mapsSearch: MapsSearchResultLike | null = null\n\n if (input.location) {\n mapsSearch = await ctx.client.post<MapsSearchResultLike>('/maps/search', {\n query: input.query,\n location: input.location,\n maxResults: input.maxResultsPerCity,\n proxyMode: input.proxyMode,\n }, 240_000)\n rows = businessRowsFromMaps(input.location, input.query, mapsSearch.results)\n await ctx.artifacts.writeJson('Maps search raw JSON', 'raw/maps-search.json', mapsSearch)\n } else {\n directory = await ctx.client.post<DirectoryWorkflowApiResult>('/directory/run', {\n query: input.query,\n state: input.state,\n minPopulation: input.minPopulation,\n maxCities: input.maxCities,\n maxResultsPerCity: input.maxResultsPerCity,\n concurrency: input.concurrency,\n proxyMode: input.proxyMode,\n saveCsv: true,\n }, 900_000)\n rows = directoryRows(directory)\n await ctx.artifacts.writeJson('Directory raw JSON', 'raw/directory-workflow.json', directory)\n await ctx.artifacts.writeCsv('Directory CSV', 'exports/directory.csv', DIRECTORY_CSV_HEADERS, rows)\n warnings.push(...directory.warnings)\n }\n\n const compareRows = comparisonRows(rows)\n const selected = compareRows.slice(0, input.hydrateTop * Math.max(1, input.location ? 1 : input.maxCities))\n const hydrated = await mapLimit(selected, 3, async (row, index) => {\n try {\n const detail = await ctx.client.post<MapsPlaceIntelResult>('/maps/place', {\n businessName: row.business_name,\n location: row.source_location,\n includeReviews: input.maxReviews > 0,\n maxReviews: Math.max(1, input.maxReviews),\n }, 180_000)\n await ctx.artifacts.writeJson(`${row.business_name} profile`, `raw/maps-place-intel/${index + 1}-${String(row.business_name).toLowerCase().replace(/[^a-z0-9]+/g, '-')}.json`, detail)\n return { row, detail, error: '' }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n warnings.push(`Profile hydration failed for ${row.business_name}: ${message}`)\n return { row, detail: null, error: message }\n }\n })\n\n const profileRows = hydrated.map(({ row, detail, error }) => ({\n source_location: row.source_location,\n result_position: row.result_position,\n business_name: row.business_name,\n category: detail?.category ?? row.category,\n review_stars: detail?.rating ?? row.review_stars,\n review_count: detail?.reviewCount ?? row.review_count,\n website_url: detail?.website ?? row.website_url,\n review_topics: (detail?.reviewTopics ?? []).map(t => `${t.label} (${t.count})`).join('; '),\n about_attributes: (detail?.aboutAttributes ?? []).map(a => `${a.section}: ${a.attribute}`).join('; '),\n reviews_status: detail?.reviewsStatus ?? '',\n error,\n }))\n const markets = marketRows(rows)\n await ctx.artifacts.writeCsv('Maps results CSV', 'maps-results.csv', ['source_query', 'source_location', 'city', 'state', 'population', 'result_position', 'business_name', 'review_stars', 'review_count', 'category', 'address', 'phone', 'website_url', 'place_url', 'cid', 'cid_decimal', 'result_status', 'error'], rows)\n await ctx.artifacts.writeCsv('Comparison CSV', 'map-comparison.csv', ['source_location', 'result_position', 'business_name', 'category', 'review_stars', 'review_count', 'review_gap_to_top3_average', 'website_url', 'place_url', 'comparison_note'], compareRows)\n await ctx.artifacts.writeCsv('Profile insights CSV', 'profile-insights.csv', ['source_location', 'result_position', 'business_name', 'category', 'review_stars', 'review_count', 'website_url', 'review_topics', 'about_attributes', 'reviews_status', 'error'], profileRows)\n await ctx.artifacts.writeJson('Maps comparison evidence', 'evidence.json', { input, directory, mapsSearch, rows, compareRows, profileRows, markets, warnings })\n await ctx.artifacts.writeText('Brief', 'brief.md', [\n `# Maps Comparison: ${input.query}`,\n '',\n `Markets: ${markets.map(row => row.source_location).join(', ')}`,\n '',\n '## How to Use',\n '- Compare rank position against review count and category patterns.',\n '- Treat review gaps and missing websites as opportunity signals, not guarantees.',\n '- Use profile topics and attributes as evidence for local content and GBP improvements.',\n ].join('\\n'))\n\n const summary = `${compareRows.length} Maps competitors compared across ${markets.length} market(s); ${profileRows.filter(row => !row.error).length} profiles hydrated.`\n const reportPath = await ctx.artifacts.writeHtml('HTML report', 'report.html', renderWorkflowReport({\n title: 'Maps Comparison',\n subtitle: `${input.query}${input.location ? ` · ${input.location}` : input.state ? ` · ${input.state}` : ''}`,\n summary,\n warnings,\n tables: [\n { title: 'Market Benchmarks', columns: ['source_location', 'result_count', 'median_review_count', 'median_rating', 'top_three_average_review_count', 'top_categories', 'websites_present'], rows: markets },\n { title: 'Competitor Comparison', columns: ['source_location', 'result_position', 'business_name', 'category', 'review_stars', 'review_count', 'review_gap_to_top3_average', 'comparison_note'], rows: compareRows.slice(0, 120) },\n { title: 'Profile Insights', columns: ['source_location', 'business_name', 'review_topics', 'about_attributes', 'error'], rows: profileRows },\n ],\n }))\n const status = warnings.length ? 'partial' : 'succeeded'\n const counts = { markets: markets.length, competitors: compareRows.length, hydratedProfiles: profileRows.filter(row => !row.error).length }\n await ctx.artifacts.writeManifest(status, counts, warnings, [])\n return { title: 'Maps Comparison', summary, status, counts, warnings, errors: [], reportPath }\n },\n}\n\nexport const serpComparisonWorkflowDefinition: WorkflowDefinition<SerpComparisonInput> = {\n id: 'serp-comparison',\n title: 'SERP Comparison',\n description: 'Compare ranking pages, SERP features, PAA evidence, AI Overview citations, and page-level content gaps.',\n inputSchema: SerpComparisonInputSchema,\n async run(input: SerpComparisonInput, ctx: WorkflowRunContext): Promise<WorkflowRunSummary> {\n await ctx.artifacts.writeManifest('running', {}, [], [])\n const warnings: string[] = []\n const targetDomain = normalizeDomain(input.domain ?? input.url ?? null)\n const serp = await ctx.client.post<HarvestLike>('/harvest/sync', {\n query: input.keyword,\n location: input.location,\n serpOnly: true,\n maxQuestions: 1,\n format: 'json',\n }, 180_000)\n await ctx.artifacts.writeJson('SERP raw JSON', 'raw/serp.json', serp)\n\n let paa: HarvestLike | null = null\n if (input.includePaa) {\n try {\n paa = await ctx.client.post<HarvestLike>('/harvest/sync', {\n query: input.keyword,\n location: input.location,\n maxQuestions: input.maxQuestions,\n format: 'json',\n }, 280_000)\n await ctx.artifacts.writeJson('PAA raw JSON', 'raw/paa.json', paa)\n } catch (err) {\n warnings.push(`PAA evidence unavailable: ${err instanceof Error ? err.message : String(err)}`)\n }\n }\n\n const organic = organicRows(serp, targetDomain).slice(0, input.maxResults)\n const organicSources = (serp.organicResults ?? []).slice(0, input.maxResults)\n const targetSource = input.url\n ? { position: 0, title: 'Target page', url: input.url, domain: domainFromUrl(input.url) }\n : organicSources.find(result => targetDomain && (normalizeDomain(result.domain ?? '') ?? domainFromUrl(result.url)) === targetDomain)\n const competitorSources = organicSources\n .filter(result => result.url && result.url !== targetSource?.url)\n .filter(result => !targetDomain || (normalizeDomain(result.domain ?? '') ?? domainFromUrl(result.url)) !== targetDomain)\n .slice(0, input.extractTop)\n\n const targetPages = targetSource ? await extractPages(ctx, [targetSource], warnings, 'Target') : []\n const competitorPages = input.extractTop > 0 ? await extractPages(ctx, competitorSources, warnings, 'Competitor') : []\n const targetPage = targetPages[0]?.page ?? null\n const pageRows = [\n ...targetPages.map(({ source, page }) => pageSummaryRow(page, { url: source.url ?? '', domain: normalizeDomain(source.domain ?? '') ?? domainFromUrl(source.url), position: source.position, title: source.title })),\n ...competitorPages.map(({ source, page }) => pageSummaryRow(page, { url: source.url ?? '', domain: normalizeDomain(source.domain ?? '') ?? domainFromUrl(source.url), position: source.position, title: source.title })),\n ]\n const gaps = pageGapRows(targetPage, competitorPages)\n const questions = questionRows(paa)\n const aiRows = (serp.aiOverview?.citations ?? []).map((citation, index) => ({\n citation_position: index + 1,\n citation_text: citation.text ?? '',\n url: citation.href ?? '',\n domain: domainFromUrl(citation.href ?? ''),\n is_target: targetDomain ? domainFromUrl(citation.href ?? '') === targetDomain : false,\n }))\n await ctx.artifacts.writeCsv('Organic results CSV', 'organic-results.csv', ['position', 'title', 'url', 'domain', 'snippet', 'is_target'], organic)\n await ctx.artifacts.writeCsv('Page comparison CSV', 'page-comparison.csv', ['position', 'domain', 'url', 'serp_title', 'page_title', 'h1', 'meta_description', 'word_count', 'heading_count', 'schema_types'], pageRows)\n await ctx.artifacts.writeCsv('Content gaps CSV', 'content-gaps.csv', ['source_position', 'source_domain', 'source_url', 'heading_level', 'competitor_heading', 'target_coverage', 'terms'], gaps)\n await ctx.artifacts.writeCsv('PAA questions CSV', 'paa-questions.csv', ['position', 'intent', 'question', 'answer_excerpt', 'source_title', 'source_domain', 'source_url'], questions)\n await ctx.artifacts.writeCsv('AI Overview citations CSV', 'ai-overview-citations.csv', ['citation_position', 'citation_text', 'url', 'domain', 'is_target'], aiRows)\n await ctx.artifacts.writeJson('SERP comparison evidence', 'evidence.json', { input, serp, paa, organic, pageRows, gaps, questions, aiRows, warnings })\n await ctx.artifacts.writeText('Writer brief', 'brief.md', [\n `# SERP Comparison Brief: ${input.keyword}`,\n '',\n `Target: ${targetDomain ?? input.url ?? 'not specified'}`,\n `Location: ${input.location ?? 'not specified'}`,\n '',\n '## Recommended Actions',\n '- Use `content-gaps.csv` to decide which missing sections deserve coverage.',\n '- Use `paa-questions.csv` for FAQ and answer-block candidates.',\n '- Use `ai-overview-citations.csv` to see whether the target is cited in AI Overview evidence.',\n '- Treat extracted page headings as evidence, not a complete semantic analysis.',\n ].join('\\n'))\n const summary = `${organic.length} organic results, ${pageRows.length} extracted pages, ${gaps.length} heading gaps, ${questions.length} PAA questions.`\n const reportPath = await ctx.artifacts.writeHtml('HTML report', 'report.html', renderWorkflowReport({\n title: 'SERP Comparison',\n subtitle: `${input.keyword}${input.location ? ` · ${input.location}` : ''}`,\n summary,\n warnings,\n tables: [\n { title: 'Organic Results', columns: ['position', 'title', 'domain', 'is_target'], rows: organic },\n { title: 'Page Comparison', columns: ['position', 'domain', 'h1', 'word_count', 'heading_count', 'schema_types'], rows: pageRows },\n { title: 'Content Gaps', columns: ['source_position', 'source_domain', 'competitor_heading', 'target_coverage', 'terms'], rows: gaps.slice(0, 80) },\n { title: 'PAA Questions', columns: ['position', 'intent', 'question', 'source_domain'], rows: questions.slice(0, 80) },\n ],\n }))\n const status = warnings.length ? 'partial' : 'succeeded'\n const counts = { organic: organic.length, pages: pageRows.length, gaps: gaps.length, questions: questions.length, aiCitations: aiRows.length }\n await ctx.artifacts.writeManifest(status, counts, warnings, [])\n return { title: 'SERP Comparison', summary, status, counts, warnings, errors: [], reportPath }\n },\n}\n\nexport const paaExpansionBriefWorkflowDefinition: WorkflowDefinition<PaaExpansionBriefInput> = {\n id: 'paa-expansion-brief',\n title: 'PAA Expansion Brief',\n description: 'Expand People Also Ask questions into an evidence-backed writer brief, section map, and source table.',\n inputSchema: PaaExpansionBriefInputSchema,\n async run(input: PaaExpansionBriefInput, ctx: WorkflowRunContext): Promise<WorkflowRunSummary> {\n await ctx.artifacts.writeManifest('running', {}, [], [])\n const warnings: string[] = []\n const paa = await ctx.client.post<HarvestLike>('/harvest/sync', {\n query: input.keyword,\n location: input.location,\n maxQuestions: input.maxQuestions,\n depth: input.depth,\n format: 'json',\n }, 300_000)\n await ctx.artifacts.writeJson('PAA raw JSON', 'raw/paa.json', paa)\n const questions = questionRows(paa)\n const sourceRows = sourceDomainRows(questions)\n const byIntent = new Map<string, Array<Record<string, unknown>>>()\n for (const row of questions) {\n const list = byIntent.get(String(row.intent)) ?? []\n list.push(row)\n byIntent.set(String(row.intent), list)\n }\n const sectionRows = [...byIntent.entries()].map(([intent, rows]) => ({\n recommended_section: intent,\n question_count: rows.length,\n sample_questions: rows.slice(0, 5).map(row => row.question).join(' | '),\n source_domains: [...new Set(rows.map(row => row.source_domain).filter(Boolean))].slice(0, 5).join('; '),\n terms: textTerms(rows.map(row => `${row.question} ${row.answer_excerpt}`).join(' '), 10),\n })).sort((a, b) => Number(b.question_count) - Number(a.question_count))\n\n await ctx.artifacts.writeCsv('PAA questions CSV', 'paa-questions.csv', ['position', 'intent', 'question', 'answer_excerpt', 'source_title', 'source_domain', 'source_url'], questions)\n await ctx.artifacts.writeCsv('Source domains CSV', 'source-domains.csv', ['domain', 'question_mentions', 'source_url_count', 'top_intents'], sourceRows)\n await ctx.artifacts.writeCsv('Section map CSV', 'section-map.csv', ['recommended_section', 'question_count', 'sample_questions', 'source_domains', 'terms'], sectionRows)\n await ctx.artifacts.writeJson('PAA brief evidence', 'evidence.json', { input, paa, questions, sourceRows, sectionRows })\n await ctx.artifacts.writeText('Writer brief', 'writer-brief.md', [\n `# PAA Expansion Brief: ${input.keyword}`,\n '',\n `Location: ${input.location ?? 'not specified'}`,\n '',\n '## Suggested Page Structure',\n ...sectionRows.map(row => `- ${row.recommended_section}: answer ${row.question_count} related question(s). Sample: ${row.sample_questions}`),\n '',\n '## Writing Rules',\n '- Answer the highest-frequency question in the first 60 words of each section.',\n '- Use exact customer question language from `paa-questions.csv` for H2/H3 candidates.',\n '- Use `source-domains.csv` to identify which source types Google is already rewarding.',\n '- Do not invent citations; cite only rows that have a source URL.',\n ].join('\\n'))\n const summary = `${questions.length} PAA questions grouped into ${sectionRows.length} writing sections.`\n const reportPath = await ctx.artifacts.writeHtml('HTML report', 'report.html', renderWorkflowReport({\n title: 'PAA Expansion Brief',\n subtitle: `${input.keyword}${input.location ? ` · ${input.location}` : ''}`,\n summary,\n warnings,\n tables: [\n { title: 'Section Map', columns: ['recommended_section', 'question_count', 'sample_questions', 'source_domains', 'terms'], rows: sectionRows },\n { title: 'Questions', columns: ['position', 'intent', 'question', 'source_domain'], rows: questions.slice(0, 120) },\n { title: 'Source Domains', columns: ['domain', 'question_mentions', 'source_url_count', 'top_intents'], rows: sourceRows },\n ],\n }))\n const counts = { questions: questions.length, sections: sectionRows.length, sourceDomains: sourceRows.length }\n await ctx.artifacts.writeManifest('succeeded', counts, warnings, [])\n return { title: 'PAA Expansion Brief', summary, status: 'succeeded', counts, warnings, errors: [], reportPath }\n },\n}\n\nexport const aiOverviewLanguageWorkflowDefinition: WorkflowDefinition<AiOverviewLanguageInput> = {\n id: 'ai-overview-language',\n title: 'AI Overview Language Brief',\n description: 'Turn AI Overview, citation, PAA, and ranking-page evidence into answer-block and citation-hook guidance.',\n inputSchema: AiOverviewLanguageInputSchema,\n async run(input: AiOverviewLanguageInput, ctx: WorkflowRunContext): Promise<WorkflowRunSummary> {\n await ctx.artifacts.writeManifest('running', {}, [], [])\n const warnings: string[] = []\n const targetDomain = normalizeDomain(input.domain ?? input.url ?? null)\n const serp = await ctx.client.post<HarvestLike>('/harvest/sync', {\n query: input.keyword,\n location: input.location,\n serpOnly: true,\n maxQuestions: 1,\n format: 'json',\n }, 180_000)\n await ctx.artifacts.writeJson('SERP raw JSON', 'raw/serp.json', serp)\n let paa: HarvestLike | null = null\n try {\n paa = await ctx.client.post<HarvestLike>('/harvest/sync', {\n query: input.keyword,\n location: input.location,\n maxQuestions: input.maxQuestions,\n format: 'json',\n }, 280_000)\n await ctx.artifacts.writeJson('PAA raw JSON', 'raw/paa.json', paa)\n } catch (err) {\n warnings.push(`PAA evidence unavailable: ${err instanceof Error ? err.message : String(err)}`)\n }\n\n const citations = (serp.aiOverview?.citations ?? []).map((citation, index) => {\n const domain = domainFromUrl(citation.href ?? '')\n return {\n citation_position: index + 1,\n citation_text: citation.text ?? '',\n url: citation.href ?? '',\n domain,\n is_target: targetDomain ? domain === targetDomain : false,\n }\n })\n const aioSentences = splitSentences(serp.aiOverview?.text)\n const claimRows = aioSentences.map((sentence, index) => ({\n position: index + 1,\n claim_type: classifySentence(sentence),\n sentence,\n reusable_pattern: sentence.length > 140 ? `${sentence.slice(0, 140)}...` : sentence,\n }))\n const questions = questionRows(paa)\n const citationSources = (serp.aiOverview?.citations ?? [])\n .filter(citation => citation.href)\n .map((citation, index) => ({ position: index + 1, title: citation.text, url: citation.href, domain: domainFromUrl(citation.href) }))\n .slice(0, input.extractTop)\n const extractedCitations = input.extractTop > 0 ? await extractPages(ctx, citationSources, warnings, 'Citation') : []\n const extractedRows = extractedCitations.map(({ source, page }) => pageSummaryRow(page, { url: source.url ?? '', domain: normalizeDomain(source.domain ?? '') ?? domainFromUrl(source.url), position: source.position, title: source.title }))\n const languageRows = [\n {\n block: 'direct_answer',\n guidance: 'Open with a 40-70 word answer that directly resolves the query before adding context.',\n evidence_basis: questions[0]?.question ?? input.keyword,\n },\n {\n block: 'criteria_or_steps',\n guidance: 'List the criteria, steps, or decision factors Google is already compressing into AI Overview language.',\n evidence_basis: claimRows.filter(row => ['criteria', 'process'].includes(String(row.claim_type))).map(row => row.sentence).slice(0, 3).join(' | '),\n },\n {\n block: 'citation_hook',\n guidance: 'Add source-worthy details competitors can cite: definitions, numbers, examples, process details, and named entity relationships.',\n evidence_basis: citations.map(row => `${row.domain}: ${row.citation_text}`).slice(0, 5).join(' | '),\n },\n {\n block: 'faq_followups',\n guidance: 'Use PAA phrasing for follow-up sections so the page answers adjacent questions in Google language.',\n evidence_basis: questions.slice(0, 5).map(row => row.question).join(' | '),\n },\n ]\n await ctx.artifacts.writeCsv('AI Overview citations CSV', 'ai-overview-citations.csv', ['citation_position', 'citation_text', 'url', 'domain', 'is_target'], citations)\n await ctx.artifacts.writeCsv('AI Overview claim patterns CSV', 'claim-patterns.csv', ['position', 'claim_type', 'sentence', 'reusable_pattern'], claimRows)\n await ctx.artifacts.writeCsv('Language guidance CSV', 'language-guidance.csv', ['block', 'guidance', 'evidence_basis'], languageRows)\n await ctx.artifacts.writeCsv('PAA questions CSV', 'paa-questions.csv', ['position', 'intent', 'question', 'answer_excerpt', 'source_title', 'source_domain', 'source_url'], questions)\n await ctx.artifacts.writeCsv('Extracted citation pages CSV', 'citation-pages.csv', ['position', 'domain', 'url', 'serp_title', 'page_title', 'h1', 'meta_description', 'word_count', 'heading_count', 'schema_types'], extractedRows)\n await ctx.artifacts.writeJson('AI Overview language evidence', 'evidence.json', { input, serp, paa, citations, claimRows, languageRows, extractedRows, warnings })\n await ctx.artifacts.writeText('Answer block template', 'answer-block-template.md', [\n `# AI Overview Language Brief: ${input.keyword}`,\n '',\n `AI Overview detected: ${serp.aiOverview?.detected ? 'yes' : 'no'}`,\n `Target cited: ${targetDomain ? citations.some(row => row.is_target) ? 'yes' : 'no' : 'target not specified'}`,\n '',\n '## Direct Answer Block',\n 'Write one compact answer block that starts with the answer, not background. Keep it clear enough that Google could lift it as a standalone summary.',\n '',\n '## Suggested Follow-Up Blocks',\n ...languageRows.map(row => `- ${row.block}: ${row.guidance}`),\n '',\n '## Evidence to Mirror',\n ...claimRows.slice(0, 8).map(row => `- ${row.claim_type}: ${row.sentence}`),\n '',\n '## Citation Hooks',\n ...citations.slice(0, 8).map(row => `- ${row.domain}: ${row.citation_text}`),\n ].join('\\n'))\n const summary = `${citations.length} AI Overview citations, ${claimRows.length} claim patterns, ${questions.length} PAA questions, ${extractedRows.length} citation pages extracted.`\n const reportPath = await ctx.artifacts.writeHtml('HTML report', 'report.html', renderWorkflowReport({\n title: 'AI Overview Language Brief',\n subtitle: `${input.keyword}${input.location ? ` · ${input.location}` : ''}`,\n summary,\n warnings,\n tables: [\n { title: 'Language Guidance', columns: ['block', 'guidance', 'evidence_basis'], rows: languageRows },\n { title: 'AI Overview Citations', columns: ['citation_position', 'citation_text', 'domain', 'is_target'], rows: citations },\n { title: 'Claim Patterns', columns: ['position', 'claim_type', 'sentence'], rows: claimRows },\n { title: 'PAA Follow-Ups', columns: ['position', 'intent', 'question', 'source_domain'], rows: questions.slice(0, 60) },\n ],\n }))\n const status = warnings.length || !serp.aiOverview?.detected ? 'partial' : 'succeeded'\n const counts = { citations: citations.length, claimPatterns: claimRows.length, questions: questions.length, extractedCitationPages: extractedRows.length }\n await ctx.artifacts.writeManifest(status, counts, warnings, [])\n return { title: 'AI Overview Language Brief', summary, status, counts, warnings, errors: [], reportPath }\n },\n}\n","export interface OrganicResult {\n position?: number\n title?: string\n url?: string\n domain?: string\n snippet?: string | null\n}\n\nexport interface PaaFlatRow {\n question?: string\n answer?: string | null\n source_title?: string | null\n source_site?: string | null\n source_cite?: string | null\n}\n\nexport interface HarvestLike {\n organicResults?: OrganicResult[]\n localPack?: Array<{ position?: number; name?: string; rating?: string | null; reviewCount?: string | null; websiteUrl?: string | null }>\n flat?: PaaFlatRow[]\n aiOverview?: { detected?: boolean; text?: string | null; citations?: Array<{ text?: string; href?: string }> }\n forumResults?: Array<{ title?: string; source?: string; url?: string }>\n videoResults?: Array<{ title?: string; channel?: string; platform?: string; url?: string }>\n}\n\nexport interface ExtractUrlResult {\n url?: string\n canonicalUrl?: string | null\n title?: string | null\n metaDescription?: string | null\n h1?: string | null\n headings?: Array<{ level: number; text: string }>\n wordCount?: number\n schemaTypes?: string[]\n bodyMarkdown?: string\n}\n\nexport interface MapsSearchBusinessLike {\n position: number\n name: string\n rating?: string | null\n reviewCount?: string | null\n category?: string | null\n address?: string | null\n phone?: string | null\n websiteUrl?: string | null\n placeUrl?: string\n cid?: string | null\n cidDecimal?: string | null\n hoursStatus?: string | null\n}\n\nexport interface MapsSearchResultLike {\n query: string\n location?: string | null\n searchQuery?: string\n resultCount: number\n results: MapsSearchBusinessLike[]\n}\n\nconst STOP_WORDS = new Set([\n 'about', 'after', 'also', 'because', 'been', 'best', 'both', 'from', 'have', 'into',\n 'more', 'most', 'near', 'only', 'over', 'than', 'that', 'their', 'them', 'then',\n 'there', 'these', 'they', 'this', 'what', 'when', 'where', 'which', 'while', 'with',\n 'your', 'will', 'would', 'should', 'could', 'does', 'were', 'cost', 'costs',\n])\n\nexport function normalizeDomain(value?: string | null): string | null {\n if (!value) return null\n try {\n const url = new URL(value.includes('://') ? value : `https://${value}`)\n return url.hostname.replace(/^www\\./, '').toLowerCase()\n } catch {\n return value.replace(/^https?:\\/\\//, '').replace(/^www\\./, '').split('/')[0]?.toLowerCase() || null\n }\n}\n\nexport function domainFromUrl(url?: string | null): string {\n return normalizeDomain(url) ?? ''\n}\n\nexport function numberFrom(value: unknown): number | null {\n if (value === null || value === undefined || value === '') return null\n const parsed = Number(String(value).replace(/[^\\d.]/g, ''))\n return Number.isFinite(parsed) ? parsed : null\n}\n\nexport function median(values: Array<number | null>): number | null {\n const nums = values.filter((v): v is number => v !== null).sort((a, b) => a - b)\n if (!nums.length) return null\n return nums[Math.floor(nums.length / 2)] ?? null\n}\n\nexport function textTerms(text: string, limit = 12): string {\n const counts = new Map<string, number>()\n for (const token of text.toLowerCase().replace(/[^a-z0-9\\s]/g, ' ').split(/\\s+/)) {\n if (token.length < 4 || STOP_WORDS.has(token)) continue\n counts.set(token, (counts.get(token) ?? 0) + 1)\n }\n return [...counts.entries()]\n .sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0]))\n .slice(0, limit)\n .map(([term, count]) => `${term} (${count})`)\n .join('; ')\n}\n\nexport function classifyQuestion(question: string): string {\n const q = question.toLowerCase()\n if (/\\b(cost|price|pricing|charge|expensive|cheap)\\b/.test(q)) return 'cost'\n if (/\\b(best|top|recommended|reviews?|compare|versus|vs)\\b/.test(q)) return 'comparison'\n if (/\\b(how|steps?|process|way to)\\b/.test(q)) return 'process'\n if (/\\b(why|worth|important|benefit)\\b/.test(q)) return 'why'\n if (/\\b(near me|city|local|nearby)\\b/.test(q)) return 'local'\n if (/\\b(can|does|do|is|are|should|will)\\b/.test(q)) return 'decision'\n return 'definition'\n}\n\nexport function questionRows(paa: HarvestLike | null): Array<Record<string, unknown>> {\n return (paa?.flat ?? [])\n .filter(row => row.question)\n .map((row, index) => {\n const url = row.source_cite ?? ''\n const domain = normalizeDomain(row.source_site ?? '') ?? domainFromUrl(url)\n return {\n position: index + 1,\n intent: classifyQuestion(row.question ?? ''),\n question: row.question ?? '',\n answer_excerpt: (row.answer ?? '').slice(0, 320),\n source_title: row.source_title ?? '',\n source_domain: domain,\n source_url: url,\n }\n })\n}\n\nexport function sourceDomainRows(rows: Array<Record<string, unknown>>): Array<Record<string, unknown>> {\n const byDomain = new Map<string, { questions: number; urls: Set<string>; intents: Map<string, number> }>()\n for (const row of rows) {\n const domain = String(row.source_domain ?? row.domain ?? '')\n if (!domain) continue\n const entry = byDomain.get(domain) ?? { questions: 0, urls: new Set<string>(), intents: new Map<string, number>() }\n entry.questions += row.question ? 1 : 0\n if (row.source_url || row.url) entry.urls.add(String(row.source_url ?? row.url))\n if (row.intent) entry.intents.set(String(row.intent), (entry.intents.get(String(row.intent)) ?? 0) + 1)\n byDomain.set(domain, entry)\n }\n return [...byDomain.entries()]\n .map(([domain, entry]) => ({\n domain,\n question_mentions: entry.questions,\n source_url_count: entry.urls.size,\n top_intents: [...entry.intents.entries()].sort((a, b) => b[1] - a[1]).map(([intent, count]) => `${intent} (${count})`).join('; '),\n }))\n .sort((a, b) => Number(b.question_mentions) - Number(a.question_mentions) || String(a.domain).localeCompare(String(b.domain)))\n}\n\nexport function splitSentences(text?: string | null): string[] {\n return (text ?? '')\n .replace(/\\s+/g, ' ')\n .split(/(?<=[.!?])\\s+/)\n .map(sentence => sentence.trim())\n .filter(sentence => sentence.length > 20)\n .slice(0, 20)\n}\n\nexport function classifySentence(sentence: string): string {\n const s = sentence.toLowerCase()\n if (/\\bis\\b|\\bare\\b|\\bmeans\\b|\\brefers to\\b/.test(s)) return 'definition'\n if (/\\binclude\\b|\\bconsider\\b|\\bfactors?\\b|\\bcriteria\\b/.test(s)) return 'criteria'\n if (/\\bfirst\\b|\\bthen\\b|\\bsteps?\\b|\\bprocess\\b/.test(s)) return 'process'\n if (/\\bvs\\b|\\bthan\\b|\\bcompare\\b|\\bdifference\\b/.test(s)) return 'comparison'\n if (/\\bcost\\b|\\bprice\\b|\\baverage\\b|\\brange\\b/.test(s)) return 'cost'\n return 'claim'\n}\n\nexport function headingRows(page: ExtractUrlResult, source: { url: string; domain: string; position?: number | string }): Array<Record<string, unknown>> {\n return (page.headings ?? [])\n .filter(heading => heading.text)\n .map(heading => ({\n source_url: source.url,\n source_domain: source.domain,\n source_position: source.position ?? '',\n heading_level: heading.level,\n heading_text: heading.text,\n heading_terms: textTerms(heading.text, 6),\n }))\n}\n\nexport function pageSummaryRow(page: ExtractUrlResult, source: { url: string; domain: string; position?: number | string; title?: string }): Record<string, unknown> {\n return {\n position: source.position ?? '',\n domain: source.domain,\n url: source.url,\n serp_title: source.title ?? '',\n page_title: page.title ?? '',\n h1: page.h1 ?? '',\n meta_description: page.metaDescription ?? '',\n word_count: page.wordCount ?? '',\n heading_count: page.headings?.length ?? 0,\n schema_types: (page.schemaTypes ?? []).join('; '),\n }\n}\n\nexport async function mapLimit<T, R>(items: T[], limit: number, fn: (item: T, index: number) => Promise<R>): Promise<R[]> {\n const out: R[] = new Array(items.length)\n let next = 0\n async function worker(): Promise<void> {\n while (next < items.length) {\n const index = next\n next += 1\n out[index] = await fn(items[index], index)\n }\n }\n await Promise.all(Array.from({ length: Math.min(Math.max(1, limit), items.length) }, () => worker()))\n return out\n}\n\n"],"mappings":";AAAA,SAAS,OAAO,UAAU,MAAM,iBAAiB;AACjD,SAAS,kBAAkB;AAC3B,SAAS,SAAS,gBAAgB;AAClC,SAAS,SAAS,YAAY;AAC9B,SAAS,gBAAgB;;;ACJlB,SAAS,SAAS,MAA0B;AACjD,QAAM,OAAmB,CAAC;AAC1B,MAAI,MAAgB,CAAC;AACrB,MAAI,QAAQ;AACZ,MAAI,SAAS;AAEb,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK,GAAG;AACvC,UAAM,KAAK,KAAK,CAAC;AACjB,UAAM,OAAO,KAAK,IAAI,CAAC;AAEvB,QAAI,QAAQ;AACV,UAAI,OAAO,OAAO,SAAS,KAAK;AAC9B,iBAAS;AACT,aAAK;AAAA,MACP,WAAW,OAAO,KAAK;AACrB,iBAAS;AAAA,MACX,OAAO;AACL,iBAAS;AAAA,MACX;AACA;AAAA,IACF;AAEA,QAAI,OAAO,KAAK;AACd,eAAS;AAAA,IACX,WAAW,OAAO,KAAK;AACrB,UAAI,KAAK,KAAK;AACd,cAAQ;AAAA,IACV,WAAW,OAAO,MAAM;AACtB,UAAI,KAAK,KAAK;AACd,WAAK,KAAK,GAAG;AACb,YAAM,CAAC;AACP,cAAQ;AAAA,IACV,WAAW,OAAO,MAAM;AACtB,eAAS;AAAA,IACX;AAAA,EACF;AAEA,MAAI,MAAM,SAAS,KAAK,IAAI,SAAS,GAAG;AACtC,QAAI,KAAK,KAAK;AACd,SAAK,KAAK,GAAG;AAAA,EACf;AAEA,SAAO;AACT;AAEO,SAAS,WAAW,MAA6C;AACtE,QAAM,OAAO,SAAS,IAAI,EAAE,OAAO,SAAO,IAAI,KAAK,UAAQ,KAAK,KAAK,MAAM,EAAE,CAAC;AAC9E,QAAM,SAAS,KAAK,CAAC,GAAG,IAAI,UAAQ,KAAK,KAAK,CAAC,KAAK,CAAC;AACrD,SAAO,KAAK,MAAM,CAAC,EAAE,IAAI,CAAC,QAAQ;AAChC,UAAM,SAAiC,CAAC;AACxC,aAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK,GAAG;AACzC,aAAO,OAAO,CAAC,CAAC,IAAI,IAAI,CAAC,KAAK;AAAA,IAChC;AACA,WAAO;AAAA,EACT,CAAC;AACH;AAEO,SAAS,QAAQ,OAAwB;AAC9C,MAAI,UAAU,QAAQ,UAAU,OAAW,QAAO;AAClD,QAAM,OAAO,OAAO,KAAK;AACzB,SAAO,WAAW,KAAK,IAAI,IAAI,IAAI,KAAK,QAAQ,MAAM,IAAI,CAAC,MAAM;AACnE;AAEO,SAAS,UAAU,SAAmB,MAA8C;AACzF,SAAO;AAAA,IACL,QAAQ,KAAK,GAAG;AAAA,IAChB,GAAG,KAAK,IAAI,SAAO,QAAQ,IAAI,YAAU,QAAQ,IAAI,MAAM,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC;AAAA,EAC1E,EAAE,KAAK,IAAI,IAAI;AACjB;;;ACpEO,SAAS,QAAQ,GAAmB;AACzC,SAAO,EAAE,YAAY,EAAE,QAAQ,QAAQ,GAAG,EAAE,QAAQ,eAAe,EAAE;AACvE;;;AFOO,SAAS,sBAAsB,WAA4B;AAChE,SAAO,WAAW,KAAK,KAAK,QAAQ,IAAI,wBAAwB,KAAK,KAAK,KAAK,QAAQ,GAAG,aAAa,aAAa;AACtH;AAEA,SAAS,YAAoB;AAC3B,UAAO,oBAAI,KAAK,GAAE,YAAY,EAAE,QAAQ,SAAS,GAAG;AACtD;AAEA,SAAS,SAAS,OAAuB;AACvC,SAAO,QAAQ,KAAK,EAAE,QAAQ,YAAY,EAAE,EAAE,MAAM,GAAG,EAAE,KAAK;AAChE;AAEO,IAAM,iBAAN,MAAM,gBAAe;AAAA,EAG1B,YACW,YACA,OACA,OACA,SACA,QACA,WACA,OACT;AAPS;AACA;AACA;AACA;AACA;AACA;AACA;AAAA,EACR;AAAA,EAPQ;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EATF,YAAgC,CAAC;AAAA,EAY1C,aAAa,OAAO,YAAoB,OAAe,OAAgC,WAAoB,aAA+C;AACxJ,UAAM,aAAY,oBAAI,KAAK,GAAE,YAAY;AACzC,UAAM,QAAQ,aAAa,KAAK,KAAK,GAAG,UAAU,CAAC,IAAI,SAAS,UAAU,CAAC,IAAI,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,GAAG,CAAC,CAAC;AACrH,UAAM,aAAa,OAAO,MAAM,WAAW,MAAM,SAAS,MAAM,UAAU,MAAM,SAAS,UAAU;AACnG,UAAM,UAAU,sBAAsB,SAAS;AAC/C,UAAM,SAAS,KAAK,SAAS,aAAa,YAAY,GAAG,UAAU,CAAC,IAAI,SAAS,UAAU,CAAC,IAAI,SAAS,KAAK,EAAE,MAAM,GAAG,EAAE,CAAC,EAAE;AAC9H,UAAM,MAAM,QAAQ,EAAE,WAAW,KAAK,CAAC;AACvC,WAAO,IAAI,gBAAe,YAAY,OAAO,OAAO,SAAS,QAAQ,WAAW,KAAK;AAAA,EACvF;AAAA,EAEA,MAAc,SAAS,MAAgC,OAAe,MAAc,MAAgC;AAClH,UAAM,OAAO,MAAM,KAAK,IAAI,EAAE,KAAK,OAAK,EAAE,IAAI,EAAE,MAAM,MAAM,MAAS;AACrE,SAAK,UAAU,KAAK,EAAE,MAAM,OAAO,MAAM,OAAO,MAAM,KAAK,CAAC;AAC5D,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,UAAU,OAAe,cAAsB,MAAgC;AACnF,UAAM,OAAO,KAAK,KAAK,QAAQ,YAAY;AAC3C,UAAM,MAAM,QAAQ,IAAI,GAAG,EAAE,WAAW,KAAK,CAAC;AAC9C,UAAM,UAAU,MAAM,KAAK,UAAU,MAAM,MAAM,CAAC,GAAG,MAAM;AAC3D,WAAO,KAAK,SAAS,QAAQ,OAAO,IAAI;AAAA,EAC1C;AAAA,EAEA,MAAM,UAAU,OAAe,cAAsB,MAAc,OAAiC,YAA6B;AAC/H,UAAM,OAAO,KAAK,KAAK,QAAQ,YAAY;AAC3C,UAAM,MAAM,QAAQ,IAAI,GAAG,EAAE,WAAW,KAAK,CAAC;AAC9C,UAAM,UAAU,MAAM,MAAM,MAAM;AAClC,WAAO,KAAK,SAAS,MAAM,OAAO,IAAI;AAAA,EACxC;AAAA,EAEA,MAAM,SAAS,OAAe,cAAsB,SAAmB,MAAuD;AAC5H,UAAM,OAAO,KAAK,KAAK,QAAQ,YAAY;AAC3C,UAAM,MAAM,QAAQ,IAAI,GAAG,EAAE,WAAW,KAAK,CAAC;AAC9C,UAAM,UAAU,MAAM,UAAU,SAAS,IAAI,GAAG,MAAM;AACtD,WAAO,KAAK,SAAS,OAAO,OAAO,MAAM,KAAK,MAAM;AAAA,EACtD;AAAA,EAEA,MAAM,UAAU,OAAe,cAAsB,MAA+B;AAClF,WAAO,KAAK,UAAU,OAAO,cAAc,MAAM,aAAa;AAAA,EAChE;AAAA,EAEA,MAAM,cAAc,QAAwB,QAAgC,UAAoB,QAAmC;AACjI,UAAM,WAA6B;AAAA,MACjC,UAAU,KAAK;AAAA,MACf,OAAO,KAAK;AAAA,MACZ,OAAO,KAAK;AAAA,MACZ;AAAA,MACA,WAAW,KAAK;AAAA,MAChB,aAAa,WAAW,YAAY,QAAO,oBAAI,KAAK,GAAE,YAAY;AAAA,MAClE,OAAO,KAAK;AAAA,MACZ,WAAW,KAAK;AAAA,MAChB;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,UAAM,OAAO,KAAK,KAAK,QAAQ,eAAe;AAC9C,UAAM,UAAU,MAAM,KAAK,UAAU,UAAU,MAAM,CAAC,GAAG,MAAM;AAC/D,UAAM,oBAAoB,UAAU,MAAM,KAAK,OAAO;AACtD,WAAO;AAAA,EACT;AACF;AAgBA,SAAS,UAAU,UAAU,sBAAsB,GAAW;AAC5D,SAAO,KAAK,SAAS,aAAa,YAAY;AAChD;AAEA,eAAe,UAAU,SAA0C;AACjE,QAAM,OAAO,UAAU,OAAO;AAC9B,MAAI,CAAC,WAAW,IAAI,EAAG,QAAO,EAAE,MAAM,CAAC,EAAE;AACzC,MAAI;AACF,WAAO,KAAK,MAAM,MAAM,SAAS,MAAM,MAAM,CAAC;AAAA,EAChD,QAAQ;AACN,WAAO,EAAE,MAAM,CAAC,EAAE;AAAA,EACpB;AACF;AAEA,eAAe,oBAAoB,UAA4B,cAAsB,SAAgC;AACnH,MAAI,SAAS,WAAW,UAAW;AACnC,QAAM,OAAO,UAAU,OAAO;AAC9B,QAAM,QAAQ,MAAM,UAAU,OAAO;AACrC,QAAM,SAAS,SAAS,UAAU,KAAK,OAAK,EAAE,SAAS,aAAa,GAAG,QAAQ;AAC/E,QAAM,QAA4B;AAAA,IAChC,UAAU,SAAS;AAAA,IACnB,OAAO,SAAS;AAAA,IAChB,QAAQ,SAAS;AAAA,IACjB,WAAW,SAAS;AAAA,IACpB,YAAY;AAAA,IACZ;AAAA,IACA,SAAS,GAAG,SAAS,KAAK,KAAK,SAAS,MAAM;AAAA,EAChD;AACA,QAAM,OAAO,CAAC,OAAO,GAAG,MAAM,KAAK,OAAO,OAAK,EAAE,UAAU,SAAS,KAAK,CAAC,EAAE,MAAM,GAAG,GAAG;AACxF,QAAM,MAAM,QAAQ,IAAI,GAAG,EAAE,WAAW,KAAK,CAAC;AAC9C,QAAM,UAAU,MAAM,KAAK,UAAU,OAAO,MAAM,CAAC,GAAG,MAAM;AAC9D;AAEA,eAAsB,oBAAoB,WAAmD;AAC3F,UAAQ,MAAM,UAAU,sBAAsB,SAAS,CAAC,GAAG;AAC7D;AAEA,eAAsB,mBAAmB,IAAY,WAAwD;AAC3G,QAAM,OAAO,MAAM,oBAAoB,SAAS;AAChD,MAAI,OAAO,OAAQ,QAAO,KAAK,CAAC,KAAK;AACrC,SAAO,KAAK,KAAK,SAAO,IAAI,UAAU,EAAE,KAAK;AAC/C;AAEA,eAAsB,mBAAmB,IAAY,WAAqC;AACxF,QAAM,MAAM,MAAM,mBAAmB,IAAI,SAAS;AAClD,MAAI,CAAC,KAAK,WAAY,OAAM,IAAI,MAAM,wBAAwB,EAAE,GAAG;AACnE,MAAI,SAAS,MAAM,UAAU;AAC3B,UAAM,IAAI,QAAc,CAAC,SAAS,WAAW;AAC3C,eAAS,QAAQ,CAAC,IAAI,UAAW,GAAG,CAAC,QAAQ,MAAM,OAAO,GAAG,IAAI,QAAQ,CAAC;AAAA,IAC5E,CAAC;AAAA,EACH;AACA,SAAO,IAAI;AACb;;;AGlKA,SAAS,KAAAA,UAAS;;;ACEX,IAAM,qBAAN,MAAsD;AAAA,EAC3D,YACmB,QACA,QACA,YAA0B,OAC3C;AAHiB;AACA;AACA;AAAA,EAChB;AAAA,EAHgB;AAAA,EACA;AAAA,EACA;AAAA,EAGnB,MAAM,KAAQ,MAAc,MAA+B,YAAY,MAAqB;AAC1F,UAAM,MAAM,MAAM,KAAK,UAAU,GAAG,KAAK,OAAO,QAAQ,OAAO,EAAE,CAAC,GAAG,IAAI,IAAI;AAAA,MAC3E,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,gBAAgB;AAAA,QAChB,aAAa,KAAK;AAAA,MACpB;AAAA,MACA,MAAM,KAAK,UAAU,IAAI;AAAA,MACzB,QAAQ,YAAY,QAAQ,SAAS;AAAA,IACvC,CAAC;AACD,UAAM,OAAO,MAAM,IAAI,KAAK,EAAE,MAAM,OAAO,CAAC,EAAE;AAC9C,QAAI,CAAC,IAAI,IAAI;AACX,YAAM,UAAU,OAAQ,KAA6B,UAAU,WAC1D,KAA2B,QAC5B,gBAAgB,IAAI,gBAAgB,IAAI,MAAM;AAClD,YAAM,IAAI,MAAM,OAAO;AAAA,IACzB;AACA,WAAO;AAAA,EACT;AACF;;;AC5BA,SAAS,SAAS;;;ACoBX,SAAS,WAAW,OAAwB;AACjD,SAAO,OAAO,SAAS,EAAE,EACtB,QAAQ,MAAM,OAAO,EACrB,QAAQ,MAAM,MAAM,EACpB,QAAQ,MAAM,MAAM,EACpB,QAAQ,MAAM,QAAQ,EACtB,QAAQ,MAAM,OAAO;AAC1B;AAEA,SAAS,YAAY,OAA4B;AAC/C,QAAM,OAAO,MAAM,KAAK,IAAI,SAC1B,OAAO,MAAM,QAAQ,IAAI,SAAO,OAAO,WAAW,IAAI,GAAG,CAAC,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC,OAC7E,EAAE,KAAK,IAAI;AACZ,SAAO;AAAA,IACL;AAAA,IACA,OAAO,WAAW,MAAM,KAAK,CAAC;AAAA,IAC9B;AAAA,IACA,cAAc,MAAM,QAAQ,IAAI,SAAO,OAAO,WAAW,GAAG,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC;AAAA,IAC9E,UAAU,QAAQ,oBAAoB,MAAM,QAAQ,MAAM,qBAAqB;AAAA,IAC/E;AAAA,IACA;AAAA,EACF,EAAE,KAAK,IAAI;AACb;AAEO,SAAS,qBAAqB,OAAoC;AACvE,QAAM,WAAW,MAAM,UAAU,SAC7B,kDAAkD,MAAM,SAAS,IAAI,OAAK,OAAO,WAAW,CAAC,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC,oBAC/G;AACJ,QAAM,YAAY,MAAM,YAAY,CAAC,GAAG,IAAI,aAC1C,gBAAgB,WAAW,QAAQ,KAAK,CAAC,WAAW,WAAW,QAAQ,IAAI,CAAC,gBAC7E,EAAE,KAAK,IAAI;AACZ,QAAM,UAAU,MAAM,UAAU,CAAC,GAAG,IAAI,WAAW,EAAE,KAAK,IAAI;AAE9D,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,UAAU,WAAW,MAAM,KAAK,CAAC;AAAA,IACjC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,OAAO,WAAW,MAAM,KAAK,CAAC;AAAA,IAC9B,MAAM,WAAW,kBAAkB,WAAW,MAAM,QAAQ,CAAC,SAAS;AAAA,IACtE,wBAAwB,WAAW,MAAM,OAAO,CAAC;AAAA,IACjD;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,EAAE,KAAK,IAAI;AACb;;;ADxEA,IAAM,yBAAyB,EAAE,OAAO;AAAA,EACtC,SAAS,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EACzB,QAAQ,EAAE,OAAO,EAAE,SAAS;AAAA,EAC5B,UAAU,EAAE,OAAO,EAAE,SAAS;AAAA,EAC9B,cAAc,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,QAAQ,EAAE;AAAA,EACzD,aAAa,EAAE,QAAQ,EAAE,QAAQ,IAAI;AAAA,EACrC,YAAY,EAAE,QAAQ,EAAE,QAAQ,IAAI;AAAA,EACpC,mBAAmB,EAAE,QAAQ,EAAE,QAAQ,IAAI;AAAA,EAC3C,eAAe,EAAE,QAAQ,EAAE,QAAQ,IAAI;AACzC,CAAC;AA2BD,SAAS,gBAAgB,OAAsC;AAC7D,MAAI,CAAC,MAAO,QAAO;AACnB,MAAI;AACF,UAAM,MAAM,IAAI,IAAI,MAAM,SAAS,KAAK,IAAI,QAAQ,WAAW,KAAK,EAAE;AACtE,WAAO,IAAI,SAAS,QAAQ,UAAU,EAAE,EAAE,YAAY;AAAA,EACxD,QAAQ;AACN,WAAO,MAAM,QAAQ,gBAAgB,EAAE,EAAE,QAAQ,UAAU,EAAE,EAAE,MAAM,GAAG,EAAE,CAAC,GAAG,YAAY,KAAK;AAAA,EACjG;AACF;AAEA,SAAS,cAAc,KAAqB;AAC1C,SAAO,gBAAgB,GAAG,KAAK;AACjC;AAEA,SAAS,WAAW,OAAyB,MAA0B,KAAyD;AAC9H,QAAM,SAAS,gBAAgB,MAAM,MAAM;AAC3C,QAAM,OAAuC,CAAC;AAC9C,aAAW,UAAU,MAAM,kBAAkB,CAAC,GAAG;AAC/C,UAAM,SAAS,gBAAgB,OAAO,MAAM,KAAK,cAAc,OAAO,GAAG;AACzE,SAAK,KAAK;AAAA,MACR,SAAS;AAAA,MACT,UAAU,OAAO;AAAA,MACjB,OAAO,OAAO;AAAA,MACd,KAAK,OAAO;AAAA,MACZ;AAAA,MACA,UAAU;AAAA,MACV,gBAAgB,OAAO,WAAW;AAAA,MAClC,WAAW,SAAS,WAAW,SAAS;AAAA,MACxC,eAAe,SAAS,WAAW,SAAS;AAAA,IAC9C,CAAC;AAAA,EACH;AACA,aAAW,OAAO,KAAK,QAAQ,CAAC,GAAG;AACjC,UAAM,MAAM,IAAI,eAAe;AAC/B,UAAM,SAAS,gBAAgB,IAAI,eAAe,EAAE,MAAM,MAAM,cAAc,GAAG,IAAI;AACrF,SAAK,KAAK;AAAA,MACR,SAAS;AAAA,MACT,UAAU;AAAA,MACV,OAAO,IAAI,gBAAgB,IAAI,eAAe;AAAA,MAC9C;AAAA,MACA;AAAA,MACA,UAAU,IAAI;AAAA,MACd,iBAAiB,IAAI,UAAU,IAAI,MAAM,GAAG,GAAG;AAAA,MAC/C,WAAW,SAAS,WAAW,SAAS;AAAA,MACxC,eAAe,SAAS,QAAQ,UAAU,WAAW,MAAM,IAAI,QAAQ,MAAM;AAAA,IAC/E,CAAC;AAAA,EACH;AACA,aAAW,CAAC,GAAG,IAAI,MAAM,MAAM,YAAY,aAAa,CAAC,GAAG,QAAQ,GAAG;AACrE,UAAM,MAAM,KAAK,QAAQ;AACzB,UAAM,SAAS,MAAM,cAAc,GAAG,IAAI;AAC1C,SAAK,KAAK;AAAA,MACR,SAAS;AAAA,MACT,UAAU,IAAI;AAAA,MACd,OAAO,KAAK,QAAQ;AAAA,MACpB;AAAA,MACA;AAAA,MACA,UAAU;AAAA,MACV,gBAAgB;AAAA,MAChB,WAAW,SAAS,WAAW,SAAS;AAAA,MACxC,eAAe,SAAS,QAAQ,UAAU,WAAW,MAAM,IAAI,QAAQ,MAAM;AAAA,IAC/E,CAAC;AAAA,EACH;AACA,SAAO;AACT;AAEA,SAAS,eAAe,MAAsC,cAA6D;AACzH,QAAM,WAAW,oBAAI,IAA+E;AACpG,aAAW,OAAO,MAAM;AACtB,UAAM,SAAS,OAAO,IAAI,UAAU,EAAE;AACtC,QAAI,CAAC,UAAU,WAAW,aAAc;AACxC,UAAM,QAAQ,SAAS,IAAI,MAAM,KAAK,EAAE,SAAS,CAAC,GAAG,KAAK,GAAG,IAAI,GAAG,MAAM,oBAAI,IAAY,EAAE;AAC5F,QAAI,IAAI,YAAY,aAAa,IAAI,SAAU,OAAM,QAAQ,KAAK,OAAO,IAAI,QAAQ,CAAC;AACtF,QAAI,IAAI,YAAY,MAAO,OAAM,OAAO;AACxC,QAAI,IAAI,YAAY,cAAe,OAAM,MAAM;AAC/C,QAAI,IAAI,IAAK,OAAM,KAAK,IAAI,OAAO,IAAI,GAAG,CAAC;AAC3C,aAAS,IAAI,QAAQ,KAAK;AAAA,EAC5B;AACA,SAAO,CAAC,GAAG,SAAS,QAAQ,CAAC,EAC1B,IAAI,CAAC,CAAC,QAAQ,KAAK,OAAO;AAAA,IACzB;AAAA,IACA,uBAAuB,MAAM,QAAQ,SAAS,KAAK,IAAI,GAAG,MAAM,OAAO,IAAI;AAAA,IAC3E,eAAe,MAAM,QAAQ;AAAA,IAC7B,cAAc,MAAM;AAAA,IACpB,uBAAuB,MAAM;AAAA,IAC7B,kBAAkB,MAAM,KAAK;AAAA,EAC/B,EAAE,EACD,KAAK,CAAC,GAAG,MAAM,OAAO,EAAE,yBAAyB,GAAG,IAAI,OAAO,EAAE,yBAAyB,GAAG,CAAC;AACnG;AAEO,IAAM,gCAAsE;AAAA,EACjF,IAAI;AAAA,EACJ,OAAO;AAAA,EACP,aAAa;AAAA,EACb,aAAa;AAAA,EACb,MAAM,IAAI,OAAyB,KAAsD;AACvF,UAAM,IAAI,UAAU,cAAc,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AACvD,UAAM,WAAqB,CAAC;AAC5B,UAAM,SAAmB,CAAC;AAC1B,QAAI,OAA2B;AAC/B,QAAI,MAA0B;AAE9B,QAAI,MAAM,aAAa;AACrB,UAAI;AACF,eAAO,MAAM,IAAI,OAAO,KAAkB,iBAAiB;AAAA,UACzD,OAAO,MAAM;AAAA,UACb,UAAU,MAAM;AAAA,UAChB,UAAU;AAAA,UACV,cAAc;AAAA,UACd,QAAQ;AAAA,QACV,GAAG,IAAO;AAAA,MACZ,SAAS,KAAK;AACZ,iBAAS,KAAK,8BAA8B,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC,EAAE;AAAA,MAChG;AAAA,IACF;AAEA,QAAI,MAAM,YAAY;AACpB,UAAI;AACF,cAAM,MAAM,IAAI,OAAO,KAAkB,iBAAiB;AAAA,UACxD,OAAO,MAAM;AAAA,UACb,UAAU,MAAM;AAAA,UAChB,cAAc,MAAM;AAAA,UACpB,QAAQ;AAAA,QACV,GAAG,IAAO;AAAA,MACZ,SAAS,KAAK;AACZ,iBAAS,KAAK,6BAA6B,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC,EAAE;AAAA,MAC/F;AAAA,IACF;AAEA,QAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,cAAe,OAAM,IAAI,MAAM,+BAA+B;AAC1F,UAAM,OAAO,WAAW,OAAO,MAAM,GAAG;AACxC,UAAM,SAAS,gBAAgB,MAAM,MAAM;AAC3C,UAAM,cAAc,eAAe,MAAM,MAAM;AAC/C,UAAM,WAAW;AAAA,MACf;AAAA,MACA,MAAM,QAAQ,EAAE,QAAQ,UAAU;AAAA,MAClC,KAAK,OAAO,EAAE,QAAQ,UAAU;AAAA,MAChC,QAAQ;AAAA,QACN,QAAQ;AAAA,QACR,kBAAkB,KAAK,OAAO,OAAK,EAAE,YAAY,aAAa,EAAE,SAAS,EAAE,IAAI,OAAK,OAAO,EAAE,QAAQ,CAAC;AAAA,QACtG,mBAAmB,KAAK,KAAK,OAAK,EAAE,YAAY,iBAAiB,EAAE,SAAS;AAAA,QAC5E,YAAY,KAAK,KAAK,OAAK,EAAE,YAAY,SAAS,EAAE,SAAS;AAAA,MAC/D;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAEA,UAAM,IAAI,UAAU,UAAU,iBAAiB,iBAAiB,QAAQ;AACxE,UAAM,IAAI,UAAU,SAAS,eAAe,eAAe,CAAC,WAAW,YAAY,SAAS,OAAO,UAAU,YAAY,kBAAkB,aAAa,eAAe,GAAG,IAAI;AAC9K,UAAM,IAAI,UAAU,SAAS,mBAAmB,mBAAmB,CAAC,UAAU,yBAAyB,iBAAiB,gBAAgB,yBAAyB,kBAAkB,GAAG,WAAW;AAEjM,UAAM,QAAQ;AAAA,MACZ,yBAAyB,MAAM,OAAO;AAAA,MACtC;AAAA,MACA,aAAa,MAAM,YAAY,eAAe;AAAA,MAC9C,kBAAkB,UAAU,eAAe;AAAA,MAC3C;AAAA,MACA;AAAA,MACA,mBAAmB,KAAK,OAAO,OAAK,EAAE,YAAY,SAAS,EAAE,MAAM;AAAA,MACnE,eAAe,KAAK,OAAO,OAAK,EAAE,YAAY,KAAK,EAAE,MAAM;AAAA,MAC3D,4BAA4B,KAAK,OAAO,OAAK,EAAE,YAAY,aAAa,EAAE,MAAM;AAAA,MAChF,yBAAyB,YAAY,MAAM;AAAA,MAC3C;AAAA,MACA;AAAA,MACA;AAAA,IACF,EAAE,KAAK,IAAI;AACX,UAAM,IAAI,UAAU,UAAU,SAAS,YAAY,KAAK;AACxD,UAAM,IAAI,UAAU,UAAU,eAAe,YAAY;AAAA,MACvD;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,EAAE,KAAK,IAAI,CAAC;AACZ,UAAM,IAAI,UAAU,UAAU,sBAAsB,yBAAyB;AAAA,MAC3E;AAAA,MACA;AAAA,MACA;AAAA,IACF,EAAE,KAAK,IAAI,CAAC;AAEZ,UAAM,UAAU,GAAG,KAAK,MAAM,sBAAsB,YAAY,MAAM;AACtE,UAAM,aAAa,MAAM,IAAI,UAAU,UAAU,eAAe,eAAe,qBAAqB;AAAA,MAClG,OAAO;AAAA,MACP,UAAU,GAAG,MAAM,OAAO,GAAG,MAAM,WAAW,SAAM,MAAM,QAAQ,KAAK,EAAE;AAAA,MACzE;AAAA,MACA;AAAA,MACA,QAAQ;AAAA,QACN,EAAE,OAAO,sBAAsB,SAAS,CAAC,UAAU,yBAAyB,iBAAiB,gBAAgB,yBAAyB,kBAAkB,GAAG,MAAM,YAAY,MAAM,GAAG,EAAE,EAAE;AAAA,QAC1L,EAAE,OAAO,oBAAoB,SAAS,CAAC,WAAW,YAAY,SAAS,UAAU,YAAY,WAAW,GAAG,MAAM,KAAK,MAAM,GAAG,GAAG,EAAE;AAAA,MACtI;AAAA,IACF,CAAC,CAAC;AACF,UAAM,SAAS,SAAS,SAAS,YAAY;AAC7C,UAAM,SAAS,EAAE,SAAS,KAAK,QAAQ,aAAa,YAAY,OAAO;AACvE,UAAM,IAAI,UAAU,cAAc,QAAQ,QAAQ,UAAU,MAAM;AAClE,WAAO,EAAE,OAAO,0BAA0B,SAAS,QAAQ,QAAQ,UAAU,QAAQ,WAAW;AAAA,EAClG;AACF;;;AE5OA,SAAS,KAAAC,UAAS;AAIlB,IAAM,kCAAkCC,GAAE,OAAO;AAAA,EAC/C,OAAOA,GAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EACvB,OAAOA,GAAE,OAAO,EAAE,IAAI,CAAC,EAAE,QAAQ,IAAI;AAAA,EACrC,eAAeA,GAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,QAAQ,GAAO;AAAA,EACtD,WAAWA,GAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,QAAQ,EAAE;AAAA,EACtD,mBAAmBA,GAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,QAAQ,EAAE;AAAA,EAC7D,aAAaA,GAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,QAAQ,CAAC;AAAA,EACrD,WAAWA,GAAE,KAAK,CAAC,YAAY,cAAc,MAAM,CAAC,EAAE,QAAQ,UAAU;AAAA,EACxE,SAASA,GAAE,QAAQ,EAAE,QAAQ,IAAI;AACnC,CAAC;AAuCM,SAAS,cAAc,QAAoE;AAChG,QAAM,OAAuC,CAAC;AAC9C,aAAW,QAAQ,OAAO,QAAQ;AAChC,QAAI,CAAC,KAAK,QAAQ,QAAQ;AACxB,WAAK,KAAK;AAAA,QACR,cAAc,OAAO;AAAA,QACrB,iBAAiB,KAAK;AAAA,QACtB,MAAM,KAAK;AAAA,QACX,OAAO,KAAK;AAAA,QACZ,YAAY,KAAK;AAAA,QACjB,iBAAiB;AAAA,QACjB,eAAe;AAAA,QACf,cAAc;AAAA,QACd,cAAc;AAAA,QACd,UAAU;AAAA,QACV,SAAS;AAAA,QACT,OAAO;AAAA,QACP,aAAa;AAAA,QACb,WAAW;AAAA,QACX,KAAK;AAAA,QACL,aAAa;AAAA,QACb,eAAe,KAAK;AAAA,QACpB,OAAO,KAAK;AAAA,MACd,CAAC;AACD;AAAA,IACF;AACA,eAAW,YAAY,KAAK,SAAS;AACnC,WAAK,KAAK;AAAA,QACR,cAAc,OAAO;AAAA,QACrB,iBAAiB,KAAK;AAAA,QACtB,MAAM,KAAK;AAAA,QACX,OAAO,KAAK;AAAA,QACZ,YAAY,KAAK;AAAA,QACjB,iBAAiB,SAAS;AAAA,QAC1B,eAAe,SAAS;AAAA,QACxB,cAAc,SAAS;AAAA,QACvB,cAAc,SAAS;AAAA,QACvB,UAAU,SAAS;AAAA,QACnB,SAAS,SAAS;AAAA,QAClB,OAAO,SAAS;AAAA,QAChB,aAAa,SAAS;AAAA,QACtB,WAAW,SAAS;AAAA,QACpB,KAAK,SAAS;AAAA,QACd,aAAa,SAAS;AAAA,QACtB,eAAe,KAAK;AAAA,QACpB,OAAO,KAAK;AAAA,MACd,CAAC;AAAA,IACH;AAAA,EACF;AACA,SAAO;AACT;AAEO,IAAM,wBAAwB;AAAA,EACnC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEO,IAAM,8BAA6E;AAAA,EACxF,IAAI;AAAA,EACJ,OAAO;AAAA,EACP,aAAa;AAAA,EACb,aAAa;AAAA,EACb,MAAM,IAAI,OAAkC,KAAsD;AAChG,UAAM,IAAI,UAAU,cAAc,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AACvD,UAAM,SAAS,MAAM,IAAI,OAAO,KAAiC,kBAAkB,OAAkC,GAAO;AAC5H,UAAM,IAAI,UAAU,UAAU,sBAAsB,iBAAiB,MAAM;AAC3E,UAAM,OAAO,cAAc,MAAM;AACjC,UAAM,IAAI,UAAU,SAAS,iBAAiB,yBAAyB,uBAAuB,IAAI;AAElG,UAAM,WAAW,OAAO,OAAO,IAAI,WAAS;AAAA,MAC1C,MAAM,KAAK;AAAA,MACX,OAAO,KAAK;AAAA,MACZ,YAAY,KAAK;AAAA,MACjB,QAAQ,KAAK;AAAA,MACb,cAAc,KAAK;AAAA,MACnB,OAAO,KAAK,SAAS;AAAA,IACvB,EAAE;AACF,UAAM,UAAU,KACb,OAAO,SAAO,IAAI,aAAa,EAC/B,MAAM,GAAG,GAAG,EACZ,IAAI,UAAQ;AAAA,MACX,MAAM,IAAI;AAAA,MACV,UAAU,IAAI;AAAA,MACd,UAAU,IAAI;AAAA,MACd,QAAQ,IAAI;AAAA,MACZ,SAAS,IAAI;AAAA,MACb,UAAU,IAAI;AAAA,MACd,SAAS,IAAI;AAAA,IACf,EAAE;AAEJ,UAAM,UAAU,GAAG,OAAO,iBAAiB,0BAA0B,OAAO,gBAAgB;AAC5F,UAAM,IAAI,UAAU,UAAU,WAAW,cAAc;AAAA;AAAA,EAA2B,OAAO;AAAA,CAAI;AAC7F,UAAM,aAAa,MAAM,IAAI,UAAU,UAAU,eAAe,eAAe,qBAAqB;AAAA,MAClG,OAAO;AAAA,MACP,UAAU,GAAG,MAAM,KAAK,SAAM,MAAM,KAAK;AAAA,MACzC;AAAA,MACA,UAAU,OAAO;AAAA,MACjB,QAAQ;AAAA,QACN,EAAE,OAAO,UAAU,SAAS,CAAC,QAAQ,SAAS,cAAc,UAAU,gBAAgB,OAAO,GAAG,MAAM,SAAS;AAAA,QAC/G,EAAE,OAAO,eAAe,SAAS,CAAC,QAAQ,YAAY,YAAY,UAAU,WAAW,YAAY,SAAS,GAAG,MAAM,QAAQ;AAAA,MAC/H;AAAA,IACF,CAAC,CAAC;AACF,UAAM,SAAS,OAAO,OAAO,KAAK,UAAQ,KAAK,WAAW,QAAQ,IAAI,YAAY;AAClF,UAAM,SAAS,EAAE,QAAQ,OAAO,mBAAmB,SAAS,OAAO,kBAAkB,MAAM,KAAK,OAAO;AACvG,UAAM,IAAI,UAAU,cAAc,QAAQ,QAAQ,OAAO,UAAU,CAAC,CAAC;AACrE,WAAO,EAAE,OAAO,sBAAsB,SAAS,QAAQ,QAAQ,UAAU,OAAO,UAAU,QAAQ,CAAC,GAAG,WAAW;AAAA,EACnH;AACF;;;AC/KA,SAAS,KAAAC,UAAS;AAKlB,IAAM,mCAAmCC,GAAE,OAAO;AAAA,EAChD,OAAOA,GAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EACvB,OAAOA,GAAE,OAAO,EAAE,IAAI,CAAC,EAAE,QAAQ,IAAI;AAAA,EACrC,eAAeA,GAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,QAAQ,GAAO;AAAA,EACtD,WAAWA,GAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,QAAQ,EAAE;AAAA,EACtD,mBAAmBA,GAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,QAAQ,EAAE;AAAA,EAC7D,YAAYA,GAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,QAAQ,CAAC;AAAA,EACrD,YAAYA,GAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,QAAQ,EAAE;AAAA,EACvD,aAAaA,GAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,QAAQ,CAAC;AAAA,EACrD,WAAWA,GAAE,KAAK,CAAC,YAAY,cAAc,MAAM,CAAC,EAAE,QAAQ,UAAU;AAAA,EACxE,eAAeA,GAAE,QAAQ,EAAE,QAAQ,IAAI;AACzC,CAAC;AAiBD,eAAe,SAAe,OAAY,OAAe,IAA0D;AACjH,QAAM,MAAW,IAAI,MAAM,MAAM,MAAM;AACvC,MAAI,OAAO;AACX,iBAAe,SAAwB;AACrC,WAAO,OAAO,MAAM,QAAQ;AAC1B,YAAM,QAAQ;AACd,cAAQ;AACR,UAAI,KAAK,IAAI,MAAM,GAAG,MAAM,KAAK,GAAG,KAAK;AAAA,IAC3C;AAAA,EACF;AACA,QAAM,QAAQ,IAAI,MAAM,KAAK,EAAE,QAAQ,KAAK,IAAI,OAAO,MAAM,MAAM,EAAE,GAAG,MAAM,OAAO,CAAC,CAAC;AACvF,SAAO;AACT;AAEA,SAAS,WAAW,OAA+B;AACjD,MAAI,UAAU,QAAQ,UAAU,UAAa,UAAU,GAAI,QAAO;AAClE,QAAM,SAAS,OAAO,OAAO,KAAK,EAAE,QAAQ,WAAW,EAAE,CAAC;AAC1D,SAAO,OAAO,SAAS,MAAM,IAAI,SAAS;AAC5C;AAEA,SAAS,OAAO,QAA6C;AAC3D,QAAM,OAAO,OAAO,OAAO,CAAC,MAAmB,MAAM,IAAI,EAAE,KAAK,CAAC,GAAG,MAAM,IAAI,CAAC;AAC/E,MAAI,CAAC,KAAK,OAAQ,QAAO;AACzB,SAAO,KAAK,KAAK,MAAM,KAAK,SAAS,CAAC,CAAC,KAAK;AAC9C;AAEA,SAAS,UAAU,OAAyB;AAC1C,QAAM,OAAO,oBAAI,IAAI,CAAC,OAAO,OAAO,OAAO,QAAQ,QAAQ,QAAQ,OAAO,QAAQ,OAAO,OAAO,OAAO,QAAQ,OAAO,QAAQ,OAAO,OAAO,QAAQ,QAAQ,SAAS,MAAM,CAAC;AAC5K,QAAM,SAAS,oBAAI,IAAoB;AACvC,aAAW,QAAQ,OAAO;AACxB,eAAW,SAAS,KAAK,YAAY,EAAE,QAAQ,gBAAgB,GAAG,EAAE,MAAM,KAAK,GAAG;AAChF,UAAI,MAAM,SAAS,KAAK,KAAK,IAAI,KAAK,EAAG;AACzC,aAAO,IAAI,QAAQ,OAAO,IAAI,KAAK,KAAK,KAAK,CAAC;AAAA,IAChD;AAAA,EACF;AACA,SAAO,CAAC,GAAG,OAAO,QAAQ,CAAC,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,MAAM,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC,MAAM,KAAK,MAAM,GAAG,IAAI,KAAK,KAAK,GAAG,EAAE,KAAK,IAAI;AAC7H;AAEO,IAAM,0CAA0F;AAAA,EACrG,IAAI;AAAA,EACJ,OAAO;AAAA,EACP,aAAa;AAAA,EACb,aAAa;AAAA,EACb,MAAM,IAAI,OAAmC,KAAsD;AACjG,UAAM,IAAI,UAAU,cAAc,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AACvD,UAAM,WAAqB,CAAC;AAC5B,UAAM,SAAmB,CAAC;AAC1B,UAAM,YAAY,MAAM,IAAI,OAAO,KAAiC,kBAAkB;AAAA,MACpF,OAAO,MAAM;AAAA,MACb,OAAO,MAAM;AAAA,MACb,eAAe,MAAM;AAAA,MACrB,WAAW,MAAM;AAAA,MACjB,mBAAmB,MAAM;AAAA,MACzB,aAAa,MAAM;AAAA,MACnB,WAAW,MAAM;AAAA,MACjB,SAAS;AAAA,IACX,GAAG,GAAO;AAEV,UAAM,IAAI,UAAU,UAAU,sBAAsB,+BAA+B,SAAS;AAC5F,UAAM,WAAW,cAAc,SAAS;AACxC,UAAM,IAAI,UAAU,SAAS,sBAAsB,yBAAyB,uBAAuB,QAAQ;AAE3G,UAAM,WAAW,UAAU,OAAO;AAAA,MAAQ,UACxC,KAAK,QAAQ,MAAM,GAAG,MAAM,UAAU,EAAE,IAAI,aAAW,EAAE,MAAM,OAAO,EAAE;AAAA,IAC1E;AACA,UAAM,OAAO,oBAAI,IAAY;AAC7B,UAAM,UAAU,SAAS,OAAO,CAAC,EAAE,MAAM,OAAO,MAAM;AACpD,YAAM,MAAM,OAAO,OAAO,OAAO,YAAY,GAAG,KAAK,QAAQ,IAAI,OAAO,KAAK,YAAY,CAAC;AAC1F,UAAI,KAAK,IAAI,GAAG,EAAG,QAAO;AAC1B,WAAK,IAAI,GAAG;AACZ,aAAO;AAAA,IACT,CAAC;AAED,UAAM,WAAW,MAAM,SAAS,SAAS,GAAG,OAAO,EAAE,MAAM,OAAO,GAAG,UAAU;AAC7E,UAAI;AACF,cAAM,SAAS,MAAM,IAAI,OAAO,KAA2B,eAAe;AAAA,UACxE,cAAc,OAAO;AAAA,UACrB,UAAU,KAAK;AAAA,UACf,gBAAgB,MAAM,aAAa;AAAA,UACnC,YAAY,KAAK,IAAI,GAAG,MAAM,UAAU;AAAA,QAC1C,GAAG,IAAO;AACV,cAAM,IAAI,UAAU,UAAU,GAAG,OAAO,IAAI,YAAY,wBAAwB,QAAQ,CAAC,IAAI,OAAO,KAAK,YAAY,EAAE,QAAQ,eAAe,GAAG,CAAC,SAAS,MAAM;AACjK,eAAO,EAAE,MAAM,QAAQ,QAAQ,OAAO,KAAsB;AAAA,MAC9D,SAAS,KAAK;AACZ,cAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC/D,iBAAS,KAAK,gCAAgC,OAAO,IAAI,KAAK,KAAK,QAAQ,MAAM,OAAO,EAAE;AAC1F,eAAO,EAAE,MAAM,QAAQ,QAAQ,MAAM,OAAO,QAAQ;AAAA,MACtD;AAAA,IACF,CAAC;AAED,UAAMC,kBAAiB,SAAS,IAAI,CAAC,EAAE,MAAM,QAAQ,QAAQ,MAAM,MAAM;AACvE,YAAM,UAAU,QAAQ,WAAW,CAAC;AACpC,YAAM,iBAAiB,QAAQ,OAAO,OAAK,EAAE,aAAa,EAAE;AAC5D,aAAO;AAAA,QACL,MAAM,KAAK;AAAA,QACX,OAAO,KAAK;AAAA,QACZ,iBAAiB,KAAK;AAAA,QACtB,iBAAiB,OAAO;AAAA,QACxB,eAAe,OAAO;AAAA,QACtB,UAAU,QAAQ,YAAY,OAAO;AAAA,QACrC,cAAc,QAAQ,UAAU,OAAO;AAAA,QACvC,cAAc,QAAQ,eAAe,OAAO;AAAA,QAC5C,OAAO,OAAO;AAAA,QACd,aAAa,QAAQ,WAAW,OAAO;AAAA,QACvC,WAAW,OAAO;AAAA,QAClB,KAAK,OAAO;AAAA,QACZ,aAAa,OAAO;AAAA,QACpB,UAAU,SAAS,SAAS;AAAA,QAC5B,gBAAgB,QAAQ,iBAAiB;AAAA,QACzC,gBAAgB,QAAQ,gBAAgB,CAAC,GAAG,IAAI,OAAK,GAAG,EAAE,KAAK,KAAK,EAAE,KAAK,GAAG,EAAE,KAAK,IAAI;AAAA,QACzF,qBAAqB,QAAQ,UAAU,iBAAiB,QAAQ,QAAQ,QAAQ,CAAC,IAAI;AAAA,QACrF,OAAO,SAAS;AAAA,MAClB;AAAA,IACF,CAAC;AAED,UAAM,oBAAoB,SAAS,IAAI,CAAC,EAAE,MAAM,QAAQ,OAAO,MAAM;AACnE,YAAM,UAAU,QAAQ,WAAW,CAAC;AACpC,YAAM,WAAW,QAAQ,OAAO,OAAK,OAAO,EAAE,KAAK,KAAK,KAAK,EAAE,IAAI,EAAE,IAAI,OAAK,EAAE,IAAK;AACrF,YAAM,WAAW,QAAQ,OAAO,OAAK,OAAO,EAAE,KAAK,IAAI,KAAK,OAAO,EAAE,KAAK,KAAK,KAAK,EAAE,IAAI,EAAE,IAAI,OAAK,EAAE,IAAK;AAC5G,aAAO;AAAA,QACL,MAAM,KAAK;AAAA,QACX,eAAe,OAAO;AAAA,QACtB,KAAK,OAAO;AAAA,QACZ,cAAc,QAAQ,eAAe,OAAO;AAAA,QAC5C,gBAAgB,QAAQ,UAAU,OAAO;AAAA,QACzC,SAAS,QAAQ,gBAAgB,CAAC,GAAG,IAAI,OAAK,GAAG,EAAE,KAAK,KAAK,EAAE,KAAK,GAAG,EAAE,KAAK,IAAI;AAAA,QAClF,cAAc,UAAU,QAAQ;AAAA,QAChC,iBAAiB,UAAU,QAAQ;AAAA,QACnC,iBAAiB,SAAS,CAAC,GAAG,MAAM,GAAG,GAAG,KAAK;AAAA,QAC/C,iBAAiB,SAAS,CAAC,GAAG,MAAM,GAAG,GAAG,KAAK;AAAA,MACjD;AAAA,IACF,CAAC;AAED,UAAM,kBAAkB,UAAU,OAAO,IAAI,UAAQ;AACnD,YAAM,qBAAqB,KAAK,QAAQ,IAAI,OAAK,WAAW,EAAE,WAAW,CAAC;AAC1E,YAAM,gBAAgB,KAAK,QAAQ,IAAI,OAAK,WAAW,EAAE,MAAM,CAAC;AAChE,YAAM,kBAAkB,KAAK,QAAQ,MAAM,GAAG,CAAC,EAAE,IAAI,OAAK,WAAW,EAAE,WAAW,CAAC,EAAE,OAAO,CAAC,MAAmB,MAAM,IAAI;AAC1H,YAAM,aAAa,oBAAI,IAAoB;AAC3C,iBAAW,UAAU,KAAK,SAAS;AACjC,YAAI,CAAC,OAAO,SAAU;AACtB,mBAAW,IAAI,OAAO,WAAW,WAAW,IAAI,OAAO,QAAQ,KAAK,KAAK,CAAC;AAAA,MAC5E;AACA,YAAM,aAAa,OAAO,kBAAkB;AAC5C,YAAM,YAAY,OAAO,aAAa;AACtC,YAAM,cAAc,gBAAgB,SAAS,KAAK,MAAM,gBAAgB,OAAO,CAAC,GAAG,MAAM,IAAI,GAAG,CAAC,IAAI,gBAAgB,MAAM,IAAI;AAC/H,YAAM,aAAa,KAAK,IAAI,KAAK,KAAK,OAAO,eAAe,KAAK,MAAM,aAAa,KAAK,KAAK,KAAK,QAAQ,OAAO,OAAK,EAAE,UAAU,EAAE,MAAM,CAAC;AAC5I,YAAM,cAAc,KAAK,IAAI,GAAG,MAAM,UAAU;AAChD,aAAO;AAAA,QACL,MAAM,KAAK;AAAA,QACX,OAAO,KAAK;AAAA,QACZ,YAAY,KAAK;AAAA,QACjB,cAAc,KAAK;AAAA,QACnB,qBAAqB,cAAc;AAAA,QACnC,eAAe,aAAa;AAAA,QAC5B,gCAAgC,eAAe;AAAA,QAC/C,gBAAgB,CAAC,GAAG,WAAW,QAAQ,CAAC,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,MAAM,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC,KAAK,KAAK,MAAM,GAAG,GAAG,KAAK,KAAK,GAAG,EAAE,KAAK,IAAI;AAAA,QACtI,mBAAmB;AAAA,QACnB,kBAAkB;AAAA,MACpB;AAAA,IACF,CAAC;AAED,UAAM,IAAI,UAAU,SAAS,mBAAmB,mBAAmB,CAAC,QAAQ,SAAS,mBAAmB,mBAAmB,iBAAiB,YAAY,gBAAgB,gBAAgB,SAAS,eAAe,aAAa,OAAO,eAAe,YAAY,kBAAkB,iBAAiB,uBAAuB,OAAO,GAAGA,eAAc;AACjV,UAAM,IAAI,UAAU,SAAS,uBAAuB,uBAAuB,CAAC,QAAQ,iBAAiB,OAAO,gBAAgB,kBAAkB,UAAU,gBAAgB,mBAAmB,mBAAmB,iBAAiB,GAAG,iBAAiB;AACnP,UAAM,IAAI,UAAU,SAAS,oBAAoB,oBAAoB,CAAC,QAAQ,SAAS,cAAc,gBAAgB,uBAAuB,iBAAiB,kCAAkC,kBAAkB,qBAAqB,kBAAkB,GAAG,eAAe;AAC1Q,UAAM,IAAI,UAAU,UAAU,kBAAkB,iBAAiB,EAAE,OAAO,WAAW,UAAU,iBAAiB,gBAAAA,iBAAgB,kBAAkB,CAAC;AACnJ,UAAM,IAAI,UAAU,UAAU,eAAe,YAAY;AAAA,MACvD;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,EAAE,KAAK,IAAI,CAAC;AAEZ,UAAM,UAAU,GAAG,UAAU,iBAAiB,YAAY,UAAU,gBAAgB,kBAAkB,SAAS,OAAO,OAAK,EAAE,MAAM,EAAE,MAAM;AAC3I,UAAM,IAAI,UAAU,UAAU,WAAW,cAAc;AAAA;AAAA,EAAgC,OAAO;AAAA,CAAI;AAClG,UAAM,aAAa,MAAM,IAAI,UAAU,UAAU,eAAe,eAAe,qBAAqB;AAAA,MAClG,OAAO;AAAA,MACP,UAAU,GAAG,MAAM,KAAK,SAAM,MAAM,KAAK;AAAA,MACzC;AAAA,MACA;AAAA,MACA,QAAQ;AAAA,QACN,EAAE,OAAO,oBAAoB,SAAS,CAAC,QAAQ,SAAS,cAAc,gBAAgB,uBAAuB,iBAAiB,kCAAkC,kBAAkB,qBAAqB,kBAAkB,GAAG,MAAM,gBAAgB;AAAA,QAClP,EAAE,OAAO,wBAAwB,SAAS,CAAC,QAAQ,mBAAmB,iBAAiB,YAAY,gBAAgB,gBAAgB,YAAY,eAAe,GAAG,MAAMA,gBAAe,MAAM,GAAG,GAAG,EAAE;AAAA,QACpM,EAAE,OAAO,mBAAmB,SAAS,CAAC,QAAQ,iBAAiB,UAAU,gBAAgB,iBAAiB,GAAG,MAAM,kBAAkB,MAAM,GAAG,GAAG,EAAE;AAAA,MACrJ;AAAA,IACF,CAAC,CAAC;AAEF,UAAM,SAAS,SAAS,UAAU,UAAU,OAAO,KAAK,UAAQ,KAAK,WAAW,QAAQ,IAAI,YAAY;AACxG,UAAM,SAAS,EAAE,QAAQ,UAAU,mBAAmB,aAAa,UAAU,kBAAkB,kBAAkB,SAAS,OAAO,OAAK,EAAE,MAAM,EAAE,OAAO;AACvJ,UAAM,IAAI,UAAU,cAAc,QAAQ,QAAQ,UAAU,MAAM;AAClE,WAAO,EAAE,OAAO,2BAA2B,SAAS,QAAQ,QAAQ,UAAU,QAAQ,WAAW;AAAA,EACnG;AACF;;;AClOA,SAAS,KAAAC,UAAS;;;AC4DlB,IAAM,aAAa,oBAAI,IAAI;AAAA,EACzB;AAAA,EAAS;AAAA,EAAS;AAAA,EAAQ;AAAA,EAAW;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAC7E;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAS;AAAA,EAAQ;AAAA,EACzE;AAAA,EAAS;AAAA,EAAS;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAC7E;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAS;AAAA,EAAU;AAAA,EAAS;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AACtE,CAAC;AAEM,SAASC,iBAAgB,OAAsC;AACpE,MAAI,CAAC,MAAO,QAAO;AACnB,MAAI;AACF,UAAM,MAAM,IAAI,IAAI,MAAM,SAAS,KAAK,IAAI,QAAQ,WAAW,KAAK,EAAE;AACtE,WAAO,IAAI,SAAS,QAAQ,UAAU,EAAE,EAAE,YAAY;AAAA,EACxD,QAAQ;AACN,WAAO,MAAM,QAAQ,gBAAgB,EAAE,EAAE,QAAQ,UAAU,EAAE,EAAE,MAAM,GAAG,EAAE,CAAC,GAAG,YAAY,KAAK;AAAA,EACjG;AACF;AAEO,SAASC,eAAc,KAA6B;AACzD,SAAOD,iBAAgB,GAAG,KAAK;AACjC;AAEO,SAASE,YAAW,OAA+B;AACxD,MAAI,UAAU,QAAQ,UAAU,UAAa,UAAU,GAAI,QAAO;AAClE,QAAM,SAAS,OAAO,OAAO,KAAK,EAAE,QAAQ,WAAW,EAAE,CAAC;AAC1D,SAAO,OAAO,SAAS,MAAM,IAAI,SAAS;AAC5C;AAEO,SAASC,QAAO,QAA6C;AAClE,QAAM,OAAO,OAAO,OAAO,CAAC,MAAmB,MAAM,IAAI,EAAE,KAAK,CAAC,GAAG,MAAM,IAAI,CAAC;AAC/E,MAAI,CAAC,KAAK,OAAQ,QAAO;AACzB,SAAO,KAAK,KAAK,MAAM,KAAK,SAAS,CAAC,CAAC,KAAK;AAC9C;AAEO,SAAS,UAAU,MAAc,QAAQ,IAAY;AAC1D,QAAM,SAAS,oBAAI,IAAoB;AACvC,aAAW,SAAS,KAAK,YAAY,EAAE,QAAQ,gBAAgB,GAAG,EAAE,MAAM,KAAK,GAAG;AAChF,QAAI,MAAM,SAAS,KAAK,WAAW,IAAI,KAAK,EAAG;AAC/C,WAAO,IAAI,QAAQ,OAAO,IAAI,KAAK,KAAK,KAAK,CAAC;AAAA,EAChD;AACA,SAAO,CAAC,GAAG,OAAO,QAAQ,CAAC,EACxB,KAAK,CAAC,GAAG,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,cAAc,EAAE,CAAC,CAAC,CAAC,EACtD,MAAM,GAAG,KAAK,EACd,IAAI,CAAC,CAAC,MAAM,KAAK,MAAM,GAAG,IAAI,KAAK,KAAK,GAAG,EAC3C,KAAK,IAAI;AACd;AAEO,SAAS,iBAAiB,UAA0B;AACzD,QAAM,IAAI,SAAS,YAAY;AAC/B,MAAI,kDAAkD,KAAK,CAAC,EAAG,QAAO;AACtE,MAAI,wDAAwD,KAAK,CAAC,EAAG,QAAO;AAC5E,MAAI,kCAAkC,KAAK,CAAC,EAAG,QAAO;AACtD,MAAI,oCAAoC,KAAK,CAAC,EAAG,QAAO;AACxD,MAAI,kCAAkC,KAAK,CAAC,EAAG,QAAO;AACtD,MAAI,uCAAuC,KAAK,CAAC,EAAG,QAAO;AAC3D,SAAO;AACT;AAEO,SAAS,aAAa,KAAyD;AACpF,UAAQ,KAAK,QAAQ,CAAC,GACnB,OAAO,SAAO,IAAI,QAAQ,EAC1B,IAAI,CAAC,KAAK,UAAU;AACnB,UAAM,MAAM,IAAI,eAAe;AAC/B,UAAM,SAASH,iBAAgB,IAAI,eAAe,EAAE,KAAKC,eAAc,GAAG;AAC1E,WAAO;AAAA,MACL,UAAU,QAAQ;AAAA,MAClB,QAAQ,iBAAiB,IAAI,YAAY,EAAE;AAAA,MAC3C,UAAU,IAAI,YAAY;AAAA,MAC1B,iBAAiB,IAAI,UAAU,IAAI,MAAM,GAAG,GAAG;AAAA,MAC/C,cAAc,IAAI,gBAAgB;AAAA,MAClC,eAAe;AAAA,MACf,YAAY;AAAA,IACd;AAAA,EACF,CAAC;AACL;AAEO,SAAS,iBAAiB,MAAsE;AACrG,QAAM,WAAW,oBAAI,IAAoF;AACzG,aAAW,OAAO,MAAM;AACtB,UAAM,SAAS,OAAO,IAAI,iBAAiB,IAAI,UAAU,EAAE;AAC3D,QAAI,CAAC,OAAQ;AACb,UAAM,QAAQ,SAAS,IAAI,MAAM,KAAK,EAAE,WAAW,GAAG,MAAM,oBAAI,IAAY,GAAG,SAAS,oBAAI,IAAoB,EAAE;AAClH,UAAM,aAAa,IAAI,WAAW,IAAI;AACtC,QAAI,IAAI,cAAc,IAAI,IAAK,OAAM,KAAK,IAAI,OAAO,IAAI,cAAc,IAAI,GAAG,CAAC;AAC/E,QAAI,IAAI,OAAQ,OAAM,QAAQ,IAAI,OAAO,IAAI,MAAM,IAAI,MAAM,QAAQ,IAAI,OAAO,IAAI,MAAM,CAAC,KAAK,KAAK,CAAC;AACtG,aAAS,IAAI,QAAQ,KAAK;AAAA,EAC5B;AACA,SAAO,CAAC,GAAG,SAAS,QAAQ,CAAC,EAC1B,IAAI,CAAC,CAAC,QAAQ,KAAK,OAAO;AAAA,IACzB;AAAA,IACA,mBAAmB,MAAM;AAAA,IACzB,kBAAkB,MAAM,KAAK;AAAA,IAC7B,aAAa,CAAC,GAAG,MAAM,QAAQ,QAAQ,CAAC,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,QAAQ,KAAK,MAAM,GAAG,MAAM,KAAK,KAAK,GAAG,EAAE,KAAK,IAAI;AAAA,EAClI,EAAE,EACD,KAAK,CAAC,GAAG,MAAM,OAAO,EAAE,iBAAiB,IAAI,OAAO,EAAE,iBAAiB,KAAK,OAAO,EAAE,MAAM,EAAE,cAAc,OAAO,EAAE,MAAM,CAAC,CAAC;AACjI;AAEO,SAAS,eAAe,MAAgC;AAC7D,UAAQ,QAAQ,IACb,QAAQ,QAAQ,GAAG,EACnB,MAAM,eAAe,EACrB,IAAI,cAAY,SAAS,KAAK,CAAC,EAC/B,OAAO,cAAY,SAAS,SAAS,EAAE,EACvC,MAAM,GAAG,EAAE;AAChB;AAEO,SAAS,iBAAiB,UAA0B;AACzD,QAAM,IAAI,SAAS,YAAY;AAC/B,MAAI,yCAAyC,KAAK,CAAC,EAAG,QAAO;AAC7D,MAAI,qDAAqD,KAAK,CAAC,EAAG,QAAO;AACzE,MAAI,4CAA4C,KAAK,CAAC,EAAG,QAAO;AAChE,MAAI,6CAA6C,KAAK,CAAC,EAAG,QAAO;AACjE,MAAI,2CAA2C,KAAK,CAAC,EAAG,QAAO;AAC/D,SAAO;AACT;AAeO,SAAS,eAAe,MAAwB,QAA8G;AACnK,SAAO;AAAA,IACL,UAAU,OAAO,YAAY;AAAA,IAC7B,QAAQ,OAAO;AAAA,IACf,KAAK,OAAO;AAAA,IACZ,YAAY,OAAO,SAAS;AAAA,IAC5B,YAAY,KAAK,SAAS;AAAA,IAC1B,IAAI,KAAK,MAAM;AAAA,IACf,kBAAkB,KAAK,mBAAmB;AAAA,IAC1C,YAAY,KAAK,aAAa;AAAA,IAC9B,eAAe,KAAK,UAAU,UAAU;AAAA,IACxC,eAAe,KAAK,eAAe,CAAC,GAAG,KAAK,IAAI;AAAA,EAClD;AACF;AAEA,eAAsBG,UAAe,OAAY,OAAe,IAA0D;AACxH,QAAM,MAAW,IAAI,MAAM,MAAM,MAAM;AACvC,MAAI,OAAO;AACX,iBAAe,SAAwB;AACrC,WAAO,OAAO,MAAM,QAAQ;AAC1B,YAAM,QAAQ;AACd,cAAQ;AACR,UAAI,KAAK,IAAI,MAAM,GAAG,MAAM,KAAK,GAAG,KAAK;AAAA,IAC3C;AAAA,EACF;AACA,QAAM,QAAQ,IAAI,MAAM,KAAK,EAAE,QAAQ,KAAK,IAAI,KAAK,IAAI,GAAG,KAAK,GAAG,MAAM,MAAM,EAAE,GAAG,MAAM,OAAO,CAAC,CAAC;AACpG,SAAO;AACT;;;ADhMA,IAAM,kBAAkBC,GAAE,KAAK,CAAC,YAAY,cAAc,MAAM,CAAC;AAEjE,IAAM,2BAA2BA,GAAE,OAAO;AAAA,EACxC,OAAOA,GAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EACvB,UAAUA,GAAE,OAAO,EAAE,SAAS;AAAA,EAC9B,OAAOA,GAAE,OAAO,EAAE,SAAS;AAAA,EAC3B,eAAeA,GAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,QAAQ,GAAO;AAAA,EACtD,WAAWA,GAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,QAAQ,CAAC;AAAA,EACrD,mBAAmBA,GAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,QAAQ,EAAE;AAAA,EAC7D,YAAYA,GAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,QAAQ,CAAC;AAAA,EACrD,YAAYA,GAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,QAAQ,EAAE;AAAA,EACvD,aAAaA,GAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,QAAQ,CAAC;AAAA,EACrD,WAAW,gBAAgB,QAAQ,UAAU;AAAA,EAC7C,eAAeA,GAAE,QAAQ,EAAE,QAAQ,IAAI;AACzC,CAAC,EAAE,OAAO,WAAS,MAAM,YAAY,MAAM,OAAO;AAAA,EAChD,SAAS;AACX,CAAC;AAED,IAAM,4BAA4BA,GAAE,OAAO;AAAA,EACzC,SAASA,GAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EACzB,QAAQA,GAAE,OAAO,EAAE,SAAS;AAAA,EAC5B,KAAKA,GAAE,OAAO,EAAE,IAAI,EAAE,SAAS;AAAA,EAC/B,UAAUA,GAAE,OAAO,EAAE,SAAS;AAAA,EAC9B,YAAYA,GAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,QAAQ,EAAE;AAAA,EACtD,cAAcA,GAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,QAAQ,EAAE;AAAA,EACzD,YAAYA,GAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,QAAQ,CAAC;AAAA,EACrD,YAAYA,GAAE,QAAQ,EAAE,QAAQ,IAAI;AAAA,EACpC,mBAAmBA,GAAE,QAAQ,EAAE,QAAQ,IAAI;AAAA,EAC3C,eAAeA,GAAE,QAAQ,EAAE,QAAQ,IAAI;AACzC,CAAC;AAED,IAAM,+BAA+BA,GAAE,OAAO;AAAA,EAC5C,SAASA,GAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EACzB,UAAUA,GAAE,OAAO,EAAE,SAAS;AAAA,EAC9B,cAAcA,GAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,QAAQ,EAAE;AAAA,EACzD,OAAOA,GAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,QAAQ,CAAC;AAAA,EAC/C,eAAeA,GAAE,QAAQ,EAAE,QAAQ,IAAI;AACzC,CAAC;AAED,IAAM,gCAAgCA,GAAE,OAAO;AAAA,EAC7C,SAASA,GAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EACzB,QAAQA,GAAE,OAAO,EAAE,SAAS;AAAA,EAC5B,KAAKA,GAAE,OAAO,EAAE,IAAI,EAAE,SAAS;AAAA,EAC/B,UAAUA,GAAE,OAAO,EAAE,SAAS;AAAA,EAC9B,cAAcA,GAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,QAAQ,EAAE;AAAA,EACzD,YAAYA,GAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,QAAQ,CAAC;AAAA,EACpD,eAAeA,GAAE,QAAQ,EAAE,QAAQ,IAAI;AACzC,CAAC;AAmBD,SAAS,qBAAqB,UAAkB,OAAe,SAAmE;AAChI,SAAO,QAAQ,IAAI,aAAW;AAAA,IAC5B,cAAc;AAAA,IACd,iBAAiB;AAAA,IACjB,MAAM,SAAS,MAAM,GAAG,EAAE,CAAC,GAAG,KAAK,KAAK;AAAA,IACxC,OAAO,SAAS,MAAM,GAAG,EAAE,CAAC,GAAG,KAAK,KAAK;AAAA,IACzC,YAAY;AAAA,IACZ,iBAAiB,OAAO;AAAA,IACxB,eAAe,OAAO;AAAA,IACtB,cAAc,OAAO,UAAU;AAAA,IAC/B,cAAc,OAAO,eAAe;AAAA,IACpC,UAAU,OAAO,YAAY;AAAA,IAC7B,SAAS,OAAO,WAAW;AAAA,IAC3B,OAAO,OAAO,SAAS;AAAA,IACvB,aAAa,OAAO,cAAc;AAAA,IAClC,WAAW,OAAO,YAAY;AAAA,IAC9B,KAAK,OAAO,OAAO;AAAA,IACnB,aAAa,OAAO,cAAc;AAAA,IAClC,eAAe;AAAA,IACf,OAAO;AAAA,EACT,EAAE;AACJ;AAEA,SAAS,WAAW,MAAsE;AACxF,QAAM,aAAa,oBAAI,IAA4C;AACnE,aAAW,OAAO,MAAM;AACtB,UAAM,MAAM,OAAO,IAAI,mBAAmB,IAAI,YAAY,EAAE;AAC5D,QAAI,CAAC,IAAK;AACV,UAAM,OAAO,WAAW,IAAI,GAAG,KAAK,CAAC;AACrC,SAAK,KAAK,GAAG;AACb,eAAW,IAAI,KAAK,IAAI;AAAA,EAC1B;AACA,SAAO,CAAC,GAAG,WAAW,QAAQ,CAAC,EAAE,IAAI,CAAC,CAAC,UAAU,IAAI,MAAM;AACzD,UAAM,SAAS,KAAK,IAAI,SAAOC,YAAW,IAAI,YAAY,CAAC;AAC3D,UAAM,UAAU,KAAK,IAAI,SAAOA,YAAW,IAAI,YAAY,CAAC;AAC5D,UAAM,WAAW,KAAK,MAAM,GAAG,CAAC,EAAE,IAAI,SAAOA,YAAW,IAAI,YAAY,CAAC,EAAE,OAAO,CAAC,MAAmB,MAAM,IAAI;AAChH,UAAM,aAAa,oBAAI,IAAoB;AAC3C,eAAW,OAAO,MAAM;AACtB,YAAM,WAAW,OAAO,IAAI,YAAY,EAAE;AAC1C,UAAI,SAAU,YAAW,IAAI,WAAW,WAAW,IAAI,QAAQ,KAAK,KAAK,CAAC;AAAA,IAC5E;AACA,WAAO;AAAA,MACL,iBAAiB;AAAA,MACjB,cAAc,KAAK,OAAO,SAAO,IAAI,aAAa,EAAE;AAAA,MACpD,qBAAqBC,QAAO,MAAM,KAAK;AAAA,MACvC,eAAeA,QAAO,OAAO,KAAK;AAAA,MAClC,gCAAgC,SAAS,SAAS,KAAK,MAAM,SAAS,OAAO,CAAC,GAAG,MAAM,IAAI,GAAG,CAAC,IAAI,SAAS,MAAM,IAAI;AAAA,MACtH,gBAAgB,CAAC,GAAG,WAAW,QAAQ,CAAC,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,MAAM,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC,KAAK,KAAK,MAAM,GAAG,GAAG,KAAK,KAAK,GAAG,EAAE,KAAK,IAAI;AAAA,MACtI,kBAAkB,KAAK,OAAO,SAAO,IAAI,WAAW,EAAE;AAAA,IACxD;AAAA,EACF,CAAC;AACH;AAEA,SAAS,eAAe,MAAsE;AAC5F,QAAM,sBAAsB,oBAAI,IAAoB;AACpD,aAAW,UAAU,WAAW,IAAI,GAAG;AACrC,wBAAoB,IAAI,OAAO,OAAO,eAAe,GAAGD,YAAW,OAAO,8BAA8B,KAAK,CAAC;AAAA,EAChH;AACA,SAAO,KACJ,OAAO,SAAO,IAAI,aAAa,EAC/B,IAAI,SAAO;AACV,UAAM,UAAUA,YAAW,IAAI,YAAY,KAAK;AAChD,UAAM,YAAY,oBAAoB,IAAI,OAAO,IAAI,eAAe,CAAC,KAAK;AAC1E,UAAM,iBAAiB,CAAC,IAAI;AAC5B,UAAM,OAAOA,YAAW,IAAI,eAAe,KAAK;AAChD,WAAO;AAAA,MACL,iBAAiB,IAAI;AAAA,MACrB,iBAAiB,IAAI;AAAA,MACrB,eAAe,IAAI;AAAA,MACnB,UAAU,IAAI;AAAA,MACd,cAAc,IAAI;AAAA,MAClB,cAAc,IAAI;AAAA,MAClB,4BAA4B,YAAY,KAAK,IAAI,GAAG,YAAY,OAAO,IAAI;AAAA,MAC3E,aAAa,IAAI;AAAA,MACjB,WAAW,IAAI;AAAA,MACf,iBAAiB,QAAQ,IAAI,mBAAmB,iBAAiB,4BAA4B,UAAU,YAAY,4BAA4B;AAAA,IACjJ;AAAA,EACF,CAAC;AACL;AAEA,SAAS,YAAY,MAA0B,cAA6D;AAC1G,UAAQ,MAAM,kBAAkB,CAAC,GAAG,IAAI,YAAU;AAChD,UAAM,MAAM,OAAO,OAAO;AAC1B,UAAM,SAASE,iBAAgB,OAAO,UAAU,EAAE,KAAKC,eAAc,GAAG;AACxE,WAAO;AAAA,MACL,UAAU,OAAO,YAAY;AAAA,MAC7B,OAAO,OAAO,SAAS;AAAA,MACvB;AAAA,MACA;AAAA,MACA,SAAS,OAAO,WAAW;AAAA,MAC3B,WAAW,eAAe,WAAW,eAAe;AAAA,IACtD;AAAA,EACF,CAAC;AACH;AAEA,SAAS,YAAY,YAAqC,iBAA2G;AACnK,QAAM,oBAAoB,IAAI,KAAK,YAAY,YAAY,CAAC,GAAG,IAAI,OAAK,EAAE,KAAK,YAAY,EAAE,QAAQ,gBAAgB,GAAG,EAAE,KAAK,CAAC,CAAC;AACjI,QAAM,cAAc,IAAI,KAAK,YAAY,YAAY,CAAC,GAAG,QAAQ,OAAK,EAAE,KAAK,YAAY,EAAE,QAAQ,gBAAgB,GAAG,EAAE,MAAM,KAAK,EAAE,OAAO,OAAO,CAAC,CAAC;AACrJ,QAAM,OAAuC,CAAC;AAC9C,aAAW,EAAE,QAAQ,KAAK,KAAK,iBAAiB;AAC9C,eAAW,WAAW,KAAK,YAAY,CAAC,GAAG;AACzC,UAAI,QAAQ,QAAQ,KAAK,CAAC,QAAQ,KAAM;AACxC,YAAM,aAAa,QAAQ,KAAK,YAAY,EAAE,QAAQ,gBAAgB,GAAG,EAAE,KAAK;AAChF,YAAM,QAAQ,WAAW,MAAM,KAAK,EAAE,OAAO,UAAQ,KAAK,SAAS,CAAC;AACpE,YAAM,UAAU,MAAM,OAAO,UAAQ,YAAY,IAAI,IAAI,CAAC,EAAE;AAC5D,YAAM,UAAU,kBAAkB,IAAI,UAAU,KAAK,WAAW,KAAK,IAAI,GAAG,KAAK,KAAK,MAAM,SAAS,CAAC,CAAC;AACvG,UAAI,WAAW,WAAY;AAC3B,WAAK,KAAK;AAAA,QACR,iBAAiB,OAAO,YAAY;AAAA,QACpC,eAAeD,iBAAgB,OAAO,UAAU,EAAE,KAAKC,eAAc,OAAO,GAAG;AAAA,QAC/E,YAAY,OAAO,OAAO;AAAA,QAC1B,eAAe,QAAQ;AAAA,QACvB,oBAAoB,QAAQ;AAAA,QAC5B,iBAAiB,aAAa,iCAAiC;AAAA,QAC/D,OAAO,UAAU,QAAQ,MAAM,CAAC;AAAA,MAClC,CAAC;AAAA,IACH;AAAA,EACF;AACA,SAAO,KAAK,MAAM,GAAG,GAAG;AAC1B;AAEA,eAAe,aAAa,KAAyB,SAA0B,UAAoB,aAAwF;AACzL,SAAOC,UAAS,QAAQ,OAAO,YAAU,OAAO,GAAG,GAAG,GAAG,OAAO,QAAQ,UAAU;AAChF,QAAI;AACF,YAAM,OAAO,MAAM,IAAI,OAAO,KAAuB,gBAAgB,EAAE,KAAK,OAAO,IAAI,GAAG,IAAO;AACjG,YAAM,IAAI,UAAU,UAAU,GAAG,WAAW,IAAI,QAAQ,CAAC,IAAI,mBAAmB,YAAY,YAAY,CAAC,IAAI,QAAQ,CAAC,SAAS,IAAI;AACnI,aAAO,EAAE,QAAQ,KAAK;AAAA,IACxB,SAAS,KAAK;AACZ,eAAS,KAAK,8BAA8B,OAAO,GAAG,KAAK,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC,EAAE;AAC7G,aAAO;AAAA,IACT;AAAA,EACF,CAAC,EAAE,KAAK,WAAS,MAAM,OAAO,CAAC,SAAoE,SAAS,IAAI,CAAC;AACnH;AAEO,IAAM,kCAA0E;AAAA,EACrF,IAAI;AAAA,EACJ,OAAO;AAAA,EACP,aAAa;AAAA,EACb,aAAa;AAAA,EACb,MAAM,IAAI,OAA2B,KAAsD;AACzF,UAAM,IAAI,UAAU,cAAc,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AACvD,UAAM,WAAqB,CAAC;AAC5B,QAAI;AACJ,QAAI,YAA+C;AACnD,QAAI,aAA0C;AAE9C,QAAI,MAAM,UAAU;AAClB,mBAAa,MAAM,IAAI,OAAO,KAA2B,gBAAgB;AAAA,QACvE,OAAO,MAAM;AAAA,QACb,UAAU,MAAM;AAAA,QAChB,YAAY,MAAM;AAAA,QAClB,WAAW,MAAM;AAAA,MACnB,GAAG,IAAO;AACV,aAAO,qBAAqB,MAAM,UAAU,MAAM,OAAO,WAAW,OAAO;AAC3E,YAAM,IAAI,UAAU,UAAU,wBAAwB,wBAAwB,UAAU;AAAA,IAC1F,OAAO;AACL,kBAAY,MAAM,IAAI,OAAO,KAAiC,kBAAkB;AAAA,QAC9E,OAAO,MAAM;AAAA,QACb,OAAO,MAAM;AAAA,QACb,eAAe,MAAM;AAAA,QACrB,WAAW,MAAM;AAAA,QACjB,mBAAmB,MAAM;AAAA,QACzB,aAAa,MAAM;AAAA,QACnB,WAAW,MAAM;AAAA,QACjB,SAAS;AAAA,MACX,GAAG,GAAO;AACV,aAAO,cAAc,SAAS;AAC9B,YAAM,IAAI,UAAU,UAAU,sBAAsB,+BAA+B,SAAS;AAC5F,YAAM,IAAI,UAAU,SAAS,iBAAiB,yBAAyB,uBAAuB,IAAI;AAClG,eAAS,KAAK,GAAG,UAAU,QAAQ;AAAA,IACrC;AAEA,UAAM,cAAc,eAAe,IAAI;AACvC,UAAM,WAAW,YAAY,MAAM,GAAG,MAAM,aAAa,KAAK,IAAI,GAAG,MAAM,WAAW,IAAI,MAAM,SAAS,CAAC;AAC1G,UAAM,WAAW,MAAMA,UAAS,UAAU,GAAG,OAAO,KAAK,UAAU;AACjE,UAAI;AACF,cAAM,SAAS,MAAM,IAAI,OAAO,KAA2B,eAAe;AAAA,UACxE,cAAc,IAAI;AAAA,UAClB,UAAU,IAAI;AAAA,UACd,gBAAgB,MAAM,aAAa;AAAA,UACnC,YAAY,KAAK,IAAI,GAAG,MAAM,UAAU;AAAA,QAC1C,GAAG,IAAO;AACV,cAAM,IAAI,UAAU,UAAU,GAAG,IAAI,aAAa,YAAY,wBAAwB,QAAQ,CAAC,IAAI,OAAO,IAAI,aAAa,EAAE,YAAY,EAAE,QAAQ,eAAe,GAAG,CAAC,SAAS,MAAM;AACrL,eAAO,EAAE,KAAK,QAAQ,OAAO,GAAG;AAAA,MAClC,SAAS,KAAK;AACZ,cAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC/D,iBAAS,KAAK,gCAAgC,IAAI,aAAa,KAAK,OAAO,EAAE;AAC7E,eAAO,EAAE,KAAK,QAAQ,MAAM,OAAO,QAAQ;AAAA,MAC7C;AAAA,IACF,CAAC;AAED,UAAM,cAAc,SAAS,IAAI,CAAC,EAAE,KAAK,QAAQ,MAAM,OAAO;AAAA,MAC5D,iBAAiB,IAAI;AAAA,MACrB,iBAAiB,IAAI;AAAA,MACrB,eAAe,IAAI;AAAA,MACnB,UAAU,QAAQ,YAAY,IAAI;AAAA,MAClC,cAAc,QAAQ,UAAU,IAAI;AAAA,MACpC,cAAc,QAAQ,eAAe,IAAI;AAAA,MACzC,aAAa,QAAQ,WAAW,IAAI;AAAA,MACpC,gBAAgB,QAAQ,gBAAgB,CAAC,GAAG,IAAI,OAAK,GAAG,EAAE,KAAK,KAAK,EAAE,KAAK,GAAG,EAAE,KAAK,IAAI;AAAA,MACzF,mBAAmB,QAAQ,mBAAmB,CAAC,GAAG,IAAI,OAAK,GAAG,EAAE,OAAO,KAAK,EAAE,SAAS,EAAE,EAAE,KAAK,IAAI;AAAA,MACpG,gBAAgB,QAAQ,iBAAiB;AAAA,MACzC;AAAA,IACF,EAAE;AACF,UAAM,UAAU,WAAW,IAAI;AAC/B,UAAM,IAAI,UAAU,SAAS,oBAAoB,oBAAoB,CAAC,gBAAgB,mBAAmB,QAAQ,SAAS,cAAc,mBAAmB,iBAAiB,gBAAgB,gBAAgB,YAAY,WAAW,SAAS,eAAe,aAAa,OAAO,eAAe,iBAAiB,OAAO,GAAG,IAAI;AAC7T,UAAM,IAAI,UAAU,SAAS,kBAAkB,sBAAsB,CAAC,mBAAmB,mBAAmB,iBAAiB,YAAY,gBAAgB,gBAAgB,8BAA8B,eAAe,aAAa,iBAAiB,GAAG,WAAW;AAClQ,UAAM,IAAI,UAAU,SAAS,wBAAwB,wBAAwB,CAAC,mBAAmB,mBAAmB,iBAAiB,YAAY,gBAAgB,gBAAgB,eAAe,iBAAiB,oBAAoB,kBAAkB,OAAO,GAAG,WAAW;AAC5Q,UAAM,IAAI,UAAU,UAAU,4BAA4B,iBAAiB,EAAE,OAAO,WAAW,YAAY,MAAM,aAAa,aAAa,SAAS,SAAS,CAAC;AAC9J,UAAM,IAAI,UAAU,UAAU,SAAS,YAAY;AAAA,MACjD,sBAAsB,MAAM,KAAK;AAAA,MACjC;AAAA,MACA,YAAY,QAAQ,IAAI,SAAO,IAAI,eAAe,EAAE,KAAK,IAAI,CAAC;AAAA,MAC9D;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,EAAE,KAAK,IAAI,CAAC;AAEZ,UAAM,UAAU,GAAG,YAAY,MAAM,qCAAqC,QAAQ,MAAM,eAAe,YAAY,OAAO,SAAO,CAAC,IAAI,KAAK,EAAE,MAAM;AACnJ,UAAM,aAAa,MAAM,IAAI,UAAU,UAAU,eAAe,eAAe,qBAAqB;AAAA,MAClG,OAAO;AAAA,MACP,UAAU,GAAG,MAAM,KAAK,GAAG,MAAM,WAAW,SAAM,MAAM,QAAQ,KAAK,MAAM,QAAQ,SAAM,MAAM,KAAK,KAAK,EAAE;AAAA,MAC3G;AAAA,MACA;AAAA,MACA,QAAQ;AAAA,QACN,EAAE,OAAO,qBAAqB,SAAS,CAAC,mBAAmB,gBAAgB,uBAAuB,iBAAiB,kCAAkC,kBAAkB,kBAAkB,GAAG,MAAM,QAAQ;AAAA,QAC1M,EAAE,OAAO,yBAAyB,SAAS,CAAC,mBAAmB,mBAAmB,iBAAiB,YAAY,gBAAgB,gBAAgB,8BAA8B,iBAAiB,GAAG,MAAM,YAAY,MAAM,GAAG,GAAG,EAAE;AAAA,QACjO,EAAE,OAAO,oBAAoB,SAAS,CAAC,mBAAmB,iBAAiB,iBAAiB,oBAAoB,OAAO,GAAG,MAAM,YAAY;AAAA,MAC9I;AAAA,IACF,CAAC,CAAC;AACF,UAAM,SAAS,SAAS,SAAS,YAAY;AAC7C,UAAM,SAAS,EAAE,SAAS,QAAQ,QAAQ,aAAa,YAAY,QAAQ,kBAAkB,YAAY,OAAO,SAAO,CAAC,IAAI,KAAK,EAAE,OAAO;AAC1I,UAAM,IAAI,UAAU,cAAc,QAAQ,QAAQ,UAAU,CAAC,CAAC;AAC9D,WAAO,EAAE,OAAO,mBAAmB,SAAS,QAAQ,QAAQ,UAAU,QAAQ,CAAC,GAAG,WAAW;AAAA,EAC/F;AACF;AAEO,IAAM,mCAA4E;AAAA,EACvF,IAAI;AAAA,EACJ,OAAO;AAAA,EACP,aAAa;AAAA,EACb,aAAa;AAAA,EACb,MAAM,IAAI,OAA4B,KAAsD;AAC1F,UAAM,IAAI,UAAU,cAAc,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AACvD,UAAM,WAAqB,CAAC;AAC5B,UAAM,eAAeF,iBAAgB,MAAM,UAAU,MAAM,OAAO,IAAI;AACtE,UAAM,OAAO,MAAM,IAAI,OAAO,KAAkB,iBAAiB;AAAA,MAC/D,OAAO,MAAM;AAAA,MACb,UAAU,MAAM;AAAA,MAChB,UAAU;AAAA,MACV,cAAc;AAAA,MACd,QAAQ;AAAA,IACV,GAAG,IAAO;AACV,UAAM,IAAI,UAAU,UAAU,iBAAiB,iBAAiB,IAAI;AAEpE,QAAI,MAA0B;AAC9B,QAAI,MAAM,YAAY;AACpB,UAAI;AACF,cAAM,MAAM,IAAI,OAAO,KAAkB,iBAAiB;AAAA,UACxD,OAAO,MAAM;AAAA,UACb,UAAU,MAAM;AAAA,UAChB,cAAc,MAAM;AAAA,UACpB,QAAQ;AAAA,QACV,GAAG,IAAO;AACV,cAAM,IAAI,UAAU,UAAU,gBAAgB,gBAAgB,GAAG;AAAA,MACnE,SAAS,KAAK;AACZ,iBAAS,KAAK,6BAA6B,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC,EAAE;AAAA,MAC/F;AAAA,IACF;AAEA,UAAM,UAAU,YAAY,MAAM,YAAY,EAAE,MAAM,GAAG,MAAM,UAAU;AACzE,UAAM,kBAAkB,KAAK,kBAAkB,CAAC,GAAG,MAAM,GAAG,MAAM,UAAU;AAC5E,UAAM,eAAe,MAAM,MACvB,EAAE,UAAU,GAAG,OAAO,eAAe,KAAK,MAAM,KAAK,QAAQC,eAAc,MAAM,GAAG,EAAE,IACtF,eAAe,KAAK,YAAU,iBAAiBD,iBAAgB,OAAO,UAAU,EAAE,KAAKC,eAAc,OAAO,GAAG,OAAO,YAAY;AACtI,UAAM,oBAAoB,eACvB,OAAO,YAAU,OAAO,OAAO,OAAO,QAAQ,cAAc,GAAG,EAC/D,OAAO,YAAU,CAAC,iBAAiBD,iBAAgB,OAAO,UAAU,EAAE,KAAKC,eAAc,OAAO,GAAG,OAAO,YAAY,EACtH,MAAM,GAAG,MAAM,UAAU;AAE5B,UAAM,cAAc,eAAe,MAAM,aAAa,KAAK,CAAC,YAAY,GAAG,UAAU,QAAQ,IAAI,CAAC;AAClG,UAAM,kBAAkB,MAAM,aAAa,IAAI,MAAM,aAAa,KAAK,mBAAmB,UAAU,YAAY,IAAI,CAAC;AACrH,UAAM,aAAa,YAAY,CAAC,GAAG,QAAQ;AAC3C,UAAM,WAAW;AAAA,MACf,GAAG,YAAY,IAAI,CAAC,EAAE,QAAQ,KAAK,MAAM,eAAe,MAAM,EAAE,KAAK,OAAO,OAAO,IAAI,QAAQD,iBAAgB,OAAO,UAAU,EAAE,KAAKC,eAAc,OAAO,GAAG,GAAG,UAAU,OAAO,UAAU,OAAO,OAAO,MAAM,CAAC,CAAC;AAAA,MACnN,GAAG,gBAAgB,IAAI,CAAC,EAAE,QAAQ,KAAK,MAAM,eAAe,MAAM,EAAE,KAAK,OAAO,OAAO,IAAI,QAAQD,iBAAgB,OAAO,UAAU,EAAE,KAAKC,eAAc,OAAO,GAAG,GAAG,UAAU,OAAO,UAAU,OAAO,OAAO,MAAM,CAAC,CAAC;AAAA,IACzN;AACA,UAAM,OAAO,YAAY,YAAY,eAAe;AACpD,UAAM,YAAY,aAAa,GAAG;AAClC,UAAM,UAAU,KAAK,YAAY,aAAa,CAAC,GAAG,IAAI,CAAC,UAAU,WAAW;AAAA,MAC1E,mBAAmB,QAAQ;AAAA,MAC3B,eAAe,SAAS,QAAQ;AAAA,MAChC,KAAK,SAAS,QAAQ;AAAA,MACtB,QAAQA,eAAc,SAAS,QAAQ,EAAE;AAAA,MACzC,WAAW,eAAeA,eAAc,SAAS,QAAQ,EAAE,MAAM,eAAe;AAAA,IAClF,EAAE;AACF,UAAM,IAAI,UAAU,SAAS,uBAAuB,uBAAuB,CAAC,YAAY,SAAS,OAAO,UAAU,WAAW,WAAW,GAAG,OAAO;AAClJ,UAAM,IAAI,UAAU,SAAS,uBAAuB,uBAAuB,CAAC,YAAY,UAAU,OAAO,cAAc,cAAc,MAAM,oBAAoB,cAAc,iBAAiB,cAAc,GAAG,QAAQ;AACvN,UAAM,IAAI,UAAU,SAAS,oBAAoB,oBAAoB,CAAC,mBAAmB,iBAAiB,cAAc,iBAAiB,sBAAsB,mBAAmB,OAAO,GAAG,IAAI;AAChM,UAAM,IAAI,UAAU,SAAS,qBAAqB,qBAAqB,CAAC,YAAY,UAAU,YAAY,kBAAkB,gBAAgB,iBAAiB,YAAY,GAAG,SAAS;AACrL,UAAM,IAAI,UAAU,SAAS,6BAA6B,6BAA6B,CAAC,qBAAqB,iBAAiB,OAAO,UAAU,WAAW,GAAG,MAAM;AACnK,UAAM,IAAI,UAAU,UAAU,4BAA4B,iBAAiB,EAAE,OAAO,MAAM,KAAK,SAAS,UAAU,MAAM,WAAW,QAAQ,SAAS,CAAC;AACrJ,UAAM,IAAI,UAAU,UAAU,gBAAgB,YAAY;AAAA,MACxD,4BAA4B,MAAM,OAAO;AAAA,MACzC;AAAA,MACA,WAAW,gBAAgB,MAAM,OAAO,eAAe;AAAA,MACvD,aAAa,MAAM,YAAY,eAAe;AAAA,MAC9C;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,EAAE,KAAK,IAAI,CAAC;AACZ,UAAM,UAAU,GAAG,QAAQ,MAAM,qBAAqB,SAAS,MAAM,qBAAqB,KAAK,MAAM,kBAAkB,UAAU,MAAM;AACvI,UAAM,aAAa,MAAM,IAAI,UAAU,UAAU,eAAe,eAAe,qBAAqB;AAAA,MAClG,OAAO;AAAA,MACP,UAAU,GAAG,MAAM,OAAO,GAAG,MAAM,WAAW,SAAM,MAAM,QAAQ,KAAK,EAAE;AAAA,MACzE;AAAA,MACA;AAAA,MACA,QAAQ;AAAA,QACN,EAAE,OAAO,mBAAmB,SAAS,CAAC,YAAY,SAAS,UAAU,WAAW,GAAG,MAAM,QAAQ;AAAA,QACjG,EAAE,OAAO,mBAAmB,SAAS,CAAC,YAAY,UAAU,MAAM,cAAc,iBAAiB,cAAc,GAAG,MAAM,SAAS;AAAA,QACjI,EAAE,OAAO,gBAAgB,SAAS,CAAC,mBAAmB,iBAAiB,sBAAsB,mBAAmB,OAAO,GAAG,MAAM,KAAK,MAAM,GAAG,EAAE,EAAE;AAAA,QAClJ,EAAE,OAAO,iBAAiB,SAAS,CAAC,YAAY,UAAU,YAAY,eAAe,GAAG,MAAM,UAAU,MAAM,GAAG,EAAE,EAAE;AAAA,MACvH;AAAA,IACF,CAAC,CAAC;AACF,UAAM,SAAS,SAAS,SAAS,YAAY;AAC7C,UAAM,SAAS,EAAE,SAAS,QAAQ,QAAQ,OAAO,SAAS,QAAQ,MAAM,KAAK,QAAQ,WAAW,UAAU,QAAQ,aAAa,OAAO,OAAO;AAC7I,UAAM,IAAI,UAAU,cAAc,QAAQ,QAAQ,UAAU,CAAC,CAAC;AAC9D,WAAO,EAAE,OAAO,mBAAmB,SAAS,QAAQ,QAAQ,UAAU,QAAQ,CAAC,GAAG,WAAW;AAAA,EAC/F;AACF;AAEO,IAAM,sCAAkF;AAAA,EAC7F,IAAI;AAAA,EACJ,OAAO;AAAA,EACP,aAAa;AAAA,EACb,aAAa;AAAA,EACb,MAAM,IAAI,OAA+B,KAAsD;AAC7F,UAAM,IAAI,UAAU,cAAc,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AACvD,UAAM,WAAqB,CAAC;AAC5B,UAAM,MAAM,MAAM,IAAI,OAAO,KAAkB,iBAAiB;AAAA,MAC9D,OAAO,MAAM;AAAA,MACb,UAAU,MAAM;AAAA,MAChB,cAAc,MAAM;AAAA,MACpB,OAAO,MAAM;AAAA,MACb,QAAQ;AAAA,IACV,GAAG,GAAO;AACV,UAAM,IAAI,UAAU,UAAU,gBAAgB,gBAAgB,GAAG;AACjE,UAAM,YAAY,aAAa,GAAG;AAClC,UAAME,cAAa,iBAAiB,SAAS;AAC7C,UAAM,WAAW,oBAAI,IAA4C;AACjE,eAAW,OAAO,WAAW;AAC3B,YAAM,OAAO,SAAS,IAAI,OAAO,IAAI,MAAM,CAAC,KAAK,CAAC;AAClD,WAAK,KAAK,GAAG;AACb,eAAS,IAAI,OAAO,IAAI,MAAM,GAAG,IAAI;AAAA,IACvC;AACA,UAAM,cAAc,CAAC,GAAG,SAAS,QAAQ,CAAC,EAAE,IAAI,CAAC,CAAC,QAAQ,IAAI,OAAO;AAAA,MACnE,qBAAqB;AAAA,MACrB,gBAAgB,KAAK;AAAA,MACrB,kBAAkB,KAAK,MAAM,GAAG,CAAC,EAAE,IAAI,SAAO,IAAI,QAAQ,EAAE,KAAK,KAAK;AAAA,MACtE,gBAAgB,CAAC,GAAG,IAAI,IAAI,KAAK,IAAI,SAAO,IAAI,aAAa,EAAE,OAAO,OAAO,CAAC,CAAC,EAAE,MAAM,GAAG,CAAC,EAAE,KAAK,IAAI;AAAA,MACtG,OAAO,UAAU,KAAK,IAAI,SAAO,GAAG,IAAI,QAAQ,IAAI,IAAI,cAAc,EAAE,EAAE,KAAK,GAAG,GAAG,EAAE;AAAA,IACzF,EAAE,EAAE,KAAK,CAAC,GAAG,MAAM,OAAO,EAAE,cAAc,IAAI,OAAO,EAAE,cAAc,CAAC;AAEtE,UAAM,IAAI,UAAU,SAAS,qBAAqB,qBAAqB,CAAC,YAAY,UAAU,YAAY,kBAAkB,gBAAgB,iBAAiB,YAAY,GAAG,SAAS;AACrL,UAAM,IAAI,UAAU,SAAS,sBAAsB,sBAAsB,CAAC,UAAU,qBAAqB,oBAAoB,aAAa,GAAGA,WAAU;AACvJ,UAAM,IAAI,UAAU,SAAS,mBAAmB,mBAAmB,CAAC,uBAAuB,kBAAkB,oBAAoB,kBAAkB,OAAO,GAAG,WAAW;AACxK,UAAM,IAAI,UAAU,UAAU,sBAAsB,iBAAiB,EAAE,OAAO,KAAK,WAAW,YAAAA,aAAY,YAAY,CAAC;AACvH,UAAM,IAAI,UAAU,UAAU,gBAAgB,mBAAmB;AAAA,MAC/D,0BAA0B,MAAM,OAAO;AAAA,MACvC;AAAA,MACA,aAAa,MAAM,YAAY,eAAe;AAAA,MAC9C;AAAA,MACA;AAAA,MACA,GAAG,YAAY,IAAI,SAAO,KAAK,IAAI,mBAAmB,YAAY,IAAI,cAAc,iCAAiC,IAAI,gBAAgB,EAAE;AAAA,MAC3I;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,EAAE,KAAK,IAAI,CAAC;AACZ,UAAM,UAAU,GAAG,UAAU,MAAM,+BAA+B,YAAY,MAAM;AACpF,UAAM,aAAa,MAAM,IAAI,UAAU,UAAU,eAAe,eAAe,qBAAqB;AAAA,MAClG,OAAO;AAAA,MACP,UAAU,GAAG,MAAM,OAAO,GAAG,MAAM,WAAW,SAAM,MAAM,QAAQ,KAAK,EAAE;AAAA,MACzE;AAAA,MACA;AAAA,MACA,QAAQ;AAAA,QACN,EAAE,OAAO,eAAe,SAAS,CAAC,uBAAuB,kBAAkB,oBAAoB,kBAAkB,OAAO,GAAG,MAAM,YAAY;AAAA,QAC7I,EAAE,OAAO,aAAa,SAAS,CAAC,YAAY,UAAU,YAAY,eAAe,GAAG,MAAM,UAAU,MAAM,GAAG,GAAG,EAAE;AAAA,QAClH,EAAE,OAAO,kBAAkB,SAAS,CAAC,UAAU,qBAAqB,oBAAoB,aAAa,GAAG,MAAMA,YAAW;AAAA,MAC3H;AAAA,IACF,CAAC,CAAC;AACF,UAAM,SAAS,EAAE,WAAW,UAAU,QAAQ,UAAU,YAAY,QAAQ,eAAeA,YAAW,OAAO;AAC7G,UAAM,IAAI,UAAU,cAAc,aAAa,QAAQ,UAAU,CAAC,CAAC;AACnE,WAAO,EAAE,OAAO,uBAAuB,SAAS,QAAQ,aAAa,QAAQ,UAAU,QAAQ,CAAC,GAAG,WAAW;AAAA,EAChH;AACF;AAEO,IAAM,uCAAoF;AAAA,EAC/F,IAAI;AAAA,EACJ,OAAO;AAAA,EACP,aAAa;AAAA,EACb,aAAa;AAAA,EACb,MAAM,IAAI,OAAgC,KAAsD;AAC9F,UAAM,IAAI,UAAU,cAAc,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AACvD,UAAM,WAAqB,CAAC;AAC5B,UAAM,eAAeH,iBAAgB,MAAM,UAAU,MAAM,OAAO,IAAI;AACtE,UAAM,OAAO,MAAM,IAAI,OAAO,KAAkB,iBAAiB;AAAA,MAC/D,OAAO,MAAM;AAAA,MACb,UAAU,MAAM;AAAA,MAChB,UAAU;AAAA,MACV,cAAc;AAAA,MACd,QAAQ;AAAA,IACV,GAAG,IAAO;AACV,UAAM,IAAI,UAAU,UAAU,iBAAiB,iBAAiB,IAAI;AACpE,QAAI,MAA0B;AAC9B,QAAI;AACF,YAAM,MAAM,IAAI,OAAO,KAAkB,iBAAiB;AAAA,QACxD,OAAO,MAAM;AAAA,QACb,UAAU,MAAM;AAAA,QAChB,cAAc,MAAM;AAAA,QACpB,QAAQ;AAAA,MACV,GAAG,IAAO;AACV,YAAM,IAAI,UAAU,UAAU,gBAAgB,gBAAgB,GAAG;AAAA,IACnE,SAAS,KAAK;AACZ,eAAS,KAAK,6BAA6B,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC,EAAE;AAAA,IAC/F;AAEA,UAAM,aAAa,KAAK,YAAY,aAAa,CAAC,GAAG,IAAI,CAAC,UAAU,UAAU;AAC5E,YAAM,SAASC,eAAc,SAAS,QAAQ,EAAE;AAChD,aAAO;AAAA,QACL,mBAAmB,QAAQ;AAAA,QAC3B,eAAe,SAAS,QAAQ;AAAA,QAChC,KAAK,SAAS,QAAQ;AAAA,QACtB;AAAA,QACA,WAAW,eAAe,WAAW,eAAe;AAAA,MACtD;AAAA,IACF,CAAC;AACD,UAAM,eAAe,eAAe,KAAK,YAAY,IAAI;AACzD,UAAM,YAAY,aAAa,IAAI,CAAC,UAAU,WAAW;AAAA,MACvD,UAAU,QAAQ;AAAA,MAClB,YAAY,iBAAiB,QAAQ;AAAA,MACrC;AAAA,MACA,kBAAkB,SAAS,SAAS,MAAM,GAAG,SAAS,MAAM,GAAG,GAAG,CAAC,QAAQ;AAAA,IAC7E,EAAE;AACF,UAAM,YAAY,aAAa,GAAG;AAClC,UAAM,mBAAmB,KAAK,YAAY,aAAa,CAAC,GACrD,OAAO,cAAY,SAAS,IAAI,EAChC,IAAI,CAAC,UAAU,WAAW,EAAE,UAAU,QAAQ,GAAG,OAAO,SAAS,MAAM,KAAK,SAAS,MAAM,QAAQA,eAAc,SAAS,IAAI,EAAE,EAAE,EAClI,MAAM,GAAG,MAAM,UAAU;AAC5B,UAAM,qBAAqB,MAAM,aAAa,IAAI,MAAM,aAAa,KAAK,iBAAiB,UAAU,UAAU,IAAI,CAAC;AACpH,UAAM,gBAAgB,mBAAmB,IAAI,CAAC,EAAE,QAAQ,KAAK,MAAM,eAAe,MAAM,EAAE,KAAK,OAAO,OAAO,IAAI,QAAQD,iBAAgB,OAAO,UAAU,EAAE,KAAKC,eAAc,OAAO,GAAG,GAAG,UAAU,OAAO,UAAU,OAAO,OAAO,MAAM,CAAC,CAAC;AAC7O,UAAM,eAAe;AAAA,MACnB;AAAA,QACE,OAAO;AAAA,QACP,UAAU;AAAA,QACV,gBAAgB,UAAU,CAAC,GAAG,YAAY,MAAM;AAAA,MAClD;AAAA,MACA;AAAA,QACE,OAAO;AAAA,QACP,UAAU;AAAA,QACV,gBAAgB,UAAU,OAAO,SAAO,CAAC,YAAY,SAAS,EAAE,SAAS,OAAO,IAAI,UAAU,CAAC,CAAC,EAAE,IAAI,SAAO,IAAI,QAAQ,EAAE,MAAM,GAAG,CAAC,EAAE,KAAK,KAAK;AAAA,MACnJ;AAAA,MACA;AAAA,QACE,OAAO;AAAA,QACP,UAAU;AAAA,QACV,gBAAgB,UAAU,IAAI,SAAO,GAAG,IAAI,MAAM,KAAK,IAAI,aAAa,EAAE,EAAE,MAAM,GAAG,CAAC,EAAE,KAAK,KAAK;AAAA,MACpG;AAAA,MACA;AAAA,QACE,OAAO;AAAA,QACP,UAAU;AAAA,QACV,gBAAgB,UAAU,MAAM,GAAG,CAAC,EAAE,IAAI,SAAO,IAAI,QAAQ,EAAE,KAAK,KAAK;AAAA,MAC3E;AAAA,IACF;AACA,UAAM,IAAI,UAAU,SAAS,6BAA6B,6BAA6B,CAAC,qBAAqB,iBAAiB,OAAO,UAAU,WAAW,GAAG,SAAS;AACtK,UAAM,IAAI,UAAU,SAAS,kCAAkC,sBAAsB,CAAC,YAAY,cAAc,YAAY,kBAAkB,GAAG,SAAS;AAC1J,UAAM,IAAI,UAAU,SAAS,yBAAyB,yBAAyB,CAAC,SAAS,YAAY,gBAAgB,GAAG,YAAY;AACpI,UAAM,IAAI,UAAU,SAAS,qBAAqB,qBAAqB,CAAC,YAAY,UAAU,YAAY,kBAAkB,gBAAgB,iBAAiB,YAAY,GAAG,SAAS;AACrL,UAAM,IAAI,UAAU,SAAS,gCAAgC,sBAAsB,CAAC,YAAY,UAAU,OAAO,cAAc,cAAc,MAAM,oBAAoB,cAAc,iBAAiB,cAAc,GAAG,aAAa;AACpO,UAAM,IAAI,UAAU,UAAU,iCAAiC,iBAAiB,EAAE,OAAO,MAAM,KAAK,WAAW,WAAW,cAAc,eAAe,SAAS,CAAC;AACjK,UAAM,IAAI,UAAU,UAAU,yBAAyB,4BAA4B;AAAA,MACjF,iCAAiC,MAAM,OAAO;AAAA,MAC9C;AAAA,MACA,yBAAyB,KAAK,YAAY,WAAW,QAAQ,IAAI;AAAA,MACjE,iBAAiB,eAAe,UAAU,KAAK,SAAO,IAAI,SAAS,IAAI,QAAQ,OAAO,sBAAsB;AAAA,MAC5G;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,GAAG,aAAa,IAAI,SAAO,KAAK,IAAI,KAAK,KAAK,IAAI,QAAQ,EAAE;AAAA,MAC5D;AAAA,MACA;AAAA,MACA,GAAG,UAAU,MAAM,GAAG,CAAC,EAAE,IAAI,SAAO,KAAK,IAAI,UAAU,KAAK,IAAI,QAAQ,EAAE;AAAA,MAC1E;AAAA,MACA;AAAA,MACA,GAAG,UAAU,MAAM,GAAG,CAAC,EAAE,IAAI,SAAO,KAAK,IAAI,MAAM,KAAK,IAAI,aAAa,EAAE;AAAA,IAC7E,EAAE,KAAK,IAAI,CAAC;AACZ,UAAM,UAAU,GAAG,UAAU,MAAM,2BAA2B,UAAU,MAAM,oBAAoB,UAAU,MAAM,mBAAmB,cAAc,MAAM;AACzJ,UAAM,aAAa,MAAM,IAAI,UAAU,UAAU,eAAe,eAAe,qBAAqB;AAAA,MAClG,OAAO;AAAA,MACP,UAAU,GAAG,MAAM,OAAO,GAAG,MAAM,WAAW,SAAM,MAAM,QAAQ,KAAK,EAAE;AAAA,MACzE;AAAA,MACA;AAAA,MACA,QAAQ;AAAA,QACN,EAAE,OAAO,qBAAqB,SAAS,CAAC,SAAS,YAAY,gBAAgB,GAAG,MAAM,aAAa;AAAA,QACnG,EAAE,OAAO,yBAAyB,SAAS,CAAC,qBAAqB,iBAAiB,UAAU,WAAW,GAAG,MAAM,UAAU;AAAA,QAC1H,EAAE,OAAO,kBAAkB,SAAS,CAAC,YAAY,cAAc,UAAU,GAAG,MAAM,UAAU;AAAA,QAC5F,EAAE,OAAO,kBAAkB,SAAS,CAAC,YAAY,UAAU,YAAY,eAAe,GAAG,MAAM,UAAU,MAAM,GAAG,EAAE,EAAE;AAAA,MACxH;AAAA,IACF,CAAC,CAAC;AACF,UAAM,SAAS,SAAS,UAAU,CAAC,KAAK,YAAY,WAAW,YAAY;AAC3E,UAAM,SAAS,EAAE,WAAW,UAAU,QAAQ,eAAe,UAAU,QAAQ,WAAW,UAAU,QAAQ,wBAAwB,cAAc,OAAO;AACzJ,UAAM,IAAI,UAAU,cAAc,QAAQ,QAAQ,UAAU,CAAC,CAAC;AAC9D,WAAO,EAAE,OAAO,8BAA8B,SAAS,QAAQ,QAAQ,UAAU,QAAQ,CAAC,GAAG,WAAW;AAAA,EAC1G;AACF;;;ANrlBA,IAAM,cAAc;AAAA,EAClB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEO,SAAS,0BAA2F;AACzG,SAAO,YAAY,IAAI,CAAC,EAAE,IAAI,OAAO,YAAY,OAAO,EAAE,IAAI,OAAO,YAAY,EAAE;AACrF;AAEO,SAAS,mBAAmB,IAAqC;AACtE,QAAM,aAAa,YAAY,KAAK,SAAO,IAAI,OAAO,EAAE;AACxD,MAAI,CAAC,WAAY,OAAM,IAAI,MAAM,qBAAqB,EAAE,iBAAiB,YAAY,IAAI,SAAO,IAAI,EAAE,EAAE,KAAK,IAAI,CAAC,EAAE;AACpH,SAAO;AACT;AAEA,eAAsB,YAAY,IAAY,UAAmC,UAA8B,CAAC,GAAgC;AAC9I,QAAM,aAAa,mBAAmB,EAAE;AACxC,QAAM,QAAQ,WAAW,YAAY,MAAM,QAAQ;AACnD,QAAM,SAAS,QAAQ,QAAQ,KAAK,KAAK,QAAQ,IAAI,qBAAqB,KAAK;AAC/E,MAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,oGAAoG;AACjI,QAAM,SAAS,QAAQ,QAAQ,KAAK,KAAK,QAAQ,IAAI,qBAAqB,KAAK,KAAK;AACpF,QAAM,YAAY,MAAM,eAAe,OAAO,WAAW,IAAI,WAAW,OAAO,OAAkC,QAAQ,WAAW,QAAQ,KAAK;AACjJ,QAAM,SAAS,IAAI,mBAAmB,QAAQ,QAAQ,QAAQ,SAAS;AACvE,MAAI;AACF,WAAO,MAAM,WAAW,IAAI,OAAO;AAAA,MACjC,OAAO,UAAU;AAAA,MACjB,WAAW,UAAU;AAAA,MACrB;AAAA,MACA;AAAA,MACA,QAAQ,QAAQ;AAAA,IAClB,CAAC;AAAA,EACH,SAAS,KAAK;AACZ,UAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC/D,UAAM,UAAU,UAAU,WAAW,cAAc,KAAK,WAAW,KAAK;AAAA;AAAA,EAAO,OAAO;AAAA,CAAI;AAC1F,UAAM,UAAU,cAAc,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC;AACzD,UAAM;AAAA,EACR;AACF;","names":["z","z","z","z","z","competitorRows","z","normalizeDomain","domainFromUrl","numberFrom","median","mapLimit","z","numberFrom","median","normalizeDomain","domainFromUrl","mapLimit","sourceRows"]}