papermark 0.6.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/commands/analytics.ts","../src/config.ts","../src/debug.ts","../src/runtime.ts","../src/client.ts","../src/output.ts","../src/exit.ts","../src/commands/auth.ts","../src/oauth.ts","../src/commands/config.ts","../src/commands/datarooms.ts","../src/commands/doctor.ts","../src/commands/documents.ts","../src/commands/folders.ts","../src/commands/links.ts","../src/commands/views.ts","../src/commands/visitors.ts"],"sourcesContent":["import { Command } from \"commander\";\n\nimport { registerAnalyticsCommands } from \"./commands/analytics.js\";\nimport { registerAuthCommands } from \"./commands/auth.js\";\nimport { registerConfigCommands } from \"./commands/config.js\";\nimport { registerDataroomsCommands } from \"./commands/datarooms.js\";\nimport { registerDoctorCommand } from \"./commands/doctor.js\";\nimport { registerDocumentsCommands } from \"./commands/documents.js\";\nimport { registerFoldersCommands } from \"./commands/folders.js\";\nimport { registerLinksCommands } from \"./commands/links.js\";\nimport { registerViewsCommands } from \"./commands/views.js\";\nimport { registerVisitorsCommands } from \"./commands/visitors.js\";\nimport { setRuntime } from \"./runtime.js\";\n\nconst program = new Command();\n\nprogram\n .name(\"papermark\")\n .description(\"Papermark CLI — manage documents, links, and views\")\n .version(\"0.1.0\")\n .option(\n \"--json\",\n \"emit machine-readable JSON on stdout (auto-enabled when piped)\",\n )\n .option(\n \"--dry-run\",\n \"print the HTTP request that would be sent and exit (token redacted)\",\n )\n .option(\"--no-color\", \"disable ANSI color (same as NO_COLOR=1)\")\n // Promote global flags so subcommands can read them via their parent.\n .hook(\"preAction\", (thisCommand) => {\n const opts = thisCommand.opts<{\n json?: boolean;\n dryRun?: boolean;\n color?: boolean;\n }>();\n setRuntime({\n json: Boolean(opts.json) || !process.stdout.isTTY,\n dryRun: Boolean(opts.dryRun),\n color: opts.color !== false && !process.env.NO_COLOR,\n });\n });\n\nregisterAuthCommands(program);\nregisterDoctorCommand(program);\nregisterDocumentsCommands(program);\nregisterFoldersCommands(program);\nregisterLinksCommands(program);\nregisterViewsCommands(program);\nregisterDataroomsCommands(program);\nregisterVisitorsCommands(program);\nregisterAnalyticsCommands(program);\nregisterConfigCommands(program);\n\nprogram.parseAsync(process.argv);\n","import chalk from \"chalk\";\nimport { Command } from \"commander\";\n\nimport { api } from \"../client.js\";\nimport { die, emit, json, table } from \"../output.js\";\nimport { setRuntime } from \"../runtime.js\";\n\n// Tinybird-backed aggregate analytics. The dataroom-level variant is also\n// surfaced as `papermark dr stats <id>` for convenience; this top-level\n// `analytics` group covers the document, link, and per-view endpoints\n// that don't have a dedicated parent command.\nexport function registerAnalyticsCommands(program: Command): void {\n const analytics = program\n .command(\"analytics\")\n .description(\"Aggregate analytics (Tinybird-backed, tighter rate limit)\");\n\n analytics\n .command(\"document <id>\")\n .description(\n \"Document analytics: total views, unique viewers, total read time, per-page average duration.\",\n )\n .option(\"--since <unix-ms>\", \"window start (default: 30 days ago)\", (v) => Number(v))\n .option(\"--until <unix-ms>\", \"window end (default: now)\", (v) => Number(v))\n .option(\"--json\", \"output raw JSON\")\n .action(\n async (\n id: string,\n opts: { since?: number; until?: number; json?: boolean },\n ) => {\n if (opts.json) setRuntime({ json: true });\n try {\n const stats = await api.documentAnalytics(id, {\n since: opts.since,\n until: opts.until,\n });\n emit(stats, () => formatDocumentAnalytics(stats));\n } catch (err) {\n die(err);\n }\n },\n );\n\n analytics\n .command(\"link <id>\")\n .description(\"Aggregate analytics for a single share link.\")\n .option(\"--since <unix-ms>\", \"window start (default: 30 days ago)\", (v) => Number(v))\n .option(\"--until <unix-ms>\", \"window end (default: now)\", (v) => Number(v))\n .option(\"--json\", \"output raw JSON\")\n .action(\n async (\n id: string,\n opts: { since?: number; until?: number; json?: boolean },\n ) => {\n if (opts.json) setRuntime({ json: true });\n try {\n const stats = await api.linkAnalytics(id, {\n since: opts.since,\n until: opts.until,\n });\n emit(stats, () => formatLinkAnalytics(stats));\n } catch (err) {\n die(err);\n }\n },\n );\n\n analytics\n .command(\"dataroom <id>\")\n .description(\"Aggregate analytics for a dataroom (alias of `papermark dr stats`).\")\n .option(\"--since <unix-ms>\", \"window start (default: 30 days ago)\", (v) => Number(v))\n .option(\"--until <unix-ms>\", \"window end (default: now)\", (v) => Number(v))\n .option(\"--json\", \"output raw JSON\")\n .action(\n async (\n id: string,\n opts: { since?: number; until?: number; json?: boolean },\n ) => {\n if (opts.json) setRuntime({ json: true });\n try {\n const stats = await api.dataroomAnalytics(id, {\n since: opts.since,\n until: opts.until,\n });\n emit(stats, () => formatDataroomAnalytics(stats));\n } catch (err) {\n die(err);\n }\n },\n );\n\n analytics\n .command(\"view <id>\")\n .description(\n \"Per-view breakdown: page-by-page time spent, total duration, viewer geo + client.\",\n )\n .option(\"--json\", \"output raw JSON\")\n .action(async (id: string, opts: { json?: boolean }) => {\n if (opts.json) setRuntime({ json: true });\n try {\n const stats = await api.viewAnalytics(id);\n emit(stats, () => json(stats));\n } catch (err) {\n die(err);\n }\n });\n}\n\nfunction formatDocumentAnalytics(stats: Awaited<ReturnType<typeof api.documentAnalytics>>): string {\n const minutes = Math.round(stats.total_duration_seconds / 60);\n const lines = [\n `${chalk.bold(\"Document:\")} ${stats.document_id}`,\n `${chalk.bold(\"Total views:\")} ${stats.total_views}`,\n `${chalk.bold(\"Unique viewers:\")} ${stats.unique_viewers}`,\n `${chalk.bold(\"Total read time:\")} ${minutes} min (${stats.total_duration_seconds.toFixed(1)} s)`,\n chalk.dim(`Window: ${stats.since.slice(0, 10)} → ${stats.until.slice(0, 10)}`),\n ];\n if (stats.avg_page_duration_seconds.length > 0) {\n const rows = stats.avg_page_duration_seconds.map((p) => ({\n page: String(p.page_number),\n avg_seconds: p.avg_duration_seconds.toFixed(1),\n }));\n lines.push(\"\", chalk.bold(\"Per-page average duration:\"));\n lines.push(table(rows, [\"page\", \"avg_seconds\"]));\n }\n return lines.join(\"\\n\");\n}\n\nfunction formatLinkAnalytics(stats: Awaited<ReturnType<typeof api.linkAnalytics>>): string {\n const minutes = Math.round(stats.total_duration_seconds / 60);\n return [\n `${chalk.bold(\"Link:\")} ${stats.link_id}`,\n `${chalk.bold(\"Total views:\")} ${stats.total_views}`,\n `${chalk.bold(\"Unique viewers:\")} ${stats.unique_viewers}`,\n `${chalk.bold(\"Total read time:\")} ${minutes} min (${stats.total_duration_seconds.toFixed(1)} s)`,\n chalk.dim(`Window: ${stats.since.slice(0, 10)} → ${stats.until.slice(0, 10)}`),\n ].join(\"\\n\");\n}\n\nfunction formatDataroomAnalytics(\n stats: Awaited<ReturnType<typeof api.dataroomAnalytics>>,\n): string {\n const minutes = Math.round(stats.total_duration_seconds / 60);\n return [\n `${chalk.bold(\"Dataroom:\")} ${stats.dataroom_id}`,\n `${chalk.bold(\"Total views:\")} ${stats.total_views}`,\n `${chalk.bold(\"Unique viewers:\")} ${stats.unique_viewers}`,\n `${chalk.bold(\"Total read time:\")} ${minutes} min (${stats.total_duration_seconds.toFixed(1)} s)`,\n chalk.dim(`Window: ${stats.since.slice(0, 10)} → ${stats.until.slice(0, 10)}`),\n ].join(\"\\n\");\n}\n","import { readFileSync } from \"node:fs\";\n\nimport Conf from \"conf\";\n\ninterface CliConfig {\n token?: string;\n apiUrl?: string;\n}\n\n// conf defaults the location to $XDG_CONFIG_HOME/papermark or ~/.config/papermark\n// on macOS/Linux and a Roaming AppData folder on Windows, with 0600 perms.\nconst store = new Conf<CliConfig>({\n projectName: \"papermark\",\n configFileMode: 0o600,\n defaults: {\n apiUrl: \"https://api.papermark.com\",\n },\n});\n\n// Read once per process — CI runners pass this as a volume-mounted\n// secret; no reason to re-stat on every request.\nlet credentialsFile: CliConfig | null | undefined;\nfunction readCredentialsFile(): CliConfig | null {\n if (credentialsFile !== undefined) return credentialsFile;\n const path = process.env.PAPERMARK_CREDENTIALS_FILE;\n if (!path) return (credentialsFile = null);\n try {\n const parsed = JSON.parse(readFileSync(path, \"utf8\"));\n if (parsed && typeof parsed === \"object\") {\n return (credentialsFile = {\n token: typeof parsed.token === \"string\" ? parsed.token : undefined,\n apiUrl:\n typeof parsed.apiUrl === \"string\"\n ? parsed.apiUrl\n : typeof parsed.api_url === \"string\"\n ? parsed.api_url\n : undefined,\n });\n }\n } catch (err) {\n process.stderr.write(\n `warning: could not read PAPERMARK_CREDENTIALS_FILE (${path}): ${\n err instanceof Error ? err.message : String(err)\n }\\n`,\n );\n }\n return (credentialsFile = null);\n}\n\n/** Empty-string env values (e.g. `PAPERMARK_TOKEN=`) are treated as unset. */\nfunction envOr(name: string): string | undefined {\n const v = process.env[name];\n return v && v.length > 0 ? v : undefined;\n}\n\n/**\n * Token resolution precedence (highest first):\n * 1. PAPERMARK_TOKEN env var\n * 2. PAPERMARK_CREDENTIALS_FILE's token field\n * 3. stored config (~/.config/papermark/config.json or equivalent)\n */\nexport function getToken(): string | undefined {\n return (\n envOr(\"PAPERMARK_TOKEN\") ??\n readCredentialsFile()?.token ??\n store.get(\"token\")\n );\n}\n\nexport type TokenSource = \"env\" | \"credentials-file\" | \"config\" | \"none\";\nexport function getTokenSource(): TokenSource {\n if (envOr(\"PAPERMARK_TOKEN\")) return \"env\";\n if (readCredentialsFile()?.token) return \"credentials-file\";\n if (store.get(\"token\")) return \"config\";\n return \"none\";\n}\n\nexport function setToken(token: string): void {\n store.set(\"token\", token);\n}\n\nexport function clearToken(): void {\n store.delete(\"token\");\n}\n\nexport function getApiUrl(): string {\n return (\n envOr(\"PAPERMARK_API_URL\") ??\n readCredentialsFile()?.apiUrl ??\n store.get(\"apiUrl\") ??\n \"https://api.papermark.com\"\n );\n}\n\nexport function setApiUrl(url: string): void {\n store.set(\"apiUrl\", url);\n}\n\nexport function getAll(): CliConfig {\n return { token: store.get(\"token\"), apiUrl: store.get(\"apiUrl\") };\n}\n\nexport function configPath(): string {\n return store.path;\n}\n\nexport function deleteKey(key: keyof CliConfig): void {\n store.delete(key);\n}\n","// Tiny opt-in tracer, gated on PAPERMARK_DEBUG=1. Zero cost when unset\n// — no console writes, no closure allocations per call site. Intended\n// for bug reports (\"run with PAPERMARK_DEBUG=1 and paste the output\").\n\nconst enabled =\n process.env.PAPERMARK_DEBUG === \"1\" ||\n process.env.PAPERMARK_DEBUG === \"true\";\n\nexport function debug(category: string, ...parts: unknown[]): void {\n if (!enabled) return;\n const line = parts\n .map((p) => (typeof p === \"string\" ? p : JSON.stringify(p)))\n .join(\" \");\n process.stderr.write(`[papermark:${category}] ${line}\\n`);\n}\n\nexport function debugEnabled(): boolean {\n return enabled;\n}\n","// Runtime flags that affect output and side effects. Populated once in\n// index.ts from the root Commander program + env vars, then consumed\n// from anywhere in the CLI (client, commands, spinners).\n//\n// Kept as module-level state (not context-passed) because threading\n// flags through every function signature is noise for a <1k-line CLI.\n\nimport type { Writable } from \"node:stream\";\n\nexport interface Runtime {\n /** User passed --json, or stdout is not a TTY (scripted). */\n json: boolean;\n /** User passed --dry-run — CLI prints intended request and exits. */\n dryRun: boolean;\n /** Controls whether ANSI color/spinners are emitted. */\n color: boolean;\n}\n\nlet current: Runtime = {\n json: !process.stdout.isTTY,\n dryRun: false,\n color: process.stdout.isTTY && !process.env.NO_COLOR,\n};\n\nexport function setRuntime(patch: Partial<Runtime>): void {\n current = { ...current, ...patch };\n}\n\nexport function getRuntime(): Runtime {\n return current;\n}\n\n/** Helpers for deciding where to send different kinds of output. */\nexport function stdout(): Writable {\n return process.stdout;\n}\nexport function stderr(): Writable {\n return process.stderr;\n}\n","import { getApiUrl, getToken } from \"./config.js\";\nimport { debug } from \"./debug.js\";\nimport { getRuntime } from \"./runtime.js\";\n\nexport interface ApiErrorBody {\n error: {\n code: string;\n message: string;\n doc_url?: string;\n details?: unknown;\n };\n}\n\nexport class ApiError extends Error {\n code: string;\n status: number;\n docUrl?: string;\n details?: unknown;\n\n constructor(status: number, body: ApiErrorBody[\"error\"] | string) {\n const message = typeof body === \"string\" ? body : body.message;\n super(message);\n this.status = status;\n if (typeof body === \"string\") {\n this.code = \"unknown\";\n } else {\n this.code = body.code;\n this.docUrl = body.doc_url;\n this.details = body.details;\n }\n }\n}\n\nexport class AuthRequiredError extends Error {\n constructor() {\n super(\"No API token found. Run `papermark login` first.\");\n this.name = \"AuthRequiredError\";\n }\n}\n\nexport class NetworkError extends Error {\n url: string;\n cause: unknown;\n constructor(url: string, cause: unknown) {\n const reason = extractNetworkReason(cause);\n super(`Network request to ${url} failed: ${reason}`);\n this.name = \"NetworkError\";\n this.url = url;\n this.cause = cause;\n }\n}\n\nfunction extractNetworkReason(err: unknown): string {\n if (err && typeof err === \"object\" && \"cause\" in err) {\n const c = (err as { cause: unknown }).cause;\n if (c && typeof c === \"object\") {\n const code = (c as { code?: string }).code;\n const msg = (c as { message?: string }).message;\n if (code || msg) return `${code ?? \"\"}${code && msg ? \" — \" : \"\"}${msg ?? \"\"}`.trim();\n }\n }\n if (err instanceof Error) return err.message;\n return String(err);\n}\n\ninterface RequestOptions {\n method?: string;\n body?: unknown;\n query?: Record<string, string | number | undefined>;\n /** If true, skip the \"Authorization\" header (used for presigned URL uploads). */\n anonymous?: boolean;\n headers?: Record<string, string>;\n}\n\nfunction buildUrl(path: string, query?: RequestOptions[\"query\"]): string {\n const base = getApiUrl().replace(/\\/$/, \"\");\n // Base URL is either https://api.papermark.com (subdomain) or\n // http://localhost:3000/api (when pointed at a local dev server).\n // Path is like \"/v1/documents\". Concatenate and normalize doubled /api.\n let fullPath = path.startsWith(\"/\") ? path : `/${path}`;\n if (base.endsWith(\"/api\") && fullPath.startsWith(\"/api/\")) {\n fullPath = fullPath.slice(4);\n }\n const url = new URL(base + fullPath);\n if (query) {\n for (const [k, v] of Object.entries(query)) {\n if (v !== undefined && v !== null && v !== \"\") {\n url.searchParams.set(k, String(v));\n }\n }\n }\n return url.toString();\n}\n\nexport async function request<T = unknown>(\n path: string,\n opts: RequestOptions = {},\n): Promise<T> {\n const headers: Record<string, string> = {\n Accept: \"application/json\",\n ...(opts.headers ?? {}),\n };\n if (!opts.anonymous) {\n const token = getToken();\n if (token) {\n headers.Authorization = `Bearer ${token}`;\n } else if (!getRuntime().dryRun) {\n // Dry-run is explicitly for inspecting what WOULD be sent, so we\n // proceed with a placeholder Authorization below. Every other code\n // path needs a real token.\n throw new AuthRequiredError();\n } else {\n headers.Authorization = \"Bearer <no-token>\";\n }\n }\n let body: BodyInit | undefined;\n if (opts.body !== undefined) {\n if (opts.body instanceof Uint8Array || opts.body instanceof ArrayBuffer) {\n body = opts.body as BodyInit;\n } else {\n body = JSON.stringify(opts.body);\n headers[\"Content-Type\"] = \"application/json\";\n }\n }\n\n const url = buildUrl(path, opts.query);\n const method = opts.method ?? (opts.body ? \"POST\" : \"GET\");\n\n if (getRuntime().dryRun) {\n // Print the request we would make and short-circuit. Token is\n // redacted so users can safely paste the output into bug reports.\n const redactedHeaders = { ...headers };\n if (redactedHeaders.Authorization) {\n redactedHeaders.Authorization = \"Bearer ***redacted***\";\n }\n process.stderr.write(\n `[dry-run] ${method} ${url}\\n` +\n Object.entries(redactedHeaders)\n .map(([k, v]) => `[dry-run] ${k}: ${v}`)\n .join(\"\\n\") +\n (body ? `\\n[dry-run] body: ${truncate(String(body), 500)}` : \"\") +\n \"\\n\",\n );\n return undefined as T;\n }\n\n debug(\"http\", method, url, body ? \"(body)\" : \"\");\n const started = Date.now();\n let res: Response;\n try {\n res = await fetch(url, { method, headers, body });\n } catch (err) {\n debug(\"http\", \"network error after\", `${Date.now() - started}ms`, String(err));\n throw new NetworkError(url, err);\n }\n debug(\"http\", method, url, `→ ${res.status}`, `(${Date.now() - started}ms)`);\n\n if (res.status === 204) return undefined as T;\n\n const text = await res.text();\n const parsed = text ? safeParseJson(text) : null;\n\n if (!res.ok) {\n if (parsed && typeof parsed === \"object\" && \"error\" in parsed) {\n throw new ApiError(res.status, (parsed as ApiErrorBody).error);\n }\n // Non-JSON response (e.g. a Next.js HTML error page). Keep the message\n // short — users don't want to read HTML.\n const looksLikeHtml = text.trimStart().toLowerCase().startsWith(\"<\");\n const msg = looksLikeHtml\n ? `HTTP ${res.status} (server returned HTML, not JSON — is the dev server healthy?)`\n : text || `HTTP ${res.status}`;\n throw new ApiError(res.status, msg);\n }\n\n // Treat a non-JSON 2xx body as an error rather than silently returning\n // undefined — it's almost always a sign of a misconfigured proxy or a\n // routing layer that handed us an HTML page instead of the API.\n if (parsed === null && text.trim() !== \"\") {\n const looksLikeHtml = text.trimStart().toLowerCase().startsWith(\"<\");\n const msg = looksLikeHtml\n ? `HTTP ${res.status} (server returned HTML on a 2xx — is the API URL pointing at the right host?)`\n : `HTTP ${res.status} (response was not JSON: ${truncate(text, 200)})`;\n throw new ApiError(res.status, msg);\n }\n\n return (parsed as T) ?? (undefined as T);\n}\n\nfunction safeParseJson(s: string): unknown {\n try {\n return JSON.parse(s);\n } catch {\n return null;\n }\n}\n\nfunction truncate(s: string, n: number): string {\n return s.length > n ? s.slice(0, n - 1) + \"…\" : s;\n}\n\n// -------- Typed helpers for each resource --------\n//\n// All response field names mirror the v1 public API exactly: snake_case,\n// nullable where the API documents it. Keep this file in sync with\n// papermark/lib/api/v1/schemas/*.ts.\n\nexport interface PublicDocument {\n id: string;\n object: \"document\";\n name: string;\n type: string | null;\n content_type: string | null;\n num_pages: number | null;\n folder_id: string | null;\n created: string;\n updated_at: string;\n}\n\nexport interface DocumentList {\n data: PublicDocument[];\n next_cursor: string | null;\n}\n\nexport interface UploadUrlResponse {\n upload_url: string;\n upload_id: string;\n required_headers: Record<string, string>;\n expires_at: string;\n}\n\nexport interface PublicDocumentVersion {\n id: string;\n object: \"document_version\";\n version_number: number;\n is_primary: boolean;\n type: string | null;\n content_type: string | null;\n num_pages: number | null;\n file_size: number | null;\n created: string;\n updated_at: string;\n}\n\nexport interface DocumentVersionList {\n data: PublicDocumentVersion[];\n}\n\nexport type FolderIcon =\n | \"folder\"\n | \"folder-open\"\n | \"briefcase\"\n | \"archive\"\n | \"box\"\n | \"file\"\n | \"book\"\n | \"bookmark\"\n | \"star\"\n | \"heart\"\n | \"lock\"\n | \"shield\"\n | \"users\"\n | \"settings\"\n | \"tag\"\n | \"layers\"\n | \"globe\"\n | \"home\"\n | \"mail\"\n | \"image\"\n | \"video\"\n | \"music\"\n | \"palette\"\n | \"pen-tool\"\n | \"lightbulb\"\n | \"zap\"\n | \"wrench\"\n | \"sparkles\"\n | \"cloud\"\n | \"flag\"\n | \"award\"\n | \"flame\"\n | \"bell\"\n | \"sun\"\n | \"hash\";\n\nexport type FolderColor =\n | \"gray\"\n | \"red\"\n | \"orange\"\n | \"yellow\"\n | \"green\"\n | \"blue\"\n | \"black\";\n\nexport interface PublicFolder {\n id: string;\n object: \"folder\";\n name: string;\n parent_id: string | null;\n path: string;\n icon: string | null;\n color: string | null;\n document_count: number;\n child_folder_count: number;\n created: string;\n updated_at: string;\n}\n\nexport interface FolderList {\n data: PublicFolder[];\n next_cursor: string | null;\n}\n\nexport type WatermarkPosition =\n | \"top-left\"\n | \"top-center\"\n | \"top-right\"\n | \"middle-left\"\n | \"middle-center\"\n | \"middle-right\"\n | \"bottom-left\"\n | \"bottom-center\"\n | \"bottom-right\";\n\nexport type WatermarkRotation = 0 | 30 | 45 | 90 | 180;\n\nexport interface WatermarkConfig {\n text: string;\n is_tiled: boolean;\n position: WatermarkPosition;\n rotation: WatermarkRotation;\n color: string;\n font_size: number;\n opacity: number;\n}\n\nexport interface PublicLink {\n id: string;\n object: \"link\";\n name: string | null;\n target_type: \"document\" | \"dataroom\";\n document_id: string | null;\n dataroom_id: string | null;\n url: string;\n domain: string | null;\n slug: string | null;\n expires_at: string | null;\n is_password_protected: boolean;\n email_protected: boolean;\n email_authenticated: boolean;\n allow_download: boolean;\n allow_list: string[];\n deny_list: string[];\n enable_watermark: boolean;\n watermark_config: WatermarkConfig | null;\n enable_feedback: boolean;\n enable_screenshot_protection: boolean;\n enable_confidential_view: boolean;\n created: string;\n updated_at: string;\n}\n\nexport interface LinkList {\n data: PublicLink[];\n next_cursor: string | null;\n}\n\nexport interface PublicView {\n id: string;\n object: \"view\";\n link_id: string | null;\n document_id: string | null;\n dataroom_id: string | null;\n viewer_email: string | null;\n view_type: string | null;\n viewed_at: string;\n downloaded_at: string | null;\n download_type: string | null;\n}\n\nexport interface ViewList {\n data: PublicView[];\n next_cursor: string | null;\n}\n\nexport interface PublicDataroom {\n id: string;\n object: \"dataroom\";\n pid: string;\n name: string;\n internal_name: string | null;\n description: string | null;\n document_count: number;\n folder_count: number;\n conversations_enabled: boolean;\n agents_enabled: boolean;\n allow_bulk_download: boolean;\n is_frozen: boolean;\n created: string;\n updated_at: string;\n}\n\nexport interface DataroomList {\n data: PublicDataroom[];\n next_cursor: string | null;\n}\n\nexport interface PublicDataroomItem {\n id: string;\n object: \"dataroom_document\";\n document_id: string;\n document_name: string;\n content_type: string | null;\n num_pages: number | null;\n folder_id: string | null;\n folder_path: string | null;\n order_index: number | null;\n created: string;\n}\n\nexport interface DataroomItemList {\n data: PublicDataroomItem[];\n next_cursor: string | null;\n}\n\nexport interface PublicDataroomFolder {\n id: string;\n object: \"dataroom_folder\";\n name: string;\n parent_id: string | null;\n path: string;\n icon: string | null;\n color: string | null;\n document_count: number;\n child_folder_count: number;\n order_index: number | null;\n created: string;\n updated_at: string;\n}\n\nexport interface DataroomFolderList {\n data: PublicDataroomFolder[];\n next_cursor: string | null;\n}\n\nexport interface PublicVisitor {\n id: string;\n object: \"visitor\";\n email: string;\n verified: boolean;\n dataroom_id: string | null;\n invited_at: string | null;\n total_views: number;\n last_viewed_at: string | null;\n created: string;\n updated_at: string;\n}\n\nexport interface VisitorList {\n data: PublicVisitor[];\n next_cursor: string | null;\n}\n\nexport interface PublicVisitorView {\n id: string;\n object: \"visitor_view\";\n link_id: string;\n document_id: string | null;\n dataroom_id: string | null;\n view_type: string;\n viewed_at: string;\n downloaded_at: string | null;\n is_archived: boolean;\n}\n\nexport interface VisitorViewList {\n data: PublicVisitorView[];\n next_cursor: string | null;\n}\n\nexport interface DocumentAnalytics {\n document_id: string;\n total_views: number;\n unique_viewers: number;\n total_duration_seconds: number;\n avg_page_duration_seconds: { page_number: number; avg_duration_seconds: number }[];\n since: string;\n until: string;\n}\n\nexport interface LinkAnalytics {\n link_id: string;\n total_views: number;\n total_duration_seconds: number;\n unique_viewers: number;\n since: string;\n until: string;\n}\n\nexport interface DataroomAnalytics {\n dataroom_id: string;\n total_views: number;\n unique_viewers: number;\n total_duration_seconds: number;\n since: string;\n until: string;\n}\n\nexport interface ViewAnalytics {\n view_id: string;\n document_id: string | null;\n viewer_email: string | null;\n viewed_at: string;\n page_durations: { page_number: number; duration_seconds: number }[];\n total_duration_seconds: number;\n location: { country: string | null; city: string | null } | null;\n client: { browser: string | null; os: string | null; device: string | null } | null;\n}\n\nexport interface UpdateDocumentBody {\n name?: string;\n folder_id?: string | null;\n}\n\nexport interface UpdateLinkBody {\n name?: string;\n expires_at?: string | null;\n password?: string | null;\n email_protected?: boolean;\n email_authenticated?: boolean;\n allow_download?: boolean;\n allow_list?: string[];\n deny_list?: string[];\n enable_watermark?: boolean;\n watermark_config?: WatermarkConfig | null;\n enable_screenshot_protection?: boolean;\n enable_confidential_view?: boolean;\n}\n\n// Uniform acknowledgment returned by every v1 DELETE endpoint.\nexport interface DeletedObject {\n id: string;\n object:\n | \"document\"\n | \"folder\"\n | \"link\"\n | \"dataroom\"\n | \"dataroom_folder\"\n | \"dataroom_document\";\n deleted: true;\n}\n\nexport const api = {\n // Documents\n listDocuments: (query?: { limit?: number; cursor?: string; query?: string }) =>\n request<DocumentList>(\"/v1/documents\", { query }),\n getDocument: (id: string) => request<PublicDocument>(`/v1/documents/${id}`),\n searchDocuments: (q: string, limit?: number) =>\n request<DocumentList>(\"/v1/documents/search\", { query: { q, limit } }),\n updateDocument: (id: string, body: UpdateDocumentBody) =>\n request<PublicDocument>(`/v1/documents/${id}`, { method: \"PATCH\", body }),\n deleteDocument: (id: string) =>\n request<DeletedObject>(`/v1/documents/${id}`, { method: \"DELETE\" }),\n uploadUrl: (body: { file_name: string; content_type: string; content_length?: number }) =>\n request<UploadUrlResponse>(\"/v1/documents/upload-url\", { method: \"POST\", body }),\n createDocument: (body: {\n name: string;\n upload_id?: string;\n source_url?: string;\n folder_id?: string;\n create_link?: boolean;\n }) => request<PublicDocument>(\"/v1/documents\", { method: \"POST\", body }),\n listDocumentVersions: (id: string) =>\n request<DocumentVersionList>(`/v1/documents/${id}/versions`),\n addDocumentVersion: (\n id: string,\n body: { upload_id?: string; source_url?: string },\n ) =>\n request<PublicDocumentVersion>(`/v1/documents/${id}/versions`, {\n method: \"POST\",\n body,\n }),\n getDocumentVersion: (id: string, vid: string) =>\n request<PublicDocumentVersion>(`/v1/documents/${id}/versions/${vid}`),\n promoteDocumentVersion: (id: string, vid: string) =>\n request<PublicDocumentVersion>(`/v1/documents/${id}/versions/${vid}`, {\n method: \"PATCH\",\n body: { is_primary: true },\n }),\n\n // Folders\n listFolders: (query?: { limit?: number; cursor?: string; parent_id?: string }) =>\n request<FolderList>(\"/v1/folders\", { query }),\n createFolder: (body: {\n name: string;\n parent_id?: string | null;\n icon?: FolderIcon;\n color?: FolderColor;\n }) => request<PublicFolder>(\"/v1/folders\", { method: \"POST\", body }),\n getFolder: (id: string) => request<PublicFolder>(`/v1/folders/${id}`),\n updateFolder: (\n id: string,\n body: { name?: string; icon?: FolderIcon | null; color?: FolderColor | null },\n ) => request<PublicFolder>(`/v1/folders/${id}`, { method: \"PATCH\", body }),\n deleteFolder: (id: string, opts?: { cascade?: boolean }) =>\n request<DeletedObject>(`/v1/folders/${id}`, {\n method: \"DELETE\",\n query: opts?.cascade ? { cascade: \"true\" } : undefined,\n }),\n moveFolder: (id: string, body: { parent_id: string | null }) =>\n request<PublicFolder>(`/v1/folders/${id}/move`, { method: \"POST\", body }),\n\n // Links\n listLinks: (query?: { limit?: number; cursor?: string; document_id?: string; dataroom_id?: string }) =>\n request<LinkList>(\"/v1/links\", { query }),\n getLink: (id: string) => request<PublicLink>(`/v1/links/${id}`),\n createLink: (body: {\n document_id?: string;\n dataroom_id?: string;\n name?: string;\n expires_at?: string;\n password?: string;\n email_protected?: boolean;\n allow_download?: boolean;\n enable_confidential_view?: boolean;\n enable_watermark?: boolean;\n watermark_config?: WatermarkConfig;\n }) => request<PublicLink>(\"/v1/links\", { method: \"POST\", body }),\n updateLink: (id: string, body: UpdateLinkBody) =>\n request<PublicLink>(`/v1/links/${id}`, { method: \"PATCH\", body }),\n deleteLink: (id: string) =>\n request<DeletedObject>(`/v1/links/${id}`, { method: \"DELETE\" }),\n\n // Views\n listViews: (linkId: string, query?: { limit?: number; cursor?: string }) =>\n request<ViewList>(`/v1/links/${linkId}/views`, { query }),\n\n // Datarooms\n listDatarooms: (query?: { limit?: number; cursor?: string; query?: string }) =>\n request<DataroomList>(\"/v1/datarooms\", { query }),\n getDataroom: (id: string) =>\n request<PublicDataroom>(`/v1/datarooms/${id}`),\n createDataroom: (body: {\n name: string;\n internal_name?: string;\n description?: string;\n }) => request<PublicDataroom>(\"/v1/datarooms\", { method: \"POST\", body }),\n updateDataroom: (\n id: string,\n body: {\n name?: string;\n internal_name?: string | null;\n description?: string | null;\n allow_bulk_download?: boolean;\n },\n ) =>\n request<PublicDataroom>(`/v1/datarooms/${id}`, { method: \"PATCH\", body }),\n deleteDataroom: (id: string) =>\n request<DeletedObject>(`/v1/datarooms/${id}`, { method: \"DELETE\" }),\n listDataroomDocuments: (\n id: string,\n query?: { limit?: number; cursor?: string; folder_id?: string },\n ) =>\n request<DataroomItemList>(`/v1/datarooms/${id}/documents`, { query }),\n attachDataroomDocument: (\n id: string,\n body: { document_id: string; folder_id?: string },\n ) =>\n request<PublicDataroomItem>(`/v1/datarooms/${id}/documents`, {\n method: \"POST\",\n body,\n }),\n detachDataroomDocument: (id: string, ddId: string) =>\n request<DeletedObject>(`/v1/datarooms/${id}/documents/${ddId}`, {\n method: \"DELETE\",\n }),\n moveDataroomDocument: (\n id: string,\n ddId: string,\n body: { folder_id: string | null },\n ) =>\n request<PublicDataroomItem>(`/v1/datarooms/${id}/documents/${ddId}/move`, {\n method: \"POST\",\n body,\n }),\n\n // Dataroom folders\n listDataroomFolders: (\n id: string,\n query?: { limit?: number; cursor?: string; parent_id?: string },\n ) =>\n request<DataroomFolderList>(`/v1/datarooms/${id}/folders`, { query }),\n createDataroomFolder: (\n id: string,\n body: {\n name: string;\n parent_id?: string | null;\n icon?: FolderIcon;\n color?: FolderColor;\n },\n ) =>\n request<PublicDataroomFolder>(`/v1/datarooms/${id}/folders`, {\n method: \"POST\",\n body,\n }),\n getDataroomFolder: (id: string, fid: string) =>\n request<PublicDataroomFolder>(`/v1/datarooms/${id}/folders/${fid}`),\n updateDataroomFolder: (\n id: string,\n fid: string,\n body: { name?: string; icon?: FolderIcon | null; color?: FolderColor | null },\n ) =>\n request<PublicDataroomFolder>(`/v1/datarooms/${id}/folders/${fid}`, {\n method: \"PATCH\",\n body,\n }),\n deleteDataroomFolder: (id: string, fid: string, opts?: { cascade?: boolean }) =>\n request<DeletedObject>(`/v1/datarooms/${id}/folders/${fid}`, {\n method: \"DELETE\",\n query: opts?.cascade ? { cascade: \"true\" } : undefined,\n }),\n moveDataroomFolder: (\n id: string,\n fid: string,\n body: { parent_id: string | null },\n ) =>\n request<PublicDataroomFolder>(`/v1/datarooms/${id}/folders/${fid}/move`, {\n method: \"POST\",\n body,\n }),\n\n // Visitors\n listVisitors: (query?: {\n limit?: number;\n cursor?: string;\n email?: string;\n dataroom_id?: string;\n }) => request<VisitorList>(\"/v1/visitors\", { query }),\n getVisitor: (id: string) => request<PublicVisitor>(`/v1/visitors/${id}`),\n listVisitorViews: (id: string, query?: { limit?: number; cursor?: string }) =>\n request<VisitorViewList>(`/v1/visitors/${id}/views`, { query }),\n\n // Analytics\n documentAnalytics: (\n id: string,\n query?: { since?: number; until?: number },\n ) =>\n request<DocumentAnalytics>(`/v1/analytics/documents/${id}`, { query }),\n linkAnalytics: (id: string, query?: { since?: number; until?: number }) =>\n request<LinkAnalytics>(`/v1/analytics/links/${id}`, { query }),\n dataroomAnalytics: (\n id: string,\n query?: { since?: number; until?: number },\n ) =>\n request<DataroomAnalytics>(`/v1/analytics/datarooms/${id}`, { query }),\n viewAnalytics: (id: string) =>\n request<ViewAnalytics>(`/v1/analytics/views/${id}`),\n};\n","import chalk from \"chalk\";\n\nimport { ApiError, AuthRequiredError, NetworkError } from \"./client.js\";\nimport { ExitCode } from \"./exit.js\";\nimport { getRuntime } from \"./runtime.js\";\n\n/**\n * CLI-side validation failure. Produced by command handlers when the user's\n * input fails the contract checks before we ever talk to the API. Maps to\n * exit code 3 + `code: \"VALIDATION\"` in the JSON envelope.\n */\nexport class ValidationError extends Error {\n details?: unknown;\n constructor(message: string, details?: unknown) {\n super(message);\n this.name = \"ValidationError\";\n this.details = details;\n }\n}\n\nexport interface FormattedError {\n /** Human-readable message for humans (with color + hint lines). */\n human: string;\n /** Machine-parseable shape for --json / !isTTY. */\n json: {\n error: {\n code: string;\n message: string;\n status?: number;\n /**\n * Whether an agent should retry this error with backoff. True for\n * transient failures (network, rate limit, 5xx); false for auth,\n * validation, or 4xx-not-429. Canonical mapping lives in\n * docs/CONTRACT_V1.md.\n */\n retryable: boolean;\n hint?: string;\n doc_url?: string;\n details?: unknown;\n };\n };\n exitCode: ExitCode;\n}\n\nexport function formatError(err: unknown): FormattedError {\n if (err instanceof AuthRequiredError) {\n const message = sanitizeForTerminal(err.message);\n return {\n human: chalk.red(\"✗ \") + message,\n json: {\n error: {\n code: \"NO_TOKEN\",\n message: err.message,\n retryable: false,\n hint: \"Run `papermark login` to authenticate.\",\n },\n },\n exitCode: ExitCode.AuthError,\n };\n }\n if (err instanceof NetworkError) {\n const message = sanitizeForTerminal(err.message);\n return {\n human:\n chalk.red(\"✗ \") +\n message +\n chalk.dim(\n \"\\n Hint: check `papermark config show` and your internet connection.\",\n ),\n json: {\n error: {\n code: \"NETWORK_ERROR\",\n message: err.message,\n retryable: true,\n hint: \"check `papermark config show` and your internet connection\",\n },\n },\n exitCode: ExitCode.NetworkError,\n };\n }\n if (err instanceof ValidationError) {\n const message = sanitizeForTerminal(err.message);\n return {\n human: chalk.red(\"✗ \") + message,\n json: {\n error: {\n code: \"VALIDATION\",\n message: err.message,\n retryable: false,\n ...(err.details ? { details: err.details } : {}),\n },\n },\n exitCode: ExitCode.ValidationError,\n };\n }\n if (err instanceof ApiError) {\n const hint = hintForApiError(err);\n const safeMessage = sanitizeForTerminal(err.message);\n const safeDocUrl = err.docUrl ? sanitizeForTerminal(err.docUrl) : \"\";\n const safeDetails =\n err.details && typeof err.details === \"object\"\n ? sanitizeForTerminal(JSON.stringify(err.details))\n : \"\";\n const docs = safeDocUrl ? chalk.dim(`\\n See: ${safeDocUrl}`) : \"\";\n const hintLine = hint ? chalk.dim(`\\n Hint: ${hint}`) : \"\";\n const details = safeDetails ? chalk.dim(\"\\n \" + safeDetails) : \"\";\n return {\n human:\n chalk.red(`✗ [${err.status} ${err.code}] `) +\n safeMessage +\n hintLine +\n docs +\n details,\n json: {\n error: {\n code: err.code,\n message: err.message,\n status: err.status,\n retryable: isRetryableStatus(err.status),\n ...(hint ? { hint } : {}),\n ...(err.docUrl ? { doc_url: err.docUrl } : {}),\n ...(err.details ? { details: err.details } : {}),\n },\n },\n exitCode: exitCodeForApiError(err),\n };\n }\n const rawMessage = err instanceof Error ? err.message : String(err);\n return {\n human: chalk.red(\"✗ \") + sanitizeForTerminal(rawMessage),\n json: { error: { code: \"INTERNAL\", message: rawMessage, retryable: false } },\n exitCode: ExitCode.Internal,\n };\n}\n\n/**\n * Canonical retryable mapping per docs/CONTRACT_V1.md:\n * - 429 (rate-limit) and 5xx are retryable with backoff\n * - 401/403/404/422 are not\n * - anything else defaults to false so agents don't retry-storm novel codes\n */\nfunction isRetryableStatus(status: number): boolean {\n if (status === 429) return true;\n if (status >= 500 && status < 600) return true;\n return false;\n}\n\nfunction hintForApiError(err: ApiError): string | undefined {\n if (err.status === 401) return \"Run `papermark login` to re-authenticate.\";\n if (err.status === 403) {\n return \"Token is missing a required scope. Re-login to refresh grants.\";\n }\n if (err.status === 429) {\n return \"Rate limit exceeded. Check X-RateLimit-* headers and back off.\";\n }\n if (err.status === 422) return \"Check the input shape — details below.\";\n return undefined;\n}\n\nfunction exitCodeForApiError(err: ApiError): ExitCode {\n if (err.status === 401) return ExitCode.AuthError;\n if (err.status === 403) return ExitCode.AuthError;\n if (err.status === 422) return ExitCode.ValidationError;\n return ExitCode.ApiError;\n}\n\nexport function die(err: unknown): never {\n const fe = formatError(err);\n if (getRuntime().json) {\n process.stderr.write(\n JSON.stringify({ ok: false, error: fe.json.error }) + \"\\n\",\n );\n } else {\n process.stderr.write(fe.human + \"\\n\");\n }\n process.exit(fe.exitCode);\n}\n\n/**\n * Print success-shaped output, respecting --json / !isTTY. JSON output is\n * wrapped in the CONTRACT_V1 envelope `{ ok: true, data, meta? }`. List-\n * shaped payloads (`{ data: [...], next_cursor }` returned by every paginated\n * v1 endpoint) get their cursor lifted into `meta` automatically.\n */\nexport function emit(payload: unknown, human: () => string): void {\n const rt = getRuntime();\n // --dry-run short-circuits before a real response exists; the client\n // already wrote the request trace to stderr, and there's nothing for\n // the command to render.\n if (rt.dryRun) return;\n if (rt.json) {\n process.stdout.write(JSON.stringify(wrapSuccess(payload), null, 2) + \"\\n\");\n } else {\n process.stdout.write(human() + \"\\n\");\n }\n}\n\nfunction wrapSuccess(payload: unknown):\n | { ok: true; data: unknown }\n | { ok: true; data: unknown; meta: { next_cursor: string | null } } {\n if (\n payload !== null &&\n typeof payload === \"object\" &&\n \"data\" in payload &&\n \"next_cursor\" in payload &&\n Array.isArray((payload as { data: unknown }).data)\n ) {\n const p = payload as { data: unknown[]; next_cursor: string | null };\n return { ok: true, data: p.data, meta: { next_cursor: p.next_cursor } };\n }\n return { ok: true, data: payload };\n}\n\n// Minimal pretty table — enough for short lists, no external dep.\nexport function table(\n rows: Array<Record<string, string>>,\n columns: string[],\n): string {\n if (rows.length === 0) return chalk.dim(\"(no rows)\");\n const widths = columns.map((c) =>\n Math.max(c.length, ...rows.map((r) => (r[c] ?? \"\").length)),\n );\n const pad = (s: string, n: number) => s + \" \".repeat(Math.max(0, n - s.length));\n const header = columns.map((c, i) => chalk.bold(pad(c, widths[i]))).join(\" \");\n const sep = columns.map((_, i) => \"─\".repeat(widths[i])).join(\" \");\n const body = rows.map((r) =>\n columns.map((c, i) => pad(r[c] ?? \"\", widths[i])).join(\" \"),\n );\n return [header, chalk.dim(sep), ...body].join(\"\\n\");\n}\n\nexport function json(obj: unknown): string {\n return JSON.stringify(obj, null, 2);\n}\n\n/**\n * Strip escape sequences and invisible/bidi-override characters from a\n * string before printing. Documents and links in Papermark are named by\n * users — a malicious name could smuggle ANSI escapes (to fake a\n * different filename), bidirectional overrides (to reorder characters),\n * or zero-width joiners (to mask content) through the terminal. Apply\n * this before handing user-controlled strings to table() or a spinner.\n */\nexport function sanitizeForTerminal(input: string): string {\n return input\n // ANSI CSI sequences and OSC sequences (terminator: BEL or ESC \\).\n .replace(/\\x1B\\[[0-9;?]*[ -/]*[@-~]/g, \"\")\n .replace(/\\x1B\\][^\\x07\\x1B]*(\\x07|\\x1B\\\\)/g, \"\")\n // C0 controls minus TAB/LF — including CR which can rewrite the\n // current line, and DEL.\n .replace(/[\\x00-\\x08\\x0B-\\x1F\\x7F]/g, \"\")\n // Any leftover ESC byte (after the CSI/OSC patterns above stripped\n // the well-formed sequences) so an attacker can't smuggle a partial\n // escape that combines with subsequent legitimate text.\n .replace(/\\x1B/g, \"\")\n // C1 control range — 8-bit equivalents of ESC-prefixed sequences.\n // Some terminals still interpret these.\n .replace(/[\\x80-\\x9F]/g, \"\")\n // Bidi overrides + formatting marks\n .replace(/[\\u202A-\\u202E\\u2066-\\u2069\\u200E\\u200F]/g, \"\")\n // Zero-width joiner / non-joiner / word joiner\n .replace(/[\\u200B-\\u200D\\u2060]/g, \"\");\n}\n","// Structured exit codes so shell scripts can branch on failure type\n// without parsing stderr. Mirrors the pattern documented by Stripe CLI\n// and Google Workspace CLI.\n\nexport const ExitCode = {\n Ok: 0,\n /** Upstream API returned 4xx/5xx that isn't auth or validation. */\n ApiError: 1,\n /** No token, expired token, invalid token, missing scope. */\n AuthError: 2,\n /** Client-side input validation, or server-side 422. */\n ValidationError: 3,\n /** Network/DNS/connection refused, bad URL, etc. */\n NetworkError: 4,\n /** Unexpected — bug in the CLI itself. */\n Internal: 5,\n} as const;\n\nexport type ExitCode = (typeof ExitCode)[keyof typeof ExitCode];\n\nexport const EXIT_CODE_LEGEND: Readonly<Record<ExitCode, string>> = {\n [ExitCode.Ok]: \"success\",\n [ExitCode.ApiError]: \"API error (4xx/5xx)\",\n [ExitCode.AuthError]: \"authentication error\",\n [ExitCode.ValidationError]: \"validation error\",\n [ExitCode.NetworkError]: \"network error\",\n [ExitCode.Internal]: \"internal CLI error\",\n};\n","import chalk from \"chalk\";\nimport { Command } from \"commander\";\nimport ora from \"ora\";\n\nimport { AuthRequiredError, NetworkError, api } from \"../client.js\";\nimport {\n clearToken,\n configPath,\n getApiUrl,\n getToken,\n getTokenSource,\n setApiUrl,\n setToken,\n} from \"../config.js\";\nimport { die, emit, formatError, ValidationError } from \"../output.js\";\nimport { getRuntime } from \"../runtime.js\";\nimport {\n DEFAULT_SCOPES,\n deriveIssuer,\n discover,\n pollForToken,\n requestDeviceAuthorization,\n tryOpenBrowser,\n} from \"../oauth.js\";\n\nexport function registerAuthCommands(program: Command): void {\n program\n .command(\"login\")\n .description(\"Sign in to Papermark via the browser (OAuth device flow)\")\n .option(\n \"--token <token>\",\n \"paste an existing API token non-interactively (skip OAuth)\",\n )\n .option(\n \"--scopes <list>\",\n \"comma-separated scopes to request (defaults to read+write on documents/links plus analytics.read)\",\n )\n .option(\"--no-browser\", \"do not auto-open a browser; print the URL only\")\n .action(\n async (opts: {\n token?: string;\n scopes?: string;\n browser?: boolean;\n }) => {\n try {\n if (opts.token) {\n return await loginWithToken(opts.token);\n }\n const scopes = opts.scopes\n ? opts.scopes.split(/[\\s,]+/).filter(Boolean)\n : DEFAULT_SCOPES;\n return await loginWithDeviceFlow(scopes, {\n openBrowser: opts.browser !== false,\n });\n } catch (err) {\n die(err);\n }\n },\n );\n\n program\n .command(\"logout\")\n .description(\"Remove the stored API token\")\n .action(() => {\n clearToken();\n emit({ removed: true }, () => chalk.green(\"✓\") + \" Token removed.\");\n });\n\n program\n .command(\"whoami\")\n .description(\"Show the active token and API URL\")\n .action(() => {\n const token = getToken();\n if (!token) {\n die(new AuthRequiredError());\n }\n const partial = `${token.slice(0, 11)}...${token.slice(-4)}`;\n emit(\n {\n apiUrl: getApiUrl(),\n token: partial,\n source: getTokenSource(),\n config: configPath(),\n },\n () =>\n [\n `${chalk.bold(\"API URL:\")} ${getApiUrl()}`,\n `${chalk.bold(\"Token: \")} ${partial}`,\n `${chalk.bold(\"Source: \")} ${getTokenSource()}`,\n `${chalk.bold(\"Config: \")} ${configPath()}`,\n ].join(\"\\n\"),\n );\n });\n\n program\n .command(\"auth\")\n .description(\"Auth helpers (export, set, status)\")\n .addCommand(buildAuthExport())\n .addCommand(buildAuthSet());\n}\n\nfunction buildAuthExport(): Command {\n return new Command(\"export\")\n .description(\n \"Print current credentials as JSON. Useful for CI: redirect into a file and set PAPERMARK_CREDENTIALS_FILE.\",\n )\n .option(\n \"--unmasked\",\n \"include the full token (default: mask to first-6 + last-4 chars)\",\n )\n .action((opts: { unmasked?: boolean }) => {\n const token = getToken();\n if (!token) {\n die(new AuthRequiredError());\n }\n const payload = {\n token: opts.unmasked\n ? token\n : `${token.slice(0, 8)}***${token.slice(-4)}`,\n apiUrl: getApiUrl(),\n source: getTokenSource(),\n };\n process.stdout.write(JSON.stringify(payload, null, 2) + \"\\n\");\n if (!opts.unmasked) {\n process.stderr.write(\n chalk.dim(\n \"Token is masked. Pass --unmasked to include the full value (e.g. for writing to a secrets file).\\n\",\n ),\n );\n }\n });\n}\n\nfunction buildAuthSet(): Command {\n return new Command(\"set\")\n .description(\n \"Set credentials from stdin. Pipes a token (or JSON blob with {token, apiUrl}) into the CLI's config without leaving a tempfile on disk or exposing the value via `ps` / shell history. Ideal for CI runners pulling from a secret manager.\",\n )\n .option(\n \"--stdin\",\n \"read the token (or JSON blob with --json) from stdin until EOF\",\n )\n .option(\n \"--json\",\n \"interpret stdin as a JSON object of shape {token, apiUrl?} instead of a bare token\",\n )\n .action(async (opts: { stdin?: boolean; json?: boolean }) => {\n if (!opts.stdin) {\n die(\n new ValidationError(\n \"auth set currently requires --stdin. Pipe the token via stdin.\",\n ),\n );\n }\n\n if (process.stdin.isTTY) {\n die(\n new ValidationError(\n \"stdin is a TTY — pipe the token in (e.g. `op read op://vault/papermark | papermark auth set --stdin`).\",\n ),\n );\n }\n\n const raw = await readStdin();\n if (!raw.trim()) {\n die(\n new ValidationError(\n \"No data on stdin. Pipe a token, or exit with Ctrl-D.\",\n ),\n );\n }\n\n let token: string;\n let apiUrl: string | undefined;\n\n if (opts.json) {\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch (parseErr) {\n die(\n new ValidationError(\"stdin was not valid JSON.\", {\n parseError:\n parseErr instanceof Error ? parseErr.message : String(parseErr),\n }),\n );\n }\n if (!parsed || typeof parsed !== \"object\") {\n die(\n new ValidationError(\n 'Expected a JSON object like {\"token\":\"...\"}.',\n ),\n );\n }\n const p = parsed as { token?: unknown; apiUrl?: unknown; api_url?: unknown };\n if (typeof p.token !== \"string\" || !p.token) {\n die(\n new ValidationError('JSON is missing a non-empty \"token\" field.'),\n );\n }\n token = p.token;\n if (typeof p.apiUrl === \"string\") apiUrl = p.apiUrl;\n else if (typeof p.api_url === \"string\") apiUrl = p.api_url;\n } else {\n // Bare-token mode — strip surrounding whitespace / trailing newline.\n token = raw.trim();\n }\n\n // Snapshot prior credentials so a bad probe doesn't strand the user\n // with a half-applied apiUrl and no working token.\n const prevToken = getToken();\n const prevApiUrl = getApiUrl();\n\n setToken(token);\n if (apiUrl) setApiUrl(apiUrl);\n\n // Validate the token actually works so CI fails fast instead of passing\n // the preflight and blowing up three commands later.\n try {\n await api.listDocuments({ limit: 1 });\n } catch (err) {\n if (prevToken) setToken(prevToken);\n else clearToken();\n if (apiUrl) setApiUrl(prevApiUrl);\n die(err);\n }\n\n const partial = `${token.slice(0, 8)}***${token.slice(-4)}`;\n emit(\n { token: partial, source: getTokenSource(), config: configPath() },\n () =>\n chalk.green(\"✓\") +\n ` Token stored (${partial}). Config: ${chalk.dim(configPath())}`,\n );\n });\n}\n\nfunction readStdin(): Promise<string> {\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = [];\n process.stdin.on(\"data\", (c) => chunks.push(c));\n process.stdin.on(\"end\", () => resolve(Buffer.concat(chunks).toString(\"utf8\")));\n process.stdin.on(\"error\", reject);\n });\n}\n\nasync function loginWithToken(token: string): Promise<void> {\n const prevToken = getToken();\n setToken(token.trim());\n try {\n await api.listDocuments({ limit: 1 });\n } catch (err) {\n if (prevToken) setToken(prevToken);\n else clearToken();\n if (err instanceof NetworkError) {\n writeErrorWithHint(\n err,\n `\\n Current API URL: ${getApiUrl()}\\n` +\n \" If you're running Papermark locally, point the CLI at it:\\n\" +\n \" papermark config set api-url http://localhost:3000/api\",\n );\n }\n throw err;\n }\n emit(\n { apiUrl: getApiUrl(), config: configPath() },\n () =>\n chalk.green(\"✓\") +\n ` Logged in at ${chalk.bold(getApiUrl())}. Config: ${chalk.dim(configPath())}`,\n );\n}\n\n/**\n * Print a formatted error with an extra command-specific hint (e.g. \"your\n * api-url might be pointing at the wrong host\"), respecting --json mode,\n * then exit with the contract-mapped code (so retryable failures keep their\n * exit code 4 instead of being downgraded to 1).\n */\nfunction writeErrorWithHint(err: unknown, hint: string): never {\n const fe = formatError(err);\n if (getRuntime().json) {\n process.stderr.write(\n JSON.stringify({ ok: false, error: fe.json.error }) + \"\\n\",\n );\n } else {\n process.stderr.write(fe.human + chalk.dim(hint) + \"\\n\");\n }\n process.exit(fe.exitCode);\n}\n\nasync function loginWithDeviceFlow(\n scopes: string[],\n { openBrowser }: { openBrowser: boolean },\n): Promise<void> {\n const issuer = deriveIssuer();\n const issuerDisplay = issuer.toString().replace(/\\/$/, \"\");\n const discoverSpinner = ora(`Contacting ${issuerDisplay}`).start();\n let as;\n try {\n as = await discover(issuer);\n } catch (err) {\n discoverSpinner.fail();\n writeErrorWithHint(\n err,\n `\\n Fetched ${issuerDisplay}/.well-known/openid-configuration.\\n` +\n \" If this isn't a Papermark deployment, paste an API token instead:\\n\" +\n \" papermark login --token pm_live_xxx\",\n );\n }\n discoverSpinner.succeed(`Discovered ${as.issuer}`);\n\n const authSpinner = ora(\"Requesting device authorization\").start();\n let auth;\n try {\n auth = await requestDeviceAuthorization(as, scopes);\n } catch (err) {\n authSpinner.fail();\n throw err;\n }\n authSpinner.succeed(\"Got a user code\");\n\n const target = auth.verification_uri_complete ?? auth.verification_uri;\n console.log(\"\");\n console.log(\" \" + chalk.bold(\"Open this URL in your browser:\"));\n console.log(\" \" + chalk.cyan(target));\n console.log(\" \" + chalk.bold(\"And enter this code if prompted:\"));\n console.log(\" \" + chalk.bold(chalk.yellow(auth.user_code)));\n console.log(\"\");\n\n if (openBrowser) {\n await tryOpenBrowser(target);\n }\n\n const pollSpinner = ora(\"Waiting for you to approve in the browser…\").start();\n let token;\n try {\n token = await pollForToken(as, auth.device_code, {\n interval: auth.interval ?? 5,\n expiresIn: auth.expires_in,\n });\n } catch (err) {\n pollSpinner.fail();\n throw err;\n }\n pollSpinner.succeed(\"Access token granted\");\n\n const prevToken = getToken();\n setToken(token.access_token);\n\n // Probe the API to be sure the token actually works through withTeam.\n try {\n await api.listDocuments({ limit: 1 });\n } catch (err) {\n if (prevToken) setToken(prevToken);\n else clearToken();\n throw err;\n }\n\n const expiresIn = token.expires_in ?? null;\n const expiryLabel = formatExpiry(expiresIn);\n emit(\n {\n apiUrl: getApiUrl(),\n config: configPath(),\n ...(token.scope ? { scopes: token.scope.split(\" \") } : {}),\n ...(expiresIn != null ? { expires_in: expiresIn } : {}),\n },\n () => {\n const lines = [\n chalk.green(\"✓\") +\n ` Logged in at ${chalk.bold(getApiUrl())}. Config: ${chalk.dim(configPath())}`,\n ];\n if (token.scope) lines.push(chalk.dim(` Scopes: ${token.scope}`));\n if (expiryLabel) {\n // Stripe-style heads-up so users know re-auth is eventually required.\n lines.push(\n chalk.dim(\n ` Please note: this key will expire after ${expiryLabel}, at which point you'll need to re-authenticate.`,\n ),\n );\n }\n return lines.join(\"\\n\");\n },\n );\n}\n\nfunction formatExpiry(expiresInSeconds: number | null): string | null {\n if (expiresInSeconds == null) return null;\n const days = Math.round(expiresInSeconds / 86_400);\n if (days >= 2) return `${days} days`;\n const hours = Math.round(expiresInSeconds / 3600);\n if (hours >= 2) return `${hours} hours`;\n return `${expiresInSeconds}s`;\n}\n","import * as oauth from \"oauth4webapi\";\nimport open from \"open\";\n\nimport { getApiUrl } from \"./config.js\";\n\nexport const CLIENT_ID = \"papermark-cli\";\n\n// The scopes we ask for by default. The user can narrow these in the\n// consent screen; we never ask for write+read when read alone would do.\nexport const DEFAULT_SCOPES = [\n \"openid\",\n \"offline_access\",\n \"documents.read\",\n \"documents.write\",\n \"links.read\",\n \"links.write\",\n \"datarooms.read\",\n \"datarooms.write\",\n \"analytics.read\",\n \"visitors.read\",\n];\n\n/**\n * Derive the OAuth issuer from the configured api-url. If the api-url points\n * at a papermark deployment's `/api` (e.g. `http://localhost:3000/api` in dev)\n * we strip the trailing `/api`; if it's the canonical API subdomain\n * (`https://api.papermark.com`) we swap to the dashboard host.\n *\n * Note: the OAuth provider runs on the *dashboard* host (`app.papermark.com`),\n * not the API subdomain or the apex domain — `api.papermark.com` serves only\n * REST, and `papermark.com` is the marketing site with no OIDC discovery doc.\n * So `api.<domain>` maps to `app.<domain>`.\n */\nexport function deriveIssuer(apiUrl: string = getApiUrl()): URL {\n const url = new URL(apiUrl);\n if (url.pathname === \"/api\" || url.pathname === \"/api/\") {\n return new URL(`${url.origin}`);\n }\n if (url.hostname.startsWith(\"api.\")) {\n // Use url.host (host:port) so self-hosted deployments on a non-default\n // port don't lose it. url.hostname is host without port.\n return new URL(`${url.protocol}//${url.host.replace(/^api\\./, \"app.\")}`);\n }\n return new URL(url.origin);\n}\n\nexport interface DiscoveredAS {\n issuer: string;\n token_endpoint: string;\n device_authorization_endpoint: string;\n revocation_endpoint?: string;\n}\n\nexport async function discover(issuer: URL): Promise<oauth.AuthorizationServer> {\n const response = await oauth.discoveryRequest(issuer, {\n algorithm: \"oidc\",\n ...allowHttpIfLocal(issuer),\n });\n return oauth.processDiscoveryResponse(issuer, response);\n}\n\n/**\n * oauth4webapi refuses plain-HTTP requests for security. Local dev runs on\n * http://localhost, so we explicitly allow it in that case only. Never set\n * this for a public deployment.\n */\nfunction allowHttpIfLocal(u: URL) {\n const isLocal =\n u.protocol === \"http:\" &&\n (u.hostname === \"localhost\" ||\n u.hostname === \"127.0.0.1\" ||\n u.hostname.endsWith(\".local\"));\n return isLocal ? { [oauth.allowInsecureRequests]: true as const } : {};\n}\n\nexport interface DeviceAuthorizationResponse {\n device_code: string;\n user_code: string;\n verification_uri: string;\n verification_uri_complete?: string;\n expires_in: number;\n interval?: number;\n}\n\nexport async function requestDeviceAuthorization(\n as: oauth.AuthorizationServer,\n scopes: string[],\n): Promise<DeviceAuthorizationResponse> {\n if (!as.device_authorization_endpoint) {\n throw new Error(\n \"Authorization server does not advertise a device authorization endpoint.\",\n );\n }\n const body = new URLSearchParams({\n client_id: CLIENT_ID,\n scope: scopes.join(\" \"),\n });\n const json = await postFormJson(\n as.device_authorization_endpoint,\n body,\n \"device authorization\",\n );\n return json as unknown as DeviceAuthorizationResponse;\n}\n\n/**\n * POST a form-urlencoded body and parse the JSON response, normalizing the\n * three failure modes the device flow can hit:\n * - DNS / TLS / connect-refused → wrapped Error with the URL in the message\n * - non-2xx with a JSON body → Error preserving status + parsed payload\n * - non-2xx with HTML/text → Error preserving status + truncated body\n *\n * Returns parsed JSON on 2xx with a JSON body. The caller decides whether\n * specific error codes (e.g. authorization_pending) mean \"keep polling\".\n */\nasync function postFormJson(\n endpoint: string,\n body: URLSearchParams,\n what: string,\n): Promise<Record<string, unknown>> {\n let res: Response;\n try {\n res = await fetch(endpoint, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n Accept: \"application/json\",\n },\n body,\n });\n } catch (err) {\n const reason = err instanceof Error ? err.message : String(err);\n throw new Error(\n `${what}: network request to ${endpoint} failed (${reason}). Check connectivity and that the OAuth server is reachable.`,\n );\n }\n const text = await res.text();\n let parsed: Record<string, unknown> | null = null;\n try {\n parsed = text ? (JSON.parse(text) as Record<string, unknown>) : null;\n } catch {\n parsed = null;\n }\n if (!res.ok) {\n if (parsed) {\n const e = new Error(\n `${what} failed: ${res.status} ${JSON.stringify(parsed)}`,\n );\n // Stash the parsed body so callers (pollForToken) can branch on\n // OAuth-defined error codes without re-parsing.\n (e as Error & { body?: Record<string, unknown> }).body = parsed;\n throw e;\n }\n const snippet = text ? text.slice(0, 200) : \"(empty body)\";\n throw new Error(\n `${what} failed: HTTP ${res.status} (non-JSON response: ${snippet})`,\n );\n }\n if (!parsed) {\n throw new Error(\n `${what} succeeded but returned a non-JSON body — is the endpoint correct? URL: ${endpoint}`,\n );\n }\n return parsed;\n}\n\nexport interface TokenResponse {\n access_token: string;\n token_type: string;\n expires_in?: number;\n refresh_token?: string;\n scope?: string;\n}\n\n/**\n * Poll the token endpoint until the user approves, denies, or the device\n * code expires. Honors `authorization_pending` and `slow_down` per RFC 8628.\n */\nexport async function pollForToken(\n as: oauth.AuthorizationServer,\n deviceCode: string,\n {\n interval = 5,\n expiresIn = 600,\n onTick,\n }: { interval?: number; expiresIn?: number; onTick?: () => void } = {},\n): Promise<TokenResponse> {\n if (!as.token_endpoint) throw new Error(\"No token_endpoint in discovery\");\n const deadline = Date.now() + expiresIn * 1000;\n let wait = Math.max(interval, 1);\n\n while (Date.now() < deadline) {\n await new Promise((r) => setTimeout(r, wait * 1000));\n onTick?.();\n const body = new URLSearchParams({\n grant_type: \"urn:ietf:params:oauth:grant-type:device_code\",\n device_code: deviceCode,\n client_id: CLIENT_ID,\n });\n let parsed: Record<string, unknown>;\n try {\n parsed = await postFormJson(as.token_endpoint, body, \"token request\");\n } catch (err) {\n // OAuth defines two error codes that mean \"keep polling\": pending\n // (user hasn't approved yet) and slow_down (we're hitting too fast).\n // postFormJson stashed the parsed body on the Error.\n const errBody = (err as Error & { body?: Record<string, unknown> }).body;\n const errCode = errBody?.error as string | undefined;\n if (errCode === \"authorization_pending\") continue;\n if (errCode === \"slow_down\") {\n wait += 5;\n continue;\n }\n throw err;\n }\n return parsed as unknown as TokenResponse;\n }\n throw new Error(\"Device code expired before authorization completed.\");\n}\n\nexport async function tryOpenBrowser(url: string): Promise<void> {\n try {\n await open(url);\n } catch {\n // ignore — user can copy/paste\n }\n}\n","import chalk from \"chalk\";\nimport { Command } from \"commander\";\n\nimport {\n configPath,\n deleteKey,\n getAll,\n setApiUrl,\n} from \"../config.js\";\nimport { die } from \"../output.js\";\n\nconst KNOWN_KEYS = [\"api-url\"] as const;\ntype KnownKey = (typeof KNOWN_KEYS)[number];\n\nfunction isKnown(key: string): key is KnownKey {\n return (KNOWN_KEYS as readonly string[]).includes(key);\n}\n\nexport function registerConfigCommands(program: Command): void {\n const cfg = program.command(\"config\").description(\"Manage CLI configuration\");\n\n cfg\n .command(\"get [key]\")\n .description(\"Print one or all config values\")\n .action((key?: string) => {\n const all = getAll();\n if (!key) {\n console.log(`${chalk.dim(\"# \" + configPath())}`);\n console.log(`api-url ${all.apiUrl ?? \"\"}`);\n console.log(`token ${all.token ? \"(set)\" : \"(not set)\"}`);\n return;\n }\n if (!isKnown(key)) return die(new Error(`Unknown key: ${key}`));\n if (key === \"api-url\") console.log(all.apiUrl ?? \"\");\n });\n\n cfg\n .command(\"set <key> <value>\")\n .description(`Set a config value. Known keys: ${KNOWN_KEYS.join(\", \")}`)\n .action((key: string, value: string) => {\n if (!isKnown(key)) return die(new Error(`Unknown key: ${key}`));\n if (key === \"api-url\") setApiUrl(value);\n console.log(chalk.green(\"✓\") + ` ${key} = ${value}`);\n });\n\n cfg\n .command(\"unset <key>\")\n .description(\"Clear a config value\")\n .action((key: string) => {\n if (!isKnown(key)) return die(new Error(`Unknown key: ${key}`));\n if (key === \"api-url\") deleteKey(\"apiUrl\");\n console.log(chalk.green(\"✓\") + ` ${key} unset`);\n });\n}\n","import chalk from \"chalk\";\nimport { Command } from \"commander\";\n\nimport { api } from \"../client.js\";\nimport { die, emit, json, sanitizeForTerminal, table } from \"../output.js\";\nimport { setRuntime } from \"../runtime.js\";\n\nexport function registerDataroomsCommands(program: Command): void {\n const dr = program\n .command(\"datarooms\")\n .alias(\"dr\")\n .description(\"Manage datarooms\");\n\n dr\n .command(\"list\")\n .description(\"List datarooms\")\n .option(\"-l, --limit <n>\", \"max results (1-100)\", \"25\")\n .option(\"-c, --cursor <id>\", \"pagination cursor\")\n .option(\"-q, --query <substring>\", \"filter by dataroom name\")\n .option(\"--json\", \"output raw JSON (same as --json on the root command)\")\n .action(\n async (opts: {\n limit?: string;\n cursor?: string;\n query?: string;\n json?: boolean;\n }) => {\n if (opts.json) setRuntime({ json: true });\n try {\n const res = await api.listDatarooms({\n limit: opts.limit ? Number(opts.limit) : undefined,\n cursor: opts.cursor,\n query: opts.query,\n });\n emit(res, () => {\n const rows = res.data.map((d) => ({\n id: d.pid,\n name: truncate(d.name, 30),\n docs: String(d.document_count),\n folders: String(d.folder_count),\n created: d.created.slice(0, 10),\n }));\n const out = table(rows, [\"id\", \"name\", \"docs\", \"folders\", \"created\"]);\n return res.next_cursor\n ? out + chalk.dim(`\\n\\nMore results: --cursor ${res.next_cursor}`)\n : out;\n });\n } catch (err) {\n die(err);\n }\n },\n );\n\n dr\n .command(\"get <id>\")\n .description(\n \"Fetch one dataroom. `id` accepts the internal cuid or the `dr_...` public id.\",\n )\n .action(async (id: string) => {\n try {\n const room = await api.getDataroom(id);\n emit(room, () => json(room));\n } catch (err) {\n die(err);\n }\n });\n\n dr\n .command(\"create\")\n .description(\"Create a new (empty) dataroom\")\n .requiredOption(\"-n, --name <name>\", \"dataroom name\")\n .option(\n \"--internal-name <slug>\",\n \"private alias visible only to your team\",\n )\n .option(\"-d, --description <text>\", \"human-readable description\")\n .action(\n async (opts: {\n name: string;\n internalName?: string;\n description?: string;\n }) => {\n try {\n const room = await api.createDataroom({\n name: opts.name,\n internal_name: opts.internalName,\n description: opts.description,\n });\n emit(\n room,\n () =>\n chalk.green(\"✓\") +\n ` Dataroom created: ${chalk.bold(room.pid)}\\n` +\n json(room),\n );\n } catch (err) {\n die(err);\n }\n },\n );\n\n dr\n .command(\"update <id>\")\n .description(\n \"Update a dataroom. `id` accepts the internal cuid or the `dr_...` public id.\",\n )\n .option(\"-n, --name <name>\")\n .option(\"--internal-name <slug>\", \"set or clear (use empty string)\")\n .option(\"-d, --description <text>\", \"set or clear (use empty string)\")\n .option(\"--bulk-download <on|off>\", \"allow or block bulk download\")\n .action(\n async (\n id: string,\n opts: {\n name?: string;\n internalName?: string;\n description?: string;\n bulkDownload?: string;\n },\n ) => {\n try {\n const body: Parameters<typeof api.updateDataroom>[1] = {};\n if (opts.name !== undefined) body.name = opts.name;\n if (opts.internalName !== undefined)\n body.internal_name = opts.internalName === \"\" ? null : opts.internalName;\n if (opts.description !== undefined)\n body.description = opts.description === \"\" ? null : opts.description;\n const tri = (\n v: string | undefined,\n flag: string,\n ): boolean | undefined => {\n if (v === undefined) return undefined;\n const norm = v.toLowerCase();\n if (norm === \"on\") return true;\n if (norm === \"off\") return false;\n throw new Error(\n `Invalid value for ${flag}: ${JSON.stringify(v)} (expected \"on\" or \"off\").`,\n );\n };\n const bulk = tri(opts.bulkDownload, \"--bulk-download\");\n if (bulk !== undefined) body.allow_bulk_download = bulk;\n\n if (Object.keys(body).length === 0) {\n throw new Error(\n \"Pass at least one field to update (e.g. --name, --description, --bulk-download off).\",\n );\n }\n const room = await api.updateDataroom(id, body);\n emit(\n room,\n () =>\n chalk.green(\"✓\") +\n ` Dataroom updated: ${chalk.bold(room.pid)}\\n` +\n json(room),\n );\n } catch (err) {\n die(err);\n }\n },\n );\n\n dr\n .command(\"links <id>\")\n .description(\n \"List share links scoped to a dataroom. `id` accepts the internal cuid or the `dr_...` public id.\",\n )\n .option(\"-l, --limit <n>\", \"max results (1-100)\", \"25\")\n .option(\"-c, --cursor <id>\", \"pagination cursor\")\n .option(\"--json\", \"output raw JSON (same as --json on the root command)\")\n .action(\n async (\n id: string,\n opts: { limit?: string; cursor?: string; json?: boolean },\n ) => {\n if (opts.json) setRuntime({ json: true });\n try {\n const res = await api.listLinks({\n dataroom_id: id,\n limit: opts.limit ? Number(opts.limit) : undefined,\n cursor: opts.cursor,\n });\n emit(res, () => {\n const rows = res.data.map((l) => ({\n id: l.id,\n name: truncate(l.name ?? \"\", 30),\n url: truncate(l.url, 45),\n password: l.is_password_protected ? \"yes\" : \"\",\n expires: l.expires_at ? l.expires_at.slice(0, 10) : \"\",\n }));\n const out = table(rows, [\"id\", \"name\", \"url\", \"password\", \"expires\"]);\n return res.next_cursor\n ? out + chalk.dim(`\\n\\nMore results: --cursor ${res.next_cursor}`)\n : out;\n });\n } catch (err) {\n die(err);\n }\n },\n );\n\n dr\n .command(\"viewers <id>\")\n .description(\n \"List persistent visitors (Viewer rows) tied to a dataroom. `id` accepts the internal cuid or the `dr_...` public id.\",\n )\n .option(\"-l, --limit <n>\", \"max results (1-100)\", \"25\")\n .option(\"-c, --cursor <id>\", \"pagination cursor\")\n .option(\"--email <email>\", \"filter to a specific email (exact match)\")\n .option(\"--json\", \"output raw JSON (same as --json on the root command)\")\n .action(\n async (\n id: string,\n opts: {\n limit?: string;\n cursor?: string;\n email?: string;\n json?: boolean;\n },\n ) => {\n if (opts.json) setRuntime({ json: true });\n try {\n const res = await api.listVisitors({\n dataroom_id: id,\n limit: opts.limit ? Number(opts.limit) : undefined,\n cursor: opts.cursor,\n email: opts.email,\n });\n emit(res, () => {\n const rows = res.data.map((v) => ({\n id: v.id,\n email: sanitizeForTerminal(v.email),\n verified: v.verified ? \"yes\" : \"\",\n views: String(v.total_views),\n last_view: v.last_viewed_at?.slice(0, 10) ?? \"\",\n }));\n const out = table(rows, [\"id\", \"email\", \"verified\", \"views\", \"last_view\"]);\n return res.next_cursor\n ? out + chalk.dim(`\\n\\nMore results: --cursor ${res.next_cursor}`)\n : out;\n });\n } catch (err) {\n die(err);\n }\n },\n );\n\n dr\n .command(\"stats <id>\")\n .alias(\"analytics\")\n .description(\n \"Aggregate analytics for a dataroom: total views, unique viewers, total read time. Backed by Tinybird — subject to a stricter rate limit. `id` accepts the internal cuid or the `dr_...` public id.\",\n )\n .option(\n \"--since <unix-ms>\",\n \"window start (default: 30 days ago)\",\n (v) => Number(v),\n )\n .option(\n \"--until <unix-ms>\",\n \"window end (default: now)\",\n (v) => Number(v),\n )\n .option(\"--json\", \"output raw JSON (same as --json on the root command)\")\n .action(\n async (\n id: string,\n opts: { since?: number; until?: number; json?: boolean },\n ) => {\n if (opts.json) setRuntime({ json: true });\n try {\n const stats = await api.dataroomAnalytics(id, {\n since: opts.since,\n until: opts.until,\n });\n emit(stats, () => {\n const minutes = Math.round(stats.total_duration_seconds / 60);\n return [\n `${chalk.bold(\"Dataroom:\")} ${stats.dataroom_id}`,\n `${chalk.bold(\"Total views:\")} ${stats.total_views}`,\n `${chalk.bold(\"Unique viewers:\")} ${stats.unique_viewers}`,\n `${chalk.bold(\"Total read time:\")} ${minutes} min (${stats.total_duration_seconds.toFixed(1)} s)`,\n chalk.dim(\n `Window: ${stats.since.slice(0, 10)} → ${stats.until.slice(0, 10)}`,\n ),\n ].join(\"\\n\");\n });\n } catch (err) {\n die(err);\n }\n },\n );\n\n dr\n .command(\"delete <id>\")\n .description(\n \"Delete a dataroom. `id` accepts the internal cuid or the `dr_...` public id.\",\n )\n .action(async (id: string) => {\n try {\n const deleted = await api.deleteDataroom(id);\n emit(\n deleted,\n () => chalk.green(\"✓\") + ` Dataroom ${id} deleted.`,\n );\n } catch (err) {\n die(err);\n }\n });\n\n dr\n .command(\"attach <id>\")\n .description(\n \"Attach an existing document to a dataroom. The document stays in the team library; this just adds it to the dataroom contents.\",\n )\n .requiredOption(\"--document <id>\", \"document id to attach\")\n .option(\n \"--folder-id <fid>\",\n \"place under a specific dataroom folder (must belong to the same dataroom)\",\n )\n .action(\n async (\n id: string,\n opts: { document: string; folderId?: string },\n ) => {\n try {\n const item = await api.attachDataroomDocument(id, {\n document_id: opts.document,\n folder_id: opts.folderId,\n });\n emit(\n item,\n () =>\n chalk.green(\"✓\") +\n ` Attached document ${chalk.bold(item.document_id)} as item ${chalk.bold(item.id)}.\\n` +\n json(item),\n );\n } catch (err) {\n die(err);\n }\n },\n );\n\n dr\n .command(\"detach <id> <ddId>\")\n .description(\n \"Detach a document from a dataroom by its dataroom-document id (the item id from `attach` or `documents`, not the document id). The document stays in the team library and attached to any other datarooms.\",\n )\n .action(async (id: string, ddId: string) => {\n try {\n const deleted = await api.detachDataroomDocument(id, ddId);\n emit(\n deleted,\n () => chalk.green(\"✓\") + ` Document ${ddId} detached from dataroom.`,\n );\n } catch (err) {\n die(err);\n }\n });\n\n dr\n .command(\"move <id> <ddId>\")\n .description(\n 'Move a document to a different folder within the dataroom, by its dataroom-document id. Pass --folder-id <fid>, or --root (or --folder-id \"\" / --folder-id root) for the dataroom root.',\n )\n .option(\n \"--folder-id <fid>\",\n 'target dataroom folder id; pass \"\" or \"root\" for the dataroom root',\n )\n .option(\"--root\", \"move to the dataroom root (alias for --folder-id root)\")\n .action(\n async (\n id: string,\n ddId: string,\n opts: { folderId?: string; root?: boolean },\n ) => {\n try {\n // Root sentinels: --root, or --folder-id with \"\" or \"root\".\n const folderIsRoot =\n opts.folderId === \"\" || opts.folderId === \"root\";\n if (opts.root && opts.folderId !== undefined && !folderIsRoot) {\n throw new Error(\n \"Pass either --root or --folder-id <fid>, not both.\",\n );\n }\n if (!opts.root && opts.folderId === undefined) {\n throw new Error(\n 'Pass --folder-id <fid>, or --root (or --folder-id \"\") to move to the dataroom root.',\n );\n }\n const folder_id = opts.root || folderIsRoot ? null : opts.folderId!;\n const item = await api.moveDataroomDocument(id, ddId, { folder_id });\n emit(\n item,\n () =>\n chalk.green(\"✓\") +\n ` Document moved.${\n item.folder_path\n ? ` New folder: ${chalk.bold(item.folder_path)}`\n : \" Now at the dataroom root.\"\n }\\n` +\n json(item),\n );\n } catch (err) {\n die(err);\n }\n },\n );\n\n // ─── Dataroom folders ────────────────────────────────────────────────\n const drFolders = dr\n .command(\"folders\")\n .description(\"Manage folders inside a dataroom\");\n\n drFolders\n .command(\"list <id>\")\n .description(\"List folders in a dataroom\")\n .option(\n \"--parent <fid>\",\n \"restrict to direct children of this folder (use 'root' for top-level)\",\n )\n .option(\"-l, --limit <n>\", \"max results (1-100)\", \"50\")\n .option(\"-c, --cursor <id>\", \"pagination cursor\")\n .option(\"--json\", \"output raw JSON\")\n .action(\n async (\n id: string,\n opts: {\n parent?: string;\n limit?: string;\n cursor?: string;\n json?: boolean;\n },\n ) => {\n if (opts.json) setRuntime({ json: true });\n try {\n const res = await api.listDataroomFolders(id, {\n limit: opts.limit ? Number(opts.limit) : undefined,\n cursor: opts.cursor,\n parent_id: opts.parent,\n });\n emit(res, () => {\n const rows = res.data.map((f) => ({\n id: f.id,\n name: truncate(f.name, 30),\n path: truncate(f.path, 40),\n docs: String(f.document_count),\n children: String(f.child_folder_count),\n }));\n const out = table(rows, [\"id\", \"name\", \"path\", \"docs\", \"children\"]);\n return res.next_cursor\n ? out + chalk.dim(`\\n\\nMore results: --cursor ${res.next_cursor}`)\n : out;\n });\n } catch (err) {\n die(err);\n }\n },\n );\n\n drFolders\n .command(\"create <id>\")\n .description(\"Create a folder inside a dataroom\")\n .requiredOption(\"-n, --name <name>\", \"folder name\")\n .option(\"--parent <fid>\", \"parent folder id (omit for dataroom root)\")\n .option(\"--icon <icon>\", \"icon name (e.g. folder, briefcase, lock)\")\n .option(\"--color <color>\", \"color token (gray, red, orange, yellow, green, blue, black)\")\n .action(\n async (\n id: string,\n opts: { name: string; parent?: string; icon?: string; color?: string },\n ) => {\n try {\n const f = await api.createDataroomFolder(id, {\n name: opts.name,\n parent_id: opts.parent ?? null,\n icon: opts.icon as never,\n color: opts.color as never,\n });\n emit(\n f,\n () =>\n chalk.green(\"✓\") +\n ` Dataroom folder created: ${chalk.bold(f.id)}\\n` +\n json(f),\n );\n } catch (err) {\n die(err);\n }\n },\n );\n\n drFolders\n .command(\"get <id> <fid>\")\n .description(\"Fetch one dataroom folder\")\n .action(async (id: string, fid: string) => {\n try {\n const f = await api.getDataroomFolder(id, fid);\n emit(f, () => json(f));\n } catch (err) {\n die(err);\n }\n });\n\n drFolders\n .command(\"update <id> <fid>\")\n .description(\"Update a dataroom folder\")\n .option(\"-n, --name <name>\")\n .option(\"--icon <icon>\", \"icon name (empty string to clear)\")\n .option(\"--color <color>\", \"color token (empty string to clear)\")\n .action(\n async (\n id: string,\n fid: string,\n opts: { name?: string; icon?: string; color?: string },\n ) => {\n try {\n const body: Parameters<typeof api.updateDataroomFolder>[2] = {};\n if (opts.name !== undefined) body.name = opts.name;\n if (opts.icon !== undefined)\n body.icon = (opts.icon === \"\" ? null : opts.icon) as never;\n if (opts.color !== undefined)\n body.color = (opts.color === \"\" ? null : opts.color) as never;\n if (Object.keys(body).length === 0) {\n throw new Error(\n \"Pass at least one of --name, --icon, --color to update.\",\n );\n }\n const f = await api.updateDataroomFolder(id, fid, body);\n emit(\n f,\n () =>\n chalk.green(\"✓\") +\n ` Dataroom folder updated: ${chalk.bold(f.id)}\\n` +\n json(f),\n );\n } catch (err) {\n die(err);\n }\n },\n );\n\n drFolders\n .command(\"delete <id> <fid>\")\n .description(\"Delete a dataroom folder\")\n .option(\n \"--cascade\",\n \"also delete nested folders + dataroom-document attachments\",\n false,\n )\n .action(\n async (id: string, fid: string, opts: { cascade?: boolean }) => {\n try {\n const deleted = await api.deleteDataroomFolder(id, fid, {\n cascade: opts.cascade,\n });\n emit(\n deleted,\n () => chalk.green(\"✓\") + ` Dataroom folder ${fid} deleted.`,\n );\n } catch (err) {\n die(err);\n }\n },\n );\n\n drFolders\n .command(\"move <id> <fid>\")\n .description(\"Move a dataroom folder under a different parent\")\n .option(\n \"--parent <fid>\",\n \"target parent folder id; pass empty string for the dataroom root\",\n )\n .action(\n async (id: string, fid: string, opts: { parent?: string }) => {\n try {\n if (opts.parent === undefined) {\n throw new Error(\n \"Pass --parent <fid> (use empty string to move to the root).\",\n );\n }\n const parent_id = opts.parent === \"\" ? null : opts.parent;\n const f = await api.moveDataroomFolder(id, fid, { parent_id });\n emit(\n f,\n () =>\n chalk.green(\"✓\") +\n ` Folder moved. New path: ${chalk.bold(f.path)}\\n` +\n json(f),\n );\n } catch (err) {\n die(err);\n }\n },\n );\n\n dr\n .command(\"documents <id>\")\n .description(\n \"List documents inside a dataroom. `id` accepts the internal cuid or the `dr_...` public id.\",\n )\n .option(\"-l, --limit <n>\", \"max results (1-100)\", \"50\")\n .option(\"-c, --cursor <id>\", \"pagination cursor\")\n .option(\"--folder <id>\", \"restrict to a folder\")\n .option(\"--json\", \"output raw JSON (same as --json on the root command)\")\n .action(\n async (\n id: string,\n opts: { limit?: string; cursor?: string; folder?: string; json?: boolean },\n ) => {\n if (opts.json) setRuntime({ json: true });\n try {\n const res = await api.listDataroomDocuments(id, {\n limit: opts.limit ? Number(opts.limit) : undefined,\n cursor: opts.cursor,\n folder_id: opts.folder,\n });\n emit(res, () => {\n const rows = res.data.map((it) => ({\n id: it.id,\n document: truncate(it.document_name, 32),\n folder: truncate(it.folder_path ?? \"/\", 64),\n type: it.content_type ?? \"\",\n pages: it.num_pages?.toString() ?? \"\",\n }));\n const out = table(rows, [\"id\", \"document\", \"folder\", \"type\", \"pages\"]);\n return res.next_cursor\n ? out + chalk.dim(`\\n\\nMore results: --cursor ${res.next_cursor}`)\n : out;\n });\n } catch (err) {\n die(err);\n }\n },\n );\n}\n\nfunction truncate(s: string, n: number): string {\n const clean = sanitizeForTerminal(s);\n return clean.length > n ? clean.slice(0, n - 1) + \"…\" : clean;\n}\n","import chalk from \"chalk\";\nimport { Command } from \"commander\";\n\nimport { ApiError, NetworkError, api } from \"../client.js\";\nimport { getApiUrl, getToken, getTokenSource } from \"../config.js\";\nimport { ExitCode } from \"../exit.js\";\nimport { emit } from \"../output.js\";\nimport { getRuntime } from \"../runtime.js\";\n\ninterface Check {\n name: string;\n ok: boolean;\n detail: string;\n hint?: string;\n}\n\nexport function registerDoctorCommand(program: Command): void {\n program\n .command(\"doctor\")\n .description(\n \"Run health checks against the CLI config + Papermark API. Returns a `checks` array (JSON) and a non-zero exit if anything fails — useful as a CI preflight before running real commands.\",\n )\n .action(async () => {\n const checks: Check[] = [];\n\n // 1) Auth present\n const token = getToken();\n checks.push({\n name: \"auth.present\",\n ok: Boolean(token),\n detail: token\n ? `token found (source: ${getTokenSource()})`\n : \"no token configured\",\n hint: token ? undefined : \"Run `papermark login` or set PAPERMARK_TOKEN.\",\n });\n\n // 2) API URL configured\n const apiUrl = getApiUrl();\n checks.push({\n name: \"config.api_url\",\n ok: Boolean(apiUrl),\n detail: apiUrl,\n });\n\n // 3) API reachable + token valid — one request covers both, but split\n // into separate checks so callers can distinguish \"the server is down\"\n // from \"the server is up but my token is wrong\". Reachability cares\n // only that we got *some* HTTP response; auth.valid is the gate on\n // whether that response was a non-4xx-auth one.\n if (token) {\n try {\n await api.listDocuments({ limit: 1 });\n checks.push({\n name: \"api.reachable\",\n ok: true,\n detail: `GET /v1/documents?limit=1 → 200 at ${apiUrl}`,\n });\n checks.push({\n name: \"api.auth\",\n ok: true,\n detail: \"token accepted\",\n });\n } catch (err) {\n if (err instanceof NetworkError) {\n checks.push({\n name: \"network.api\",\n ok: false,\n detail: err.message,\n hint: \"Check your internet connection and the configured api-url.\",\n });\n } else if (err instanceof ApiError) {\n const authIssue = err.status === 401 || err.status === 403;\n // The server responded — that's reachability, regardless of\n // what status it returned.\n checks.push({\n name: \"api.reachable\",\n ok: true,\n detail: `HTTP ${err.status} ${err.code}: ${err.message}`,\n });\n checks.push({\n name: \"api.auth\",\n ok: !authIssue,\n detail: authIssue\n ? `Token rejected: HTTP ${err.status} ${err.code}`\n : `non-auth API error: HTTP ${err.status} ${err.code}`,\n hint: authIssue\n ? \"Run `papermark login` to refresh.\"\n : undefined,\n });\n } else {\n checks.push({\n name: \"api.reachable\",\n ok: false,\n detail: err instanceof Error ? err.message : String(err),\n });\n }\n }\n } else {\n checks.push({\n name: \"api.reachable\",\n ok: false,\n detail: \"skipped (no token)\",\n });\n }\n\n const allOk = checks.every((c) => c.ok);\n\n emit({ ok: allOk, checks }, () => {\n const lines = checks.map((c) => {\n const glyph = c.ok ? chalk.green(\"✓\") : chalk.red(\"✗\");\n const hint = c.hint ? chalk.dim(`\\n Hint: ${c.hint}`) : \"\";\n return `${glyph} ${chalk.bold(c.name)} ${chalk.dim(c.detail)}${hint}`;\n });\n const footer = allOk\n ? chalk.green(\"\\nAll checks passed.\")\n : chalk.red(\"\\nOne or more checks failed.\");\n return lines.join(\"\\n\") + footer;\n });\n\n if (!allOk) {\n // Don't use die() — we've already printed the payload. Just exit with\n // the right code so CI scripts can branch on it. Network failures\n // win over auth/API since DNS/connectivity issues are the most\n // useful signal for retry logic.\n const anyNetworkFailure = checks.some(\n (c) => !c.ok && c.name.startsWith(\"network\"),\n );\n const anyAuthFailure = checks.some(\n (c) =>\n !c.ok && (c.name.startsWith(\"auth\") || c.name === \"api.auth\"),\n );\n process.exit(\n anyNetworkFailure\n ? ExitCode.NetworkError\n : anyAuthFailure\n ? ExitCode.AuthError\n : ExitCode.ApiError,\n );\n }\n });\n}\n\n// Tiny guard to quiet an unused-import warning in runtime when tree-shaking\n// skips the helper. (Referenced for documentation only.)\nexport const _internal = { getRuntime };\n","import { createReadStream } from \"node:fs\";\nimport { stat } from \"node:fs/promises\";\nimport { basename } from \"node:path\";\nimport { Readable } from \"node:stream\";\n\nimport chalk from \"chalk\";\nimport { Command } from \"commander\";\nimport { lookup as lookupMimeType } from \"mime-types\";\nimport ora from \"ora\";\n\nimport { api } from \"../client.js\";\nimport { die, emit, json, sanitizeForTerminal, table } from \"../output.js\";\nimport { setRuntime } from \"../runtime.js\";\n\nexport function registerDocumentsCommands(program: Command): void {\n const docs = program\n .command(\"documents\")\n .alias(\"doc\")\n .description(\"Manage documents\");\n\n docs\n .command(\"list\")\n .description(\"List documents\")\n .option(\"-l, --limit <n>\", \"max results (1-100)\", \"25\")\n .option(\"-c, --cursor <id>\", \"pagination cursor\")\n .option(\"--json\", \"output raw JSON (same as --json on the root command)\")\n .action(async (opts: { limit?: string; cursor?: string; json?: boolean }) => {\n if (opts.json) setRuntime({ json: true });\n try {\n const res = await api.listDocuments({\n limit: opts.limit ? Number(opts.limit) : undefined,\n cursor: opts.cursor,\n });\n emit(res, () => {\n const rows = res.data.map((d) => ({\n id: d.id,\n name: truncate(d.name, 40),\n type: d.type ?? \"\",\n pages: d.num_pages?.toString() ?? \"\",\n created: d.created.slice(0, 10),\n }));\n const out = table(rows, [\"id\", \"name\", \"type\", \"pages\", \"created\"]);\n return res.next_cursor\n ? out + chalk.dim(`\\n\\nMore results: --cursor ${res.next_cursor}`)\n : out;\n });\n } catch (err) {\n die(err);\n }\n });\n\n docs\n .command(\"get <id>\")\n .description(\"Fetch one document\")\n .action(async (id: string) => {\n try {\n const doc = await api.getDocument(id);\n emit(doc, () => json(doc));\n } catch (err) {\n die(err);\n }\n });\n\n docs\n .command(\"search <query>\")\n .description(\"Search documents by name\")\n .option(\"-l, --limit <n>\", \"max results (1-100)\", \"25\")\n .option(\"--json\", \"output raw JSON (same as --json on the root command)\")\n .action(async (query: string, opts: { limit?: string; json?: boolean }) => {\n if (opts.json) setRuntime({ json: true });\n try {\n const res = await api.searchDocuments(\n query,\n opts.limit ? Number(opts.limit) : undefined,\n );\n emit(res, () => {\n const rows = res.data.map((d) => ({\n id: d.id,\n name: truncate(d.name, 40),\n type: d.type ?? \"\",\n created: d.created.slice(0, 10),\n }));\n return table(rows, [\"id\", \"name\", \"type\", \"created\"]);\n });\n } catch (err) {\n die(err);\n }\n });\n\n docs\n .command(\"update <id>\")\n .description(\"Rename a document or move it to a different team-library folder\")\n .option(\"-n, --name <name>\", \"new document name\")\n .option(\"--folder-id <id>\", \"move into folder id (use empty string for root)\")\n .action(\n async (id: string, opts: { name?: string; folderId?: string }) => {\n try {\n const body: Parameters<typeof api.updateDocument>[1] = {};\n if (opts.name !== undefined) body.name = opts.name;\n if (opts.folderId !== undefined) {\n body.folder_id = opts.folderId === \"\" ? null : opts.folderId;\n }\n if (Object.keys(body).length === 0) {\n throw new Error(\n \"Pass at least one of --name or --folder-id to update.\",\n );\n }\n const doc = await api.updateDocument(id, body);\n emit(\n doc,\n () =>\n chalk.green(\"✓\") +\n ` Document updated: ${chalk.bold(doc.id)}\\n` +\n json(doc),\n );\n } catch (err) {\n die(err);\n }\n },\n );\n\n docs\n .command(\"delete <id>\")\n .description(\"Delete a document\")\n .action(async (id: string) => {\n try {\n const deleted = await api.deleteDocument(id);\n emit(\n deleted,\n () => chalk.green(\"✓\") + ` Document ${id} deleted.`,\n );\n } catch (err) {\n die(err);\n }\n });\n\n docs\n .command(\"upload <file>\")\n .description(\"Upload a local file and create a document\")\n .option(\"-n, --name <name>\", \"override document name (default: filename)\")\n .option(\"--link\", \"also create a default share link for this document\")\n .option(\"--folder-id <id>\", \"place in folder by id (create folders via `papermark folders create`)\")\n .action(\n async (\n filePath: string,\n opts: { name?: string; link?: boolean; folderId?: string },\n ) => {\n const spinner = ora();\n try {\n const stats = await stat(filePath);\n if (!stats.isFile()) throw new Error(`${filePath} is not a file.`);\n const fileName = opts.name ?? basename(filePath);\n const contentType =\n lookupMimeType(filePath) || \"application/octet-stream\";\n\n spinner.start(\"Requesting upload URL\");\n const upload = await api.uploadUrl({\n file_name: fileName,\n content_type: contentType,\n content_length: stats.size,\n });\n spinner.succeed(\"Got presigned URL\");\n\n spinner.start(`Uploading ${humanSize(stats.size)}`);\n // Stream the file directly to S3 instead of buffering in memory —\n // dataroom PDFs can easily be hundreds of MB. fetch needs the\n // explicit Content-Length so the request doesn't fall back to\n // chunked transfer-encoding (which presigned PUT URLs reject),\n // and `duplex: \"half\"` is required by undici for any streamed\n // request body.\n const fileStream = Readable.toWeb(createReadStream(filePath));\n const putRes = await fetch(upload.upload_url, {\n method: \"PUT\",\n headers: {\n ...upload.required_headers,\n \"Content-Length\": String(stats.size),\n },\n body: fileStream as unknown as BodyInit,\n duplex: \"half\",\n } as RequestInit & { duplex: \"half\" });\n if (!putRes.ok) {\n const errText = await putRes.text().catch(() => \"\");\n throw new Error(\n `Upload failed: HTTP ${putRes.status} ${putRes.statusText}${\n errText ? \"\\n\" + errText.slice(0, 500) : \"\"\n }`,\n );\n }\n spinner.succeed(\"Uploaded to storage\");\n\n spinner.start(\"Creating document\");\n const doc = await api.createDocument({\n name: fileName,\n upload_id: upload.upload_id,\n folder_id: opts.folderId,\n create_link: opts.link ?? false,\n });\n spinner.succeed(`Document created: ${chalk.bold(doc.id)}`);\n\n // Best-effort link lookup: the document is already created, so\n // a list-links failure shouldn't fail the whole command. Surface\n // it as a warning instead and emit a single combined success\n // payload so the JSON envelope stays well-formed.\n let link: Awaited<ReturnType<typeof api.listLinks>>[\"data\"][number] | null = null;\n let linkWarning: string | null = null;\n if (opts.link) {\n try {\n const links = await api.listLinks({\n document_id: doc.id,\n limit: 1,\n });\n link = links.data[0] ?? null;\n if (!link) {\n linkWarning =\n \"--link was set but no link was returned. Try `papermark links list --document \" +\n doc.id +\n \"`.\";\n }\n } catch (warnErr) {\n linkWarning = `Document created, but listing the share link failed: ${\n warnErr instanceof Error ? warnErr.message : String(warnErr)\n }`;\n }\n if (linkWarning) {\n process.stderr.write(chalk.yellow(\"! \") + linkWarning + \"\\n\");\n }\n }\n\n emit({ document: doc, link }, () => {\n const blocks = [json(doc)];\n if (link) {\n blocks.push(\n chalk.green(\"✓\") + \" Share link: \" + chalk.bold(link.url),\n );\n }\n return blocks.join(\"\\n\");\n });\n } catch (err) {\n spinner.fail();\n die(err);\n }\n },\n );\n\n // ─── Versions ────────────────────────────────────────────────────────\n const versions = docs\n .command(\"versions\")\n .description(\"Manage document versions\");\n\n versions\n .command(\"list <id>\")\n .description(\"List versions of a document, primary first\")\n .option(\"--json\", \"output raw JSON\")\n .action(async (id: string, opts: { json?: boolean }) => {\n if (opts.json) setRuntime({ json: true });\n try {\n const res = await api.listDocumentVersions(id);\n emit(res, () => {\n const rows = res.data.map((v) => ({\n id: v.id,\n version: String(v.version_number),\n primary: v.is_primary ? \"★\" : \"\",\n type: v.type ?? \"\",\n pages: v.num_pages?.toString() ?? \"\",\n size: v.file_size !== null ? humanSize(v.file_size) : \"\",\n created: v.created.slice(0, 10),\n }));\n return table(rows, [\n \"id\",\n \"version\",\n \"primary\",\n \"type\",\n \"pages\",\n \"size\",\n \"created\",\n ]);\n });\n } catch (err) {\n die(err);\n }\n });\n\n versions\n .command(\"get <id> <vid>\")\n .description(\"Fetch a single document version\")\n .action(async (id: string, vid: string) => {\n try {\n const v = await api.getDocumentVersion(id, vid);\n emit(v, () => json(v));\n } catch (err) {\n die(err);\n }\n });\n\n versions\n .command(\"add <id> <file>\")\n .description(\"Upload a new version of an existing document\")\n .action(async (id: string, filePath: string) => {\n const spinner = ora();\n try {\n const stats = await stat(filePath);\n if (!stats.isFile()) throw new Error(`${filePath} is not a file.`);\n const fileName = basename(filePath);\n const contentType =\n lookupMimeType(filePath) || \"application/octet-stream\";\n\n spinner.start(\"Requesting upload URL\");\n const upload = await api.uploadUrl({\n file_name: fileName,\n content_type: contentType,\n content_length: stats.size,\n });\n spinner.succeed(\"Got presigned URL\");\n\n spinner.start(`Uploading ${humanSize(stats.size)}`);\n const fileStream = Readable.toWeb(createReadStream(filePath));\n const putRes = await fetch(upload.upload_url, {\n method: \"PUT\",\n headers: {\n ...upload.required_headers,\n \"Content-Length\": String(stats.size),\n },\n body: fileStream as unknown as BodyInit,\n duplex: \"half\",\n } as RequestInit & { duplex: \"half\" });\n if (!putRes.ok) {\n const errText = await putRes.text().catch(() => \"\");\n throw new Error(\n `Upload failed: HTTP ${putRes.status} ${putRes.statusText}${\n errText ? \"\\n\" + errText.slice(0, 500) : \"\"\n }`,\n );\n }\n spinner.succeed(\"Uploaded to storage\");\n\n spinner.start(\"Adding version\");\n const v = await api.addDocumentVersion(id, { upload_id: upload.upload_id });\n spinner.succeed(`Version ${v.version_number} added: ${chalk.bold(v.id)}`);\n\n emit(v, () => json(v));\n } catch (err) {\n spinner.fail();\n die(err);\n }\n });\n\n versions\n .command(\"promote <id> <vid>\")\n .description(\"Promote a version to primary\")\n .action(async (id: string, vid: string) => {\n try {\n const v = await api.promoteDocumentVersion(id, vid);\n emit(\n v,\n () =>\n chalk.green(\"✓\") +\n ` Version ${v.version_number} promoted to primary.\\n` +\n json(v),\n );\n } catch (err) {\n die(err);\n }\n });\n}\n\nfunction truncate(s: string, n: number): string {\n const clean = sanitizeForTerminal(s);\n return clean.length > n ? clean.slice(0, n - 1) + \"…\" : clean;\n}\n\nfunction humanSize(bytes: number): string {\n const units = [\"B\", \"KB\", \"MB\", \"GB\"];\n let n = bytes;\n let i = 0;\n while (n >= 1024 && i < units.length - 1) {\n n /= 1024;\n i++;\n }\n return `${n.toFixed(i === 0 ? 0 : 1)}${units[i]}`;\n}\n","import chalk from \"chalk\";\nimport { Command } from \"commander\";\n\nimport { api } from \"../client.js\";\nimport { die, emit, json, sanitizeForTerminal, table } from \"../output.js\";\nimport { setRuntime } from \"../runtime.js\";\n\nexport function registerFoldersCommands(program: Command): void {\n const folders = program\n .command(\"folders\")\n .description(\"Manage team-library folders\");\n\n folders\n .command(\"list\")\n .description(\"List folders in the team library\")\n .option(\n \"--parent <id>\",\n \"restrict to direct children of this folder (use 'root' for top-level)\",\n )\n .option(\"-l, --limit <n>\", \"max results (1-100)\", \"50\")\n .option(\"-c, --cursor <id>\", \"pagination cursor\")\n .option(\"--json\", \"output raw JSON\")\n .action(\n async (opts: {\n parent?: string;\n limit?: string;\n cursor?: string;\n json?: boolean;\n }) => {\n if (opts.json) setRuntime({ json: true });\n try {\n const res = await api.listFolders({\n limit: opts.limit ? Number(opts.limit) : undefined,\n cursor: opts.cursor,\n parent_id: opts.parent,\n });\n emit(res, () => {\n const rows = res.data.map((f) => ({\n id: f.id,\n name: truncate(f.name, 30),\n path: truncate(f.path, 40),\n docs: String(f.document_count),\n children: String(f.child_folder_count),\n }));\n const out = table(rows, [\"id\", \"name\", \"path\", \"docs\", \"children\"]);\n return res.next_cursor\n ? out + chalk.dim(`\\n\\nMore results: --cursor ${res.next_cursor}`)\n : out;\n });\n } catch (err) {\n die(err);\n }\n },\n );\n\n folders\n .command(\"create\")\n .description(\"Create a folder in the team library\")\n .requiredOption(\"-n, --name <name>\", \"folder name\")\n .option(\"--parent <id>\", \"parent folder id (omit for library root)\")\n .option(\"--icon <icon>\", \"icon name (e.g. folder, briefcase, lock)\")\n .option(\"--color <color>\", \"color token (gray, red, orange, yellow, green, blue, black)\")\n .action(\n async (opts: {\n name: string;\n parent?: string;\n icon?: string;\n color?: string;\n }) => {\n try {\n const f = await api.createFolder({\n name: opts.name,\n parent_id: opts.parent ?? null,\n icon: opts.icon as never,\n color: opts.color as never,\n });\n emit(\n f,\n () =>\n chalk.green(\"✓\") +\n ` Folder created: ${chalk.bold(f.id)}\\n` +\n json(f),\n );\n } catch (err) {\n die(err);\n }\n },\n );\n\n folders\n .command(\"get <id>\")\n .description(\"Fetch one folder\")\n .action(async (id: string) => {\n try {\n const f = await api.getFolder(id);\n emit(f, () => json(f));\n } catch (err) {\n die(err);\n }\n });\n\n folders\n .command(\"update <id>\")\n .description(\"Update a folder\")\n .option(\"-n, --name <name>\")\n .option(\"--icon <icon>\", \"icon name (empty string to clear)\")\n .option(\"--color <color>\", \"color token (empty string to clear)\")\n .action(\n async (\n id: string,\n opts: { name?: string; icon?: string; color?: string },\n ) => {\n try {\n const body: Parameters<typeof api.updateFolder>[1] = {};\n if (opts.name !== undefined) body.name = opts.name;\n if (opts.icon !== undefined)\n body.icon = (opts.icon === \"\" ? null : opts.icon) as never;\n if (opts.color !== undefined)\n body.color = (opts.color === \"\" ? null : opts.color) as never;\n if (Object.keys(body).length === 0) {\n throw new Error(\n \"Pass at least one of --name, --icon, --color to update.\",\n );\n }\n const f = await api.updateFolder(id, body);\n emit(\n f,\n () =>\n chalk.green(\"✓\") +\n ` Folder updated: ${chalk.bold(f.id)}\\n` +\n json(f),\n );\n } catch (err) {\n die(err);\n }\n },\n );\n\n folders\n .command(\"delete <id>\")\n .description(\"Delete a folder\")\n .option(\n \"--cascade\",\n \"also delete nested folders and every document inside them\",\n false,\n )\n .action(async (id: string, opts: { cascade?: boolean }) => {\n try {\n const deleted = await api.deleteFolder(id, { cascade: opts.cascade });\n emit(\n deleted,\n () => chalk.green(\"✓\") + ` Folder ${id} deleted.`,\n );\n } catch (err) {\n die(err);\n }\n });\n\n folders\n .command(\"move <id>\")\n .description(\"Move a folder under a different parent\")\n .option(\n \"--parent <id>\",\n \"target parent folder id; pass empty string to move to the library root\",\n )\n .action(async (id: string, opts: { parent?: string }) => {\n try {\n if (opts.parent === undefined) {\n throw new Error(\n \"Pass --parent <id> (use empty string to move to the root).\",\n );\n }\n const parent_id = opts.parent === \"\" ? null : opts.parent;\n const f = await api.moveFolder(id, { parent_id });\n emit(\n f,\n () =>\n chalk.green(\"✓\") +\n ` Folder moved. New path: ${chalk.bold(f.path)}\\n` +\n json(f),\n );\n } catch (err) {\n die(err);\n }\n });\n}\n\nfunction truncate(s: string, n: number): string {\n const clean = sanitizeForTerminal(s);\n return clean.length > n ? clean.slice(0, n - 1) + \"…\" : clean;\n}\n","import chalk from \"chalk\";\nimport { Command } from \"commander\";\n\nimport {\n api,\n WatermarkConfig,\n WatermarkPosition,\n WatermarkRotation,\n} from \"../client.js\";\nimport { die, emit, json, sanitizeForTerminal, table } from \"../output.js\";\nimport { setRuntime } from \"../runtime.js\";\n\nconst WATERMARK_POSITIONS: readonly WatermarkPosition[] = [\n \"top-left\",\n \"top-center\",\n \"top-right\",\n \"middle-left\",\n \"middle-center\",\n \"middle-right\",\n \"bottom-left\",\n \"bottom-center\",\n \"bottom-right\",\n];\nconst WATERMARK_ROTATIONS: readonly WatermarkRotation[] = [0, 30, 45, 90, 180];\n\ninterface WatermarkOpts {\n watermarkText?: string;\n watermarkTiled?: string;\n watermarkPosition?: string;\n watermarkRotation?: string;\n watermarkColor?: string;\n watermarkFontSize?: string;\n watermarkOpacity?: string;\n}\n\n// Parse the seven --watermark-* flags into a public WatermarkConfig, or\n// return undefined when none were passed. Throws on partial/invalid input.\nfunction parseWatermarkConfig(opts: WatermarkOpts): WatermarkConfig | undefined {\n const fields = {\n text: opts.watermarkText,\n is_tiled: opts.watermarkTiled,\n position: opts.watermarkPosition,\n rotation: opts.watermarkRotation,\n color: opts.watermarkColor,\n font_size: opts.watermarkFontSize,\n opacity: opts.watermarkOpacity,\n };\n const flagNames: Record<keyof typeof fields, string> = {\n text: \"--watermark-text\",\n is_tiled: \"--watermark-tiled\",\n position: \"--watermark-position\",\n rotation: \"--watermark-rotation\",\n color: \"--watermark-color\",\n font_size: \"--watermark-font-size\",\n opacity: \"--watermark-opacity\",\n };\n const provided = Object.entries(fields).filter(([, v]) => v !== undefined);\n if (provided.length === 0) return undefined;\n\n const missing = Object.entries(fields)\n .filter(([, v]) => v === undefined)\n .map(([k]) => flagNames[k as keyof typeof fields]);\n if (missing.length > 0) {\n throw new Error(\n `Watermark config is partial. Missing: ${missing.join(\", \")}.`,\n );\n }\n\n const tiled =\n fields.is_tiled!.toLowerCase() === \"true\" ||\n fields.is_tiled!.toLowerCase() === \"on\";\n const tiledOff =\n fields.is_tiled!.toLowerCase() === \"false\" ||\n fields.is_tiled!.toLowerCase() === \"off\";\n if (!tiled && !tiledOff) {\n throw new Error(\n `Invalid --watermark-tiled value ${JSON.stringify(fields.is_tiled)} (expected on/off).`,\n );\n }\n\n if (!WATERMARK_POSITIONS.includes(fields.position as WatermarkPosition)) {\n throw new Error(\n `Invalid --watermark-position ${JSON.stringify(fields.position)}. Expected one of: ${WATERMARK_POSITIONS.join(\", \")}.`,\n );\n }\n const rotation = Number(fields.rotation);\n if (\n !Number.isFinite(rotation) ||\n !WATERMARK_ROTATIONS.includes(rotation as WatermarkRotation)\n ) {\n throw new Error(\n `Invalid --watermark-rotation ${JSON.stringify(fields.rotation)}. Expected one of: ${WATERMARK_ROTATIONS.join(\", \")}.`,\n );\n }\n if (!/^#([0-9A-Fa-f]{3}){1,2}$/.test(fields.color!)) {\n throw new Error(\n `Invalid --watermark-color ${JSON.stringify(fields.color)}. Expected #RGB or #RRGGBB.`,\n );\n }\n const fontSize = Number(fields.font_size);\n if (!Number.isInteger(fontSize) || fontSize < 1 || fontSize > 96) {\n throw new Error(\n `Invalid --watermark-font-size ${JSON.stringify(fields.font_size)}. Expected integer 1-96.`,\n );\n }\n const opacity = Number(fields.opacity);\n if (!Number.isFinite(opacity) || opacity < 0 || opacity > 1) {\n throw new Error(\n `Invalid --watermark-opacity ${JSON.stringify(fields.opacity)}. Expected 0-1.`,\n );\n }\n\n return {\n text: fields.text!,\n is_tiled: tiled,\n position: fields.position as WatermarkPosition,\n rotation: rotation as WatermarkRotation,\n color: fields.color!,\n font_size: fontSize,\n opacity,\n };\n}\n\nfunction addWatermarkOptions(cmd: Command): Command {\n return cmd\n .option(\n \"--watermark-text <text>\",\n \"watermark text; tokens {{email}} {{date}} {{time}} {{link}} {{ipAddress}} interpolated per view\",\n )\n .option(\"--watermark-tiled <on|off>\", \"tile the watermark across the page\")\n .option(\n \"--watermark-position <pos>\",\n `anchor position (${WATERMARK_POSITIONS.join(\"|\")})`,\n )\n .option(\n \"--watermark-rotation <deg>\",\n `rotation in degrees (${WATERMARK_ROTATIONS.join(\"|\")})`,\n )\n .option(\"--watermark-color <hex>\", \"text color as #RGB or #RRGGBB\")\n .option(\"--watermark-font-size <n>\", \"font size 1-96\")\n .option(\"--watermark-opacity <n>\", \"opacity 0-1\");\n}\n\nexport function registerLinksCommands(program: Command): void {\n const links = program.command(\"links\").description(\"Manage share links\");\n\n links\n .command(\"list\")\n .description(\"List share links\")\n .option(\"-l, --limit <n>\", \"max results (1-100)\", \"25\")\n .option(\"-c, --cursor <id>\", \"pagination cursor\")\n .option(\"--document <id>\", \"filter by document id\")\n .option(\"--dataroom <id>\", \"filter by dataroom id\")\n .option(\"--json\", \"output raw JSON (same as --json on the root command)\")\n .action(\n async (opts: {\n limit?: string;\n cursor?: string;\n document?: string;\n dataroom?: string;\n json?: boolean;\n }) => {\n if (opts.json) setRuntime({ json: true });\n try {\n const res = await api.listLinks({\n limit: opts.limit ? Number(opts.limit) : undefined,\n cursor: opts.cursor,\n document_id: opts.document,\n dataroom_id: opts.dataroom,\n });\n emit(res, () => {\n const rows = res.data.map((l) => ({\n id: l.id,\n name: truncate(l.name ?? \"\", 30),\n url: truncate(l.url, 45),\n password: l.is_password_protected ? \"yes\" : \"\",\n expires: l.expires_at ? l.expires_at.slice(0, 10) : \"\",\n }));\n const out = table(rows, [\"id\", \"name\", \"url\", \"password\", \"expires\"]);\n return res.next_cursor\n ? out + chalk.dim(`\\n\\nMore results: --cursor ${res.next_cursor}`)\n : out;\n });\n } catch (err) {\n die(err);\n }\n },\n );\n\n links\n .command(\"get <id>\")\n .description(\"Fetch one share link\")\n .action(async (id: string) => {\n try {\n const link = await api.getLink(id);\n emit(link, () => json(link));\n } catch (err) {\n die(err);\n }\n });\n\n addWatermarkOptions(\n links\n .command(\"create\")\n .description(\"Create a share link for a document or dataroom\")\n .option(\"--document <id>\", \"document id\")\n .option(\"--dataroom <id>\", \"dataroom id\")\n .option(\"-n, --name <name>\", \"link name\")\n .option(\"--expires <iso-date>\", \"expiration date (ISO 8601)\")\n .option(\"--password <pw>\", \"require a password to view\")\n .option(\"--email-protected\", \"require email before viewing\", false)\n .option(\"--allow-download\", \"allow viewer to download the file\", false)\n .option(\n \"--confidential-view\",\n \"reveal only a narrow band of each page at a time; blurs the rest to prevent full-page screenshots\",\n false,\n )\n .option(\"--watermark\", \"enable watermark overlay (use with --watermark-*)\", false),\n )\n .action(\n async (opts: {\n document?: string;\n dataroom?: string;\n name?: string;\n expires?: string;\n password?: string;\n emailProtected?: boolean;\n allowDownload?: boolean;\n confidentialView?: boolean;\n watermark?: boolean;\n } & WatermarkOpts) => {\n try {\n if (!opts.document && !opts.dataroom) {\n throw new Error(\"Either --document <id> or --dataroom <id> is required.\");\n }\n const watermarkConfig = parseWatermarkConfig(opts);\n // Implicit enable: passing any --watermark-* flag turns the watermark\n // on without needing --watermark on top.\n const enableWatermark = opts.watermark || watermarkConfig !== undefined;\n const link = await api.createLink({\n document_id: opts.document,\n dataroom_id: opts.dataroom,\n name: opts.name,\n expires_at: opts.expires,\n password: opts.password,\n email_protected: opts.emailProtected,\n allow_download: opts.allowDownload,\n enable_confidential_view: opts.confidentialView,\n enable_watermark: enableWatermark || undefined,\n watermark_config: watermarkConfig,\n });\n emit(\n link,\n () =>\n chalk.green(\"✓\") +\n \" Link created\\n\" +\n chalk.bold(\"URL: \") +\n link.url +\n \"\\n\" +\n json(link),\n );\n } catch (err) {\n die(err);\n }\n },\n );\n\n addWatermarkOptions(\n links\n .command(\"update <id>\")\n .description(\"Update an existing share link\")\n .option(\"-n, --name <name>\")\n .option(\"--expires <iso-date>\", \"expiration date (ISO 8601), or empty string to clear\")\n .option(\"--password <pw>\", \"set a password (empty string to clear)\")\n .option(\"--email-protected <on|off>\")\n .option(\"--email-authenticated <on|off>\")\n .option(\"--allow-download <on|off>\")\n .option(\n \"--allow-list <items>\",\n \"comma-separated email/domain allow list (e.g. '@acme.com,bob@x.com')\",\n )\n .option(\"--deny-list <items>\", \"comma-separated email/domain deny list\")\n .option(\"--watermark <on|off>\", \"enable watermark overlay\")\n .option(\"--watermark-clear\", \"clear the existing watermark config\", false)\n .option(\"--screenshot-protection <on|off>\", \"blur on screenshot\")\n .option(\n \"--confidential-view <on|off>\",\n \"reveal only a narrow band of each page at a time; blurs the rest to prevent full-page screenshots\",\n ),\n )\n .action(\n async (\n id: string,\n opts: {\n name?: string;\n expires?: string;\n password?: string;\n emailProtected?: string;\n emailAuthenticated?: string;\n allowDownload?: string;\n allowList?: string;\n denyList?: string;\n watermark?: string;\n watermarkClear?: boolean;\n screenshotProtection?: string;\n confidentialView?: string;\n } & WatermarkOpts,\n ) => {\n try {\n const tri = (\n v: string | undefined,\n flag: string,\n ): boolean | undefined => {\n if (v === undefined) return undefined;\n const norm = v.toLowerCase();\n if (norm === \"on\") return true;\n if (norm === \"off\") return false;\n throw new Error(\n `Invalid value for ${flag}: ${JSON.stringify(v)} (expected \"on\" or \"off\").`,\n );\n };\n const list = (v: string | undefined): string[] | undefined =>\n v === undefined\n ? undefined\n : v === \"\"\n ? []\n : v.split(\",\").map((s) => s.trim()).filter(Boolean);\n\n const body: Parameters<typeof api.updateLink>[1] = {};\n if (opts.name !== undefined) body.name = opts.name;\n if (opts.expires !== undefined)\n body.expires_at = opts.expires === \"\" ? null : opts.expires;\n if (opts.password !== undefined)\n body.password = opts.password === \"\" ? null : opts.password;\n const ep = tri(opts.emailProtected, \"--email-protected\");\n if (ep !== undefined) body.email_protected = ep;\n const ea = tri(opts.emailAuthenticated, \"--email-authenticated\");\n if (ea !== undefined) body.email_authenticated = ea;\n const ad = tri(opts.allowDownload, \"--allow-download\");\n if (ad !== undefined) body.allow_download = ad;\n const al = list(opts.allowList);\n if (al !== undefined) body.allow_list = al;\n const dl = list(opts.denyList);\n if (dl !== undefined) body.deny_list = dl;\n const wm = tri(opts.watermark, \"--watermark\");\n if (wm !== undefined) body.enable_watermark = wm;\n const watermarkConfig = parseWatermarkConfig(opts);\n if (opts.watermarkClear && watermarkConfig !== undefined) {\n throw new Error(\n \"Pass either --watermark-clear or --watermark-* flags, not both.\",\n );\n }\n if (opts.watermarkClear) {\n body.watermark_config = null;\n } else if (watermarkConfig !== undefined) {\n body.watermark_config = watermarkConfig;\n // Implicit enable on update too: passing a config without an\n // explicit --watermark on|off turns the toggle on. Mirrors create.\n if (wm === undefined) body.enable_watermark = true;\n }\n const sp = tri(opts.screenshotProtection, \"--screenshot-protection\");\n if (sp !== undefined) body.enable_screenshot_protection = sp;\n const cv = tri(opts.confidentialView, \"--confidential-view\");\n if (cv !== undefined) body.enable_confidential_view = cv;\n\n if (Object.keys(body).length === 0) {\n throw new Error(\n \"Pass at least one field to update (e.g. --name, --expires, --password).\",\n );\n }\n const link = await api.updateLink(id, body);\n emit(\n link,\n () =>\n chalk.green(\"✓\") + ` Link updated: ${chalk.bold(link.id)}\\n` +\n json(link),\n );\n } catch (err) {\n die(err);\n }\n },\n );\n\n links\n .command(\"delete <id>\")\n .description(\"Revoke a share link\")\n .action(async (id: string) => {\n try {\n const deleted = await api.deleteLink(id);\n emit(\n deleted,\n () => chalk.green(\"✓\") + ` Link ${id} revoked.`,\n );\n } catch (err) {\n die(err);\n }\n });\n}\n\nfunction truncate(s: string, n: number): string {\n const clean = sanitizeForTerminal(s);\n return clean.length > n ? clean.slice(0, n - 1) + \"…\" : clean;\n}\n","import chalk from \"chalk\";\nimport { Command } from \"commander\";\n\nimport { api } from \"../client.js\";\nimport { die, emit, sanitizeForTerminal, table } from \"../output.js\";\nimport { setRuntime } from \"../runtime.js\";\n\nexport function registerViewsCommands(program: Command): void {\n const views = program.command(\"views\").description(\"Read link view analytics\");\n\n views\n .command(\"list\")\n .description(\"List views for a share link\")\n .requiredOption(\"--link <id>\", \"link id\")\n .option(\"-l, --limit <n>\", \"max results (1-100)\", \"25\")\n .option(\"-c, --cursor <id>\", \"pagination cursor\")\n .option(\"--json\", \"output raw JSON (same as --json on the root command)\")\n .action(\n async (opts: { link: string; limit?: string; cursor?: string; json?: boolean }) => {\n if (opts.json) setRuntime({ json: true });\n try {\n const res = await api.listViews(opts.link, {\n limit: opts.limit ? Number(opts.limit) : undefined,\n cursor: opts.cursor,\n });\n emit(res, () => {\n const rows = res.data.map((v) => ({\n id: v.id,\n viewer: sanitizeForTerminal(v.viewer_email ?? \"\"),\n type: v.view_type ?? \"\",\n viewed: v.viewed_at.replace(\"T\", \" \").slice(0, 16),\n downloaded: v.downloaded_at ? v.downloaded_at.slice(0, 10) : \"\",\n }));\n const out = table(rows, [\"id\", \"viewer\", \"type\", \"viewed\", \"downloaded\"]);\n return res.next_cursor\n ? out + chalk.dim(`\\n\\nMore results: --cursor ${res.next_cursor}`)\n : out;\n });\n } catch (err) {\n die(err);\n }\n },\n );\n}\n","import chalk from \"chalk\";\nimport { Command } from \"commander\";\n\nimport { api } from \"../client.js\";\nimport { die, emit, json, sanitizeForTerminal, table } from \"../output.js\";\nimport { setRuntime } from \"../runtime.js\";\n\nexport function registerVisitorsCommands(program: Command): void {\n const visitors = program\n .command(\"visitors\")\n .description(\"Manage persistent visitors (Viewer rows)\");\n\n visitors\n .command(\"list\")\n .description(\"List visitors\")\n .option(\"-l, --limit <n>\", \"max results (1-100)\", \"25\")\n .option(\"-c, --cursor <id>\", \"pagination cursor\")\n .option(\"--email <email>\", \"exact email match (case-insensitive)\")\n .option(\"--dataroom <id>\", \"filter by dataroom id\")\n .option(\"--json\", \"output raw JSON\")\n .action(\n async (opts: {\n limit?: string;\n cursor?: string;\n email?: string;\n dataroom?: string;\n json?: boolean;\n }) => {\n if (opts.json) setRuntime({ json: true });\n try {\n const res = await api.listVisitors({\n limit: opts.limit ? Number(opts.limit) : undefined,\n cursor: opts.cursor,\n email: opts.email,\n dataroom_id: opts.dataroom,\n });\n emit(res, () => {\n const rows = res.data.map((v) => ({\n id: v.id,\n email: sanitizeForTerminal(v.email),\n verified: v.verified ? \"yes\" : \"\",\n views: String(v.total_views),\n last_view: v.last_viewed_at?.slice(0, 10) ?? \"\",\n }));\n const out = table(rows, [\"id\", \"email\", \"verified\", \"views\", \"last_view\"]);\n return res.next_cursor\n ? out + chalk.dim(`\\n\\nMore results: --cursor ${res.next_cursor}`)\n : out;\n });\n } catch (err) {\n die(err);\n }\n },\n );\n\n visitors\n .command(\"get <id>\")\n .description(\"Fetch one visitor\")\n .action(async (id: string) => {\n try {\n const v = await api.getVisitor(id);\n emit(v, () => json(v));\n } catch (err) {\n die(err);\n }\n });\n\n visitors\n .command(\"views <id>\")\n .description(\"List view events tied to a visitor\")\n .option(\"-l, --limit <n>\", \"max results (1-100)\", \"25\")\n .option(\"-c, --cursor <id>\", \"pagination cursor\")\n .option(\"--json\", \"output raw JSON\")\n .action(\n async (\n id: string,\n opts: { limit?: string; cursor?: string; json?: boolean },\n ) => {\n if (opts.json) setRuntime({ json: true });\n try {\n const res = await api.listVisitorViews(id, {\n limit: opts.limit ? Number(opts.limit) : undefined,\n cursor: opts.cursor,\n });\n emit(res, () => {\n const rows = res.data.map((v) => ({\n id: v.id,\n link: v.link_id,\n type: v.view_type,\n viewed: v.viewed_at.replace(\"T\", \" \").slice(0, 16),\n downloaded: v.downloaded_at ? v.downloaded_at.slice(0, 10) : \"\",\n }));\n const out = table(rows, [\"id\", \"link\", \"type\", \"viewed\", \"downloaded\"]);\n return res.next_cursor\n ? out + chalk.dim(`\\n\\nMore results: --cursor ${res.next_cursor}`)\n : out;\n });\n } catch (err) {\n die(err);\n }\n },\n );\n}\n"],"mappings":"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","names":["Command","chalk","program","chalk","chalk","json","program","chalk","chalk","program","chalk","chalk","program","truncate","chalk","chalk","program","chalk","chalk","ora","program","truncate","chalk","ora","chalk","program","truncate","chalk","chalk","program","truncate","chalk","chalk","program","chalk","chalk","program","chalk","Command"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/commands/analytics.ts","../src/config.ts","../src/debug.ts","../src/runtime.ts","../src/client.ts","../src/output.ts","../src/exit.ts","../src/commands/auth.ts","../src/oauth.ts","../src/commands/config.ts","../src/commands/datarooms.ts","../src/commands/permissions-input.ts","../src/commands/doctor.ts","../src/commands/documents.ts","../src/commands/folders.ts","../src/commands/links.ts","../src/commands/views.ts","../src/commands/visitors.ts"],"sourcesContent":["import { Command } from \"commander\";\n\nimport { registerAnalyticsCommands } from \"./commands/analytics.js\";\nimport { registerAuthCommands } from \"./commands/auth.js\";\nimport { registerConfigCommands } from \"./commands/config.js\";\nimport { registerDataroomsCommands } from \"./commands/datarooms.js\";\nimport { registerDoctorCommand } from \"./commands/doctor.js\";\nimport { registerDocumentsCommands } from \"./commands/documents.js\";\nimport { registerFoldersCommands } from \"./commands/folders.js\";\nimport { registerLinksCommands } from \"./commands/links.js\";\nimport { registerViewsCommands } from \"./commands/views.js\";\nimport { registerVisitorsCommands } from \"./commands/visitors.js\";\nimport { setRuntime } from \"./runtime.js\";\n\nconst program = new Command();\n\nprogram\n .name(\"papermark\")\n .description(\"Papermark CLI — manage documents, links, and views\")\n .version(\"0.1.0\")\n .option(\n \"--json\",\n \"emit machine-readable JSON on stdout (auto-enabled when piped)\",\n )\n .option(\n \"--dry-run\",\n \"print the HTTP request that would be sent and exit (token redacted)\",\n )\n .option(\"--no-color\", \"disable ANSI color (same as NO_COLOR=1)\")\n // Promote global flags so subcommands can read them via their parent.\n .hook(\"preAction\", (thisCommand) => {\n const opts = thisCommand.opts<{\n json?: boolean;\n dryRun?: boolean;\n color?: boolean;\n }>();\n setRuntime({\n json: Boolean(opts.json) || !process.stdout.isTTY,\n dryRun: Boolean(opts.dryRun),\n color: opts.color !== false && !process.env.NO_COLOR,\n });\n });\n\nregisterAuthCommands(program);\nregisterDoctorCommand(program);\nregisterDocumentsCommands(program);\nregisterFoldersCommands(program);\nregisterLinksCommands(program);\nregisterViewsCommands(program);\nregisterDataroomsCommands(program);\nregisterVisitorsCommands(program);\nregisterAnalyticsCommands(program);\nregisterConfigCommands(program);\n\nprogram.parseAsync(process.argv);\n","import chalk from \"chalk\";\nimport { Command } from \"commander\";\n\nimport { api } from \"../client.js\";\nimport { die, emit, json, table } from \"../output.js\";\nimport { setRuntime } from \"../runtime.js\";\n\n// Tinybird-backed aggregate analytics. The dataroom-level variant is also\n// surfaced as `papermark dr stats <id>` for convenience; this top-level\n// `analytics` group covers the document, link, and per-view endpoints\n// that don't have a dedicated parent command.\nexport function registerAnalyticsCommands(program: Command): void {\n const analytics = program\n .command(\"analytics\")\n .description(\"Aggregate analytics (Tinybird-backed, tighter rate limit)\");\n\n analytics\n .command(\"document <id>\")\n .description(\n \"Document analytics: total views, unique viewers, total read time, per-page average duration.\",\n )\n .option(\"--since <unix-ms>\", \"window start (default: 30 days ago)\", (v) => Number(v))\n .option(\"--until <unix-ms>\", \"window end (default: now)\", (v) => Number(v))\n .option(\"--json\", \"output raw JSON\")\n .action(\n async (\n id: string,\n opts: { since?: number; until?: number; json?: boolean },\n ) => {\n if (opts.json) setRuntime({ json: true });\n try {\n const stats = await api.documentAnalytics(id, {\n since: opts.since,\n until: opts.until,\n });\n emit(stats, () => formatDocumentAnalytics(stats));\n } catch (err) {\n die(err);\n }\n },\n );\n\n analytics\n .command(\"link <id>\")\n .description(\"Aggregate analytics for a single share link.\")\n .option(\"--since <unix-ms>\", \"window start (default: 30 days ago)\", (v) => Number(v))\n .option(\"--until <unix-ms>\", \"window end (default: now)\", (v) => Number(v))\n .option(\"--json\", \"output raw JSON\")\n .action(\n async (\n id: string,\n opts: { since?: number; until?: number; json?: boolean },\n ) => {\n if (opts.json) setRuntime({ json: true });\n try {\n const stats = await api.linkAnalytics(id, {\n since: opts.since,\n until: opts.until,\n });\n emit(stats, () => formatLinkAnalytics(stats));\n } catch (err) {\n die(err);\n }\n },\n );\n\n analytics\n .command(\"dataroom <id>\")\n .description(\"Aggregate analytics for a dataroom (alias of `papermark dr stats`).\")\n .option(\"--since <unix-ms>\", \"window start (default: 30 days ago)\", (v) => Number(v))\n .option(\"--until <unix-ms>\", \"window end (default: now)\", (v) => Number(v))\n .option(\"--json\", \"output raw JSON\")\n .action(\n async (\n id: string,\n opts: { since?: number; until?: number; json?: boolean },\n ) => {\n if (opts.json) setRuntime({ json: true });\n try {\n const stats = await api.dataroomAnalytics(id, {\n since: opts.since,\n until: opts.until,\n });\n emit(stats, () => formatDataroomAnalytics(stats));\n } catch (err) {\n die(err);\n }\n },\n );\n\n analytics\n .command(\"view <id>\")\n .description(\n \"Per-view breakdown: page-by-page time spent, total duration, viewer geo + client.\",\n )\n .option(\"--json\", \"output raw JSON\")\n .action(async (id: string, opts: { json?: boolean }) => {\n if (opts.json) setRuntime({ json: true });\n try {\n const stats = await api.viewAnalytics(id);\n emit(stats, () => json(stats));\n } catch (err) {\n die(err);\n }\n });\n}\n\nfunction formatDocumentAnalytics(stats: Awaited<ReturnType<typeof api.documentAnalytics>>): string {\n const minutes = Math.round(stats.total_duration_seconds / 60);\n const lines = [\n `${chalk.bold(\"Document:\")} ${stats.document_id}`,\n `${chalk.bold(\"Total views:\")} ${stats.total_views}`,\n `${chalk.bold(\"Unique viewers:\")} ${stats.unique_viewers}`,\n `${chalk.bold(\"Total read time:\")} ${minutes} min (${stats.total_duration_seconds.toFixed(1)} s)`,\n chalk.dim(`Window: ${stats.since.slice(0, 10)} → ${stats.until.slice(0, 10)}`),\n ];\n if (stats.avg_page_duration_seconds.length > 0) {\n const rows = stats.avg_page_duration_seconds.map((p) => ({\n page: String(p.page_number),\n avg_seconds: p.avg_duration_seconds.toFixed(1),\n }));\n lines.push(\"\", chalk.bold(\"Per-page average duration:\"));\n lines.push(table(rows, [\"page\", \"avg_seconds\"]));\n }\n return lines.join(\"\\n\");\n}\n\nfunction formatLinkAnalytics(stats: Awaited<ReturnType<typeof api.linkAnalytics>>): string {\n const minutes = Math.round(stats.total_duration_seconds / 60);\n return [\n `${chalk.bold(\"Link:\")} ${stats.link_id}`,\n `${chalk.bold(\"Total views:\")} ${stats.total_views}`,\n `${chalk.bold(\"Unique viewers:\")} ${stats.unique_viewers}`,\n `${chalk.bold(\"Total read time:\")} ${minutes} min (${stats.total_duration_seconds.toFixed(1)} s)`,\n chalk.dim(`Window: ${stats.since.slice(0, 10)} → ${stats.until.slice(0, 10)}`),\n ].join(\"\\n\");\n}\n\nfunction formatDataroomAnalytics(\n stats: Awaited<ReturnType<typeof api.dataroomAnalytics>>,\n): string {\n const minutes = Math.round(stats.total_duration_seconds / 60);\n return [\n `${chalk.bold(\"Dataroom:\")} ${stats.dataroom_id}`,\n `${chalk.bold(\"Total views:\")} ${stats.total_views}`,\n `${chalk.bold(\"Unique viewers:\")} ${stats.unique_viewers}`,\n `${chalk.bold(\"Total read time:\")} ${minutes} min (${stats.total_duration_seconds.toFixed(1)} s)`,\n chalk.dim(`Window: ${stats.since.slice(0, 10)} → ${stats.until.slice(0, 10)}`),\n ].join(\"\\n\");\n}\n","import { readFileSync } from \"node:fs\";\n\nimport Conf from \"conf\";\n\ninterface CliConfig {\n token?: string;\n apiUrl?: string;\n}\n\n// conf defaults the location to $XDG_CONFIG_HOME/papermark or ~/.config/papermark\n// on macOS/Linux and a Roaming AppData folder on Windows, with 0600 perms.\nconst store = new Conf<CliConfig>({\n projectName: \"papermark\",\n configFileMode: 0o600,\n defaults: {\n apiUrl: \"https://api.papermark.com\",\n },\n});\n\n// Read once per process — CI runners pass this as a volume-mounted\n// secret; no reason to re-stat on every request.\nlet credentialsFile: CliConfig | null | undefined;\nfunction readCredentialsFile(): CliConfig | null {\n if (credentialsFile !== undefined) return credentialsFile;\n const path = process.env.PAPERMARK_CREDENTIALS_FILE;\n if (!path) return (credentialsFile = null);\n try {\n const parsed = JSON.parse(readFileSync(path, \"utf8\"));\n if (parsed && typeof parsed === \"object\") {\n return (credentialsFile = {\n token: typeof parsed.token === \"string\" ? parsed.token : undefined,\n apiUrl:\n typeof parsed.apiUrl === \"string\"\n ? parsed.apiUrl\n : typeof parsed.api_url === \"string\"\n ? parsed.api_url\n : undefined,\n });\n }\n } catch (err) {\n process.stderr.write(\n `warning: could not read PAPERMARK_CREDENTIALS_FILE (${path}): ${\n err instanceof Error ? err.message : String(err)\n }\\n`,\n );\n }\n return (credentialsFile = null);\n}\n\n/** Empty-string env values (e.g. `PAPERMARK_TOKEN=`) are treated as unset. */\nfunction envOr(name: string): string | undefined {\n const v = process.env[name];\n return v && v.length > 0 ? v : undefined;\n}\n\n/**\n * Token resolution precedence (highest first):\n * 1. PAPERMARK_TOKEN env var\n * 2. PAPERMARK_CREDENTIALS_FILE's token field\n * 3. stored config (~/.config/papermark/config.json or equivalent)\n */\nexport function getToken(): string | undefined {\n return (\n envOr(\"PAPERMARK_TOKEN\") ??\n readCredentialsFile()?.token ??\n store.get(\"token\")\n );\n}\n\nexport type TokenSource = \"env\" | \"credentials-file\" | \"config\" | \"none\";\nexport function getTokenSource(): TokenSource {\n if (envOr(\"PAPERMARK_TOKEN\")) return \"env\";\n if (readCredentialsFile()?.token) return \"credentials-file\";\n if (store.get(\"token\")) return \"config\";\n return \"none\";\n}\n\nexport function setToken(token: string): void {\n store.set(\"token\", token);\n}\n\nexport function clearToken(): void {\n store.delete(\"token\");\n}\n\nexport function getApiUrl(): string {\n return (\n envOr(\"PAPERMARK_API_URL\") ??\n readCredentialsFile()?.apiUrl ??\n store.get(\"apiUrl\") ??\n \"https://api.papermark.com\"\n );\n}\n\nexport function setApiUrl(url: string): void {\n store.set(\"apiUrl\", url);\n}\n\nexport function getAll(): CliConfig {\n return { token: store.get(\"token\"), apiUrl: store.get(\"apiUrl\") };\n}\n\nexport function configPath(): string {\n return store.path;\n}\n\nexport function deleteKey(key: keyof CliConfig): void {\n store.delete(key);\n}\n","// Tiny opt-in tracer, gated on PAPERMARK_DEBUG=1. Zero cost when unset\n// — no console writes, no closure allocations per call site. Intended\n// for bug reports (\"run with PAPERMARK_DEBUG=1 and paste the output\").\n\nconst enabled =\n process.env.PAPERMARK_DEBUG === \"1\" ||\n process.env.PAPERMARK_DEBUG === \"true\";\n\nexport function debug(category: string, ...parts: unknown[]): void {\n if (!enabled) return;\n const line = parts\n .map((p) => (typeof p === \"string\" ? p : JSON.stringify(p)))\n .join(\" \");\n process.stderr.write(`[papermark:${category}] ${line}\\n`);\n}\n\nexport function debugEnabled(): boolean {\n return enabled;\n}\n","// Runtime flags that affect output and side effects. Populated once in\n// index.ts from the root Commander program + env vars, then consumed\n// from anywhere in the CLI (client, commands, spinners).\n//\n// Kept as module-level state (not context-passed) because threading\n// flags through every function signature is noise for a <1k-line CLI.\n\nimport type { Writable } from \"node:stream\";\n\nexport interface Runtime {\n /** User passed --json, or stdout is not a TTY (scripted). */\n json: boolean;\n /** User passed --dry-run — CLI prints intended request and exits. */\n dryRun: boolean;\n /** Controls whether ANSI color/spinners are emitted. */\n color: boolean;\n}\n\nlet current: Runtime = {\n json: !process.stdout.isTTY,\n dryRun: false,\n color: process.stdout.isTTY && !process.env.NO_COLOR,\n};\n\nexport function setRuntime(patch: Partial<Runtime>): void {\n current = { ...current, ...patch };\n}\n\nexport function getRuntime(): Runtime {\n return current;\n}\n\n/** Helpers for deciding where to send different kinds of output. */\nexport function stdout(): Writable {\n return process.stdout;\n}\nexport function stderr(): Writable {\n return process.stderr;\n}\n","import { getApiUrl, getToken } from \"./config.js\";\nimport { debug } from \"./debug.js\";\nimport { getRuntime } from \"./runtime.js\";\n\nexport interface ApiErrorBody {\n error: {\n code: string;\n message: string;\n doc_url?: string;\n details?: unknown;\n };\n}\n\nexport class ApiError extends Error {\n code: string;\n status: number;\n docUrl?: string;\n details?: unknown;\n\n constructor(status: number, body: ApiErrorBody[\"error\"] | string) {\n const message = typeof body === \"string\" ? body : body.message;\n super(message);\n this.status = status;\n if (typeof body === \"string\") {\n this.code = \"unknown\";\n } else {\n this.code = body.code;\n this.docUrl = body.doc_url;\n this.details = body.details;\n }\n }\n}\n\nexport class AuthRequiredError extends Error {\n constructor() {\n super(\"No API token found. Run `papermark login` first.\");\n this.name = \"AuthRequiredError\";\n }\n}\n\nexport class NetworkError extends Error {\n url: string;\n cause: unknown;\n constructor(url: string, cause: unknown) {\n const reason = extractNetworkReason(cause);\n super(`Network request to ${url} failed: ${reason}`);\n this.name = \"NetworkError\";\n this.url = url;\n this.cause = cause;\n }\n}\n\nfunction extractNetworkReason(err: unknown): string {\n if (err && typeof err === \"object\" && \"cause\" in err) {\n const c = (err as { cause: unknown }).cause;\n if (c && typeof c === \"object\") {\n const code = (c as { code?: string }).code;\n const msg = (c as { message?: string }).message;\n if (code || msg) return `${code ?? \"\"}${code && msg ? \" — \" : \"\"}${msg ?? \"\"}`.trim();\n }\n }\n if (err instanceof Error) return err.message;\n return String(err);\n}\n\ninterface RequestOptions {\n method?: string;\n body?: unknown;\n query?: Record<string, string | number | undefined>;\n /** If true, skip the \"Authorization\" header (used for presigned URL uploads). */\n anonymous?: boolean;\n headers?: Record<string, string>;\n}\n\nfunction buildUrl(path: string, query?: RequestOptions[\"query\"]): string {\n const base = getApiUrl().replace(/\\/$/, \"\");\n // Base URL is either https://api.papermark.com (subdomain) or\n // http://localhost:3000/api (when pointed at a local dev server).\n // Path is like \"/v1/documents\". Concatenate and normalize doubled /api.\n let fullPath = path.startsWith(\"/\") ? path : `/${path}`;\n if (base.endsWith(\"/api\") && fullPath.startsWith(\"/api/\")) {\n fullPath = fullPath.slice(4);\n }\n const url = new URL(base + fullPath);\n if (query) {\n for (const [k, v] of Object.entries(query)) {\n if (v !== undefined && v !== null && v !== \"\") {\n url.searchParams.set(k, String(v));\n }\n }\n }\n return url.toString();\n}\n\nexport async function request<T = unknown>(\n path: string,\n opts: RequestOptions = {},\n): Promise<T> {\n const headers: Record<string, string> = {\n Accept: \"application/json\",\n ...(opts.headers ?? {}),\n };\n if (!opts.anonymous) {\n const token = getToken();\n if (token) {\n headers.Authorization = `Bearer ${token}`;\n } else if (!getRuntime().dryRun) {\n // Dry-run is explicitly for inspecting what WOULD be sent, so we\n // proceed with a placeholder Authorization below. Every other code\n // path needs a real token.\n throw new AuthRequiredError();\n } else {\n headers.Authorization = \"Bearer <no-token>\";\n }\n }\n let body: BodyInit | undefined;\n if (opts.body !== undefined) {\n if (opts.body instanceof Uint8Array || opts.body instanceof ArrayBuffer) {\n body = opts.body as BodyInit;\n } else {\n body = JSON.stringify(opts.body);\n headers[\"Content-Type\"] = \"application/json\";\n }\n }\n\n const url = buildUrl(path, opts.query);\n const method = opts.method ?? (opts.body ? \"POST\" : \"GET\");\n\n if (getRuntime().dryRun) {\n // Print the request we would make and short-circuit. Token is\n // redacted so users can safely paste the output into bug reports.\n const redactedHeaders = { ...headers };\n if (redactedHeaders.Authorization) {\n redactedHeaders.Authorization = \"Bearer ***redacted***\";\n }\n process.stderr.write(\n `[dry-run] ${method} ${url}\\n` +\n Object.entries(redactedHeaders)\n .map(([k, v]) => `[dry-run] ${k}: ${v}`)\n .join(\"\\n\") +\n (body ? `\\n[dry-run] body: ${truncate(String(body), 500)}` : \"\") +\n \"\\n\",\n );\n return undefined as T;\n }\n\n debug(\"http\", method, url, body ? \"(body)\" : \"\");\n const started = Date.now();\n let res: Response;\n try {\n res = await fetch(url, { method, headers, body });\n } catch (err) {\n debug(\"http\", \"network error after\", `${Date.now() - started}ms`, String(err));\n throw new NetworkError(url, err);\n }\n debug(\"http\", method, url, `→ ${res.status}`, `(${Date.now() - started}ms)`);\n\n if (res.status === 204) return undefined as T;\n\n const text = await res.text();\n const parsed = text ? safeParseJson(text) : null;\n\n if (!res.ok) {\n if (parsed && typeof parsed === \"object\" && \"error\" in parsed) {\n throw new ApiError(res.status, (parsed as ApiErrorBody).error);\n }\n // Non-JSON response (e.g. a Next.js HTML error page). Keep the message\n // short — users don't want to read HTML.\n const looksLikeHtml = text.trimStart().toLowerCase().startsWith(\"<\");\n const msg = looksLikeHtml\n ? `HTTP ${res.status} (server returned HTML, not JSON — is the dev server healthy?)`\n : text || `HTTP ${res.status}`;\n throw new ApiError(res.status, msg);\n }\n\n // Treat a non-JSON 2xx body as an error rather than silently returning\n // undefined — it's almost always a sign of a misconfigured proxy or a\n // routing layer that handed us an HTML page instead of the API.\n if (parsed === null && text.trim() !== \"\") {\n const looksLikeHtml = text.trimStart().toLowerCase().startsWith(\"<\");\n const msg = looksLikeHtml\n ? `HTTP ${res.status} (server returned HTML on a 2xx — is the API URL pointing at the right host?)`\n : `HTTP ${res.status} (response was not JSON: ${truncate(text, 200)})`;\n throw new ApiError(res.status, msg);\n }\n\n return (parsed as T) ?? (undefined as T);\n}\n\nfunction safeParseJson(s: string): unknown {\n try {\n return JSON.parse(s);\n } catch {\n return null;\n }\n}\n\nfunction truncate(s: string, n: number): string {\n return s.length > n ? s.slice(0, n - 1) + \"…\" : s;\n}\n\n// -------- Typed helpers for each resource --------\n//\n// All response field names mirror the v1 public API exactly: snake_case,\n// nullable where the API documents it. Keep this file in sync with\n// papermark/lib/api/v1/schemas/*.ts.\n\nexport interface PublicDocument {\n id: string;\n object: \"document\";\n name: string;\n type: string | null;\n content_type: string | null;\n // Target URL for `link`/`notion` documents; null for file-based documents.\n url: string | null;\n num_pages: number | null;\n folder_id: string | null;\n created: string;\n updated_at: string;\n}\n\nexport interface DocumentList {\n data: PublicDocument[];\n next_cursor: string | null;\n}\n\nexport interface UploadUrlResponse {\n upload_url: string;\n upload_id: string;\n required_headers: Record<string, string>;\n expires_at: string;\n}\n\nexport interface PublicDocumentVersion {\n id: string;\n object: \"document_version\";\n version_number: number;\n is_primary: boolean;\n type: string | null;\n content_type: string | null;\n num_pages: number | null;\n file_size: number | null;\n created: string;\n updated_at: string;\n}\n\nexport interface DocumentVersionList {\n data: PublicDocumentVersion[];\n}\n\nexport type FolderIcon =\n | \"folder\"\n | \"folder-open\"\n | \"briefcase\"\n | \"archive\"\n | \"box\"\n | \"file\"\n | \"book\"\n | \"bookmark\"\n | \"star\"\n | \"heart\"\n | \"lock\"\n | \"shield\"\n | \"users\"\n | \"settings\"\n | \"tag\"\n | \"layers\"\n | \"globe\"\n | \"home\"\n | \"mail\"\n | \"image\"\n | \"video\"\n | \"music\"\n | \"palette\"\n | \"pen-tool\"\n | \"lightbulb\"\n | \"zap\"\n | \"wrench\"\n | \"sparkles\"\n | \"cloud\"\n | \"flag\"\n | \"award\"\n | \"flame\"\n | \"bell\"\n | \"sun\"\n | \"hash\";\n\nexport type FolderColor =\n | \"gray\"\n | \"red\"\n | \"orange\"\n | \"yellow\"\n | \"green\"\n | \"blue\"\n | \"black\";\n\nexport interface PublicFolder {\n id: string;\n object: \"folder\";\n name: string;\n parent_id: string | null;\n path: string;\n icon: string | null;\n color: string | null;\n document_count: number;\n child_folder_count: number;\n created: string;\n updated_at: string;\n}\n\nexport interface FolderList {\n data: PublicFolder[];\n next_cursor: string | null;\n}\n\nexport type WatermarkPosition =\n | \"top-left\"\n | \"top-center\"\n | \"top-right\"\n | \"middle-left\"\n | \"middle-center\"\n | \"middle-right\"\n | \"bottom-left\"\n | \"bottom-center\"\n | \"bottom-right\";\n\nexport type WatermarkRotation = 0 | 30 | 45 | 90 | 180;\n\nexport interface WatermarkConfig {\n text: string;\n is_tiled: boolean;\n position: WatermarkPosition;\n rotation: WatermarkRotation;\n color: string;\n font_size: number;\n opacity: number;\n}\n\nexport type LinkAudienceType = \"general\" | \"group\" | \"team\";\n\nexport interface PublicLink {\n id: string;\n object: \"link\";\n name: string | null;\n target_type: \"document\" | \"dataroom\";\n audience_type: LinkAudienceType;\n group_id: string | null;\n document_id: string | null;\n dataroom_id: string | null;\n url: string;\n domain: string | null;\n slug: string | null;\n expires_at: string | null;\n is_password_protected: boolean;\n email_protected: boolean;\n email_authenticated: boolean;\n allow_download: boolean;\n allow_list: string[];\n deny_list: string[];\n enable_watermark: boolean;\n watermark_config: WatermarkConfig | null;\n enable_feedback: boolean;\n enable_screenshot_protection: boolean;\n enable_confidential_view: boolean;\n created: string;\n updated_at: string;\n}\n\nexport interface LinkList {\n data: PublicLink[];\n next_cursor: string | null;\n}\n\nexport interface PublicView {\n id: string;\n object: \"view\";\n link_id: string | null;\n document_id: string | null;\n dataroom_id: string | null;\n viewer_email: string | null;\n view_type: string | null;\n viewed_at: string;\n downloaded_at: string | null;\n download_type: string | null;\n}\n\nexport interface ViewList {\n data: PublicView[];\n next_cursor: string | null;\n}\n\nexport interface PublicDataroom {\n id: string;\n object: \"dataroom\";\n pid: string;\n name: string;\n internal_name: string | null;\n description: string | null;\n document_count: number;\n folder_count: number;\n conversations_enabled: boolean;\n agents_enabled: boolean;\n allow_bulk_download: boolean;\n is_frozen: boolean;\n created: string;\n updated_at: string;\n}\n\nexport interface DataroomList {\n data: PublicDataroom[];\n next_cursor: string | null;\n}\n\nexport interface PublicDataroomItem {\n id: string;\n object: \"dataroom_document\";\n document_id: string;\n document_name: string;\n content_type: string | null;\n num_pages: number | null;\n folder_id: string | null;\n folder_path: string | null;\n order_index: number | null;\n created: string;\n}\n\nexport interface DataroomItemList {\n data: PublicDataroomItem[];\n next_cursor: string | null;\n}\n\nexport interface PublicDataroomFolder {\n id: string;\n object: \"dataroom_folder\";\n name: string;\n parent_id: string | null;\n path: string;\n icon: string | null;\n color: string | null;\n document_count: number;\n child_folder_count: number;\n order_index: number | null;\n created: string;\n updated_at: string;\n}\n\nexport interface DataroomFolderList {\n data: PublicDataroomFolder[];\n next_cursor: string | null;\n}\n\nexport interface PublicVisitor {\n id: string;\n object: \"visitor\";\n email: string;\n verified: boolean;\n dataroom_id: string | null;\n invited_at: string | null;\n total_views: number;\n last_viewed_at: string | null;\n created: string;\n updated_at: string;\n}\n\nexport interface VisitorList {\n data: PublicVisitor[];\n next_cursor: string | null;\n}\n\nexport interface PublicVisitorView {\n id: string;\n object: \"visitor_view\";\n link_id: string;\n document_id: string | null;\n dataroom_id: string | null;\n view_type: string;\n viewed_at: string;\n downloaded_at: string | null;\n is_archived: boolean;\n}\n\nexport interface VisitorViewList {\n data: PublicVisitorView[];\n next_cursor: string | null;\n}\n\nexport interface DocumentAnalytics {\n document_id: string;\n total_views: number;\n unique_viewers: number;\n total_duration_seconds: number;\n avg_page_duration_seconds: { page_number: number; avg_duration_seconds: number }[];\n since: string;\n until: string;\n}\n\nexport interface LinkAnalytics {\n link_id: string;\n total_views: number;\n total_duration_seconds: number;\n unique_viewers: number;\n since: string;\n until: string;\n}\n\nexport interface DataroomAnalytics {\n dataroom_id: string;\n total_views: number;\n unique_viewers: number;\n total_duration_seconds: number;\n since: string;\n until: string;\n}\n\nexport interface ViewAnalytics {\n view_id: string;\n document_id: string | null;\n viewer_email: string | null;\n viewed_at: string;\n page_durations: { page_number: number; duration_seconds: number }[];\n total_duration_seconds: number;\n location: { country: string | null; city: string | null } | null;\n client: { browser: string | null; os: string | null; device: string | null } | null;\n}\n\nexport interface UpdateDocumentBody {\n name?: string;\n folder_id?: string | null;\n}\n\nexport interface UpdateLinkBody {\n // `group` (dataroom links only) scopes the link to a dataroom group and\n // forces email protection; `general` clears the group scope.\n audience_type?: \"general\" | \"group\";\n group_id?: string | null;\n name?: string;\n expires_at?: string | null;\n password?: string | null;\n email_protected?: boolean;\n email_authenticated?: boolean;\n allow_download?: boolean;\n allow_list?: string[];\n deny_list?: string[];\n enable_watermark?: boolean;\n watermark_config?: WatermarkConfig | null;\n enable_screenshot_protection?: boolean;\n enable_confidential_view?: boolean;\n}\n\nexport interface PublicDataroomGroup {\n id: string;\n object: \"dataroom_group\";\n name: string;\n allow_all: boolean;\n domains: string[];\n member_count: number;\n link_count: number;\n dataroom_id: string;\n created: string;\n updated_at: string;\n}\n\nexport interface DataroomGroupList {\n data: PublicDataroomGroup[];\n next_cursor: string | null;\n}\n\nexport interface PublicDataroomGroupMember {\n // Membership id — use it to remove the member.\n id: string;\n object: \"dataroom_group_member\";\n email: string;\n viewer_id: string;\n created: string;\n}\n\nexport interface DataroomGroupMemberList {\n data: PublicDataroomGroupMember[];\n next_cursor: string | null;\n}\n\nexport type PermissionItemType = \"dataroom_document\" | \"dataroom_folder\";\n\nexport interface PermissionEntry {\n item_id: string;\n item_type: PermissionItemType;\n can_view: boolean;\n can_download: boolean;\n}\n\nexport interface DataroomGroupPermission {\n object: \"dataroom_group_permission\";\n item_id: string;\n item_type: PermissionItemType;\n can_view: boolean;\n can_download: boolean;\n updated_at: string;\n}\n\nexport interface DataroomGroupPermissionList {\n data: DataroomGroupPermission[];\n next_cursor: string | null;\n}\n\nexport interface LinkPermission {\n object: \"link_permission\";\n item_id: string;\n item_type: PermissionItemType;\n can_view: boolean;\n can_download: boolean;\n can_download_original: boolean;\n updated_at: string;\n}\n\nexport interface LinkPermissionList {\n data: LinkPermission[];\n}\n\n// Uniform acknowledgment returned by every v1 DELETE endpoint.\nexport interface DeletedObject {\n id: string;\n object:\n | \"document\"\n | \"folder\"\n | \"link\"\n | \"dataroom\"\n | \"dataroom_folder\"\n | \"dataroom_document\"\n | \"dataroom_group\"\n | \"dataroom_group_member\";\n deleted: true;\n}\n\nexport const api = {\n // Documents\n listDocuments: (query?: { limit?: number; cursor?: string; query?: string }) =>\n request<DocumentList>(\"/v1/documents\", { query }),\n getDocument: (id: string) => request<PublicDocument>(`/v1/documents/${id}`),\n searchDocuments: (q: string, limit?: number) =>\n request<DocumentList>(\"/v1/documents/search\", { query: { q, limit } }),\n updateDocument: (id: string, body: UpdateDocumentBody) =>\n request<PublicDocument>(`/v1/documents/${id}`, { method: \"PATCH\", body }),\n deleteDocument: (id: string) =>\n request<DeletedObject>(`/v1/documents/${id}`, { method: \"DELETE\" }),\n uploadUrl: (body: { file_name: string; content_type: string; content_length?: number }) =>\n request<UploadUrlResponse>(\"/v1/documents/upload-url\", { method: \"POST\", body }),\n createDocument: (body: {\n name: string;\n // Set to create a non-file document from `external_url`: `link` (any\n // external page) or `notion` (a public Notion page). Omit for file-based\n // documents created via `upload_id` or `source_url`.\n type?: \"link\" | \"notion\";\n upload_id?: string;\n source_url?: string;\n external_url?: string;\n folder_id?: string;\n create_link?: boolean;\n }) => request<PublicDocument>(\"/v1/documents\", { method: \"POST\", body }),\n listDocumentVersions: (id: string) =>\n request<DocumentVersionList>(`/v1/documents/${id}/versions`),\n addDocumentVersion: (\n id: string,\n // `external_url` repoints a link/notion document at a new URL (preserved\n // type); upload_id/source_url replace a file document's bytes.\n body: { upload_id?: string; source_url?: string; external_url?: string },\n ) =>\n request<PublicDocumentVersion>(`/v1/documents/${id}/versions`, {\n method: \"POST\",\n body,\n }),\n getDocumentVersion: (id: string, vid: string) =>\n request<PublicDocumentVersion>(`/v1/documents/${id}/versions/${vid}`),\n promoteDocumentVersion: (id: string, vid: string) =>\n request<PublicDocumentVersion>(`/v1/documents/${id}/versions/${vid}`, {\n method: \"PATCH\",\n body: { is_primary: true },\n }),\n\n // Folders\n listFolders: (query?: { limit?: number; cursor?: string; parent_id?: string }) =>\n request<FolderList>(\"/v1/folders\", { query }),\n createFolder: (body: {\n name: string;\n parent_id?: string | null;\n icon?: FolderIcon;\n color?: FolderColor;\n }) => request<PublicFolder>(\"/v1/folders\", { method: \"POST\", body }),\n getFolder: (id: string) => request<PublicFolder>(`/v1/folders/${id}`),\n updateFolder: (\n id: string,\n body: { name?: string; icon?: FolderIcon | null; color?: FolderColor | null },\n ) => request<PublicFolder>(`/v1/folders/${id}`, { method: \"PATCH\", body }),\n deleteFolder: (id: string, opts?: { cascade?: boolean }) =>\n request<DeletedObject>(`/v1/folders/${id}`, {\n method: \"DELETE\",\n query: opts?.cascade ? { cascade: \"true\" } : undefined,\n }),\n moveFolder: (id: string, body: { parent_id: string | null }) =>\n request<PublicFolder>(`/v1/folders/${id}/move`, { method: \"POST\", body }),\n\n // Links\n listLinks: (query?: { limit?: number; cursor?: string; document_id?: string; dataroom_id?: string; group_id?: string }) =>\n request<LinkList>(\"/v1/links\", { query }),\n getLink: (id: string) => request<PublicLink>(`/v1/links/${id}`),\n createLink: (body: {\n document_id?: string;\n dataroom_id?: string;\n // `group` (dataroom links only) requires group_id and forces email\n // protection.\n audience_type?: \"general\" | \"group\";\n group_id?: string;\n name?: string;\n expires_at?: string;\n password?: string;\n email_protected?: boolean;\n allow_download?: boolean;\n enable_confidential_view?: boolean;\n enable_watermark?: boolean;\n watermark_config?: WatermarkConfig;\n }) => request<PublicLink>(\"/v1/links\", { method: \"POST\", body }),\n updateLink: (id: string, body: UpdateLinkBody) =>\n request<PublicLink>(`/v1/links/${id}`, { method: \"PATCH\", body }),\n deleteLink: (id: string) =>\n request<DeletedObject>(`/v1/links/${id}`, { method: \"DELETE\" }),\n getLinkPermissions: (id: string) =>\n request<LinkPermissionList>(`/v1/links/${id}/permissions`),\n // Full-replace semantics: the payload is the complete desired state;\n // items not listed lose their override.\n setLinkPermissions: (id: string, body: { permissions: PermissionEntry[] }) =>\n request<LinkPermissionList>(`/v1/links/${id}/permissions`, {\n method: \"PUT\",\n body,\n }),\n\n // Views\n listViews: (linkId: string, query?: { limit?: number; cursor?: string }) =>\n request<ViewList>(`/v1/links/${linkId}/views`, { query }),\n\n // Datarooms\n listDatarooms: (query?: { limit?: number; cursor?: string; query?: string }) =>\n request<DataroomList>(\"/v1/datarooms\", { query }),\n getDataroom: (id: string) =>\n request<PublicDataroom>(`/v1/datarooms/${id}`),\n createDataroom: (body: {\n name: string;\n internal_name?: string;\n description?: string;\n }) => request<PublicDataroom>(\"/v1/datarooms\", { method: \"POST\", body }),\n updateDataroom: (\n id: string,\n body: {\n name?: string;\n internal_name?: string | null;\n description?: string | null;\n allow_bulk_download?: boolean;\n },\n ) =>\n request<PublicDataroom>(`/v1/datarooms/${id}`, { method: \"PATCH\", body }),\n deleteDataroom: (id: string) =>\n request<DeletedObject>(`/v1/datarooms/${id}`, { method: \"DELETE\" }),\n listDataroomDocuments: (\n id: string,\n query?: { limit?: number; cursor?: string; folder_id?: string },\n ) =>\n request<DataroomItemList>(`/v1/datarooms/${id}/documents`, { query }),\n attachDataroomDocument: (\n id: string,\n body: { document_id: string; folder_id?: string },\n ) =>\n request<PublicDataroomItem>(`/v1/datarooms/${id}/documents`, {\n method: \"POST\",\n body,\n }),\n detachDataroomDocument: (id: string, ddId: string) =>\n request<DeletedObject>(`/v1/datarooms/${id}/documents/${ddId}`, {\n method: \"DELETE\",\n }),\n moveDataroomDocument: (\n id: string,\n ddId: string,\n body: { folder_id: string | null },\n ) =>\n request<PublicDataroomItem>(`/v1/datarooms/${id}/documents/${ddId}/move`, {\n method: \"POST\",\n body,\n }),\n\n // Dataroom folders\n listDataroomFolders: (\n id: string,\n query?: { limit?: number; cursor?: string; parent_id?: string },\n ) =>\n request<DataroomFolderList>(`/v1/datarooms/${id}/folders`, { query }),\n createDataroomFolder: (\n id: string,\n body: {\n name: string;\n parent_id?: string | null;\n icon?: FolderIcon;\n color?: FolderColor;\n },\n ) =>\n request<PublicDataroomFolder>(`/v1/datarooms/${id}/folders`, {\n method: \"POST\",\n body,\n }),\n getDataroomFolder: (id: string, fid: string) =>\n request<PublicDataroomFolder>(`/v1/datarooms/${id}/folders/${fid}`),\n updateDataroomFolder: (\n id: string,\n fid: string,\n body: { name?: string; icon?: FolderIcon | null; color?: FolderColor | null },\n ) =>\n request<PublicDataroomFolder>(`/v1/datarooms/${id}/folders/${fid}`, {\n method: \"PATCH\",\n body,\n }),\n deleteDataroomFolder: (id: string, fid: string, opts?: { cascade?: boolean }) =>\n request<DeletedObject>(`/v1/datarooms/${id}/folders/${fid}`, {\n method: \"DELETE\",\n query: opts?.cascade ? { cascade: \"true\" } : undefined,\n }),\n moveDataroomFolder: (\n id: string,\n fid: string,\n body: { parent_id: string | null },\n ) =>\n request<PublicDataroomFolder>(`/v1/datarooms/${id}/folders/${fid}/move`, {\n method: \"POST\",\n body,\n }),\n\n // Dataroom groups\n listDataroomGroups: (\n id: string,\n query?: { limit?: number; cursor?: string },\n ) =>\n request<DataroomGroupList>(`/v1/datarooms/${id}/groups`, { query }),\n createDataroomGroup: (\n id: string,\n body: { name: string; allow_all?: boolean; domains?: string[] },\n ) =>\n request<PublicDataroomGroup>(`/v1/datarooms/${id}/groups`, {\n method: \"POST\",\n body,\n }),\n getDataroomGroup: (id: string, gid: string) =>\n request<PublicDataroomGroup>(`/v1/datarooms/${id}/groups/${gid}`),\n updateDataroomGroup: (\n id: string,\n gid: string,\n body: { name?: string; allow_all?: boolean; domains?: string[] },\n ) =>\n request<PublicDataroomGroup>(`/v1/datarooms/${id}/groups/${gid}`, {\n method: \"PATCH\",\n body,\n }),\n // Also deletes every share link pointing at the group (matching the\n // dashboard).\n deleteDataroomGroup: (id: string, gid: string) =>\n request<DeletedObject>(`/v1/datarooms/${id}/groups/${gid}`, {\n method: \"DELETE\",\n }),\n listDataroomGroupMembers: (\n id: string,\n gid: string,\n query?: { limit?: number; cursor?: string },\n ) =>\n request<DataroomGroupMemberList>(\n `/v1/datarooms/${id}/groups/${gid}/members`,\n { query },\n ),\n addDataroomGroupMembers: (id: string, gid: string, body: { emails: string[] }) =>\n request<DataroomGroupMemberList>(\n `/v1/datarooms/${id}/groups/${gid}/members`,\n { method: \"POST\", body },\n ),\n removeDataroomGroupMember: (id: string, gid: string, mid: string) =>\n request<DeletedObject>(\n `/v1/datarooms/${id}/groups/${gid}/members/${mid}`,\n { method: \"DELETE\" },\n ),\n listDataroomGroupPermissions: (\n id: string,\n gid: string,\n query?: { limit?: number; cursor?: string },\n ) =>\n request<DataroomGroupPermissionList>(\n `/v1/datarooms/${id}/groups/${gid}/permissions`,\n { query },\n ),\n // Upsert-delta semantics: entries sent are upserted, entries omitted keep\n // their current state; ancestor folders of visible items are auto-shown.\n setDataroomGroupPermissions: (\n id: string,\n gid: string,\n body: { permissions: PermissionEntry[] },\n ) =>\n request<{ data: DataroomGroupPermission[] }>(\n `/v1/datarooms/${id}/groups/${gid}/permissions`,\n { method: \"PUT\", body },\n ),\n\n // Visitors\n listVisitors: (query?: {\n limit?: number;\n cursor?: string;\n email?: string;\n dataroom_id?: string;\n }) => request<VisitorList>(\"/v1/visitors\", { query }),\n getVisitor: (id: string) => request<PublicVisitor>(`/v1/visitors/${id}`),\n listVisitorViews: (id: string, query?: { limit?: number; cursor?: string }) =>\n request<VisitorViewList>(`/v1/visitors/${id}/views`, { query }),\n\n // Analytics\n documentAnalytics: (\n id: string,\n query?: { since?: number; until?: number },\n ) =>\n request<DocumentAnalytics>(`/v1/analytics/documents/${id}`, { query }),\n linkAnalytics: (id: string, query?: { since?: number; until?: number }) =>\n request<LinkAnalytics>(`/v1/analytics/links/${id}`, { query }),\n dataroomAnalytics: (\n id: string,\n query?: { since?: number; until?: number },\n ) =>\n request<DataroomAnalytics>(`/v1/analytics/datarooms/${id}`, { query }),\n viewAnalytics: (id: string) =>\n request<ViewAnalytics>(`/v1/analytics/views/${id}`),\n};\n","import chalk from \"chalk\";\n\nimport { ApiError, AuthRequiredError, NetworkError } from \"./client.js\";\nimport { ExitCode } from \"./exit.js\";\nimport { getRuntime } from \"./runtime.js\";\n\n/**\n * CLI-side validation failure. Produced by command handlers when the user's\n * input fails the contract checks before we ever talk to the API. Maps to\n * exit code 3 + `code: \"VALIDATION\"` in the JSON envelope.\n */\nexport class ValidationError extends Error {\n details?: unknown;\n constructor(message: string, details?: unknown) {\n super(message);\n this.name = \"ValidationError\";\n this.details = details;\n }\n}\n\nexport interface FormattedError {\n /** Human-readable message for humans (with color + hint lines). */\n human: string;\n /** Machine-parseable shape for --json / !isTTY. */\n json: {\n error: {\n code: string;\n message: string;\n status?: number;\n /**\n * Whether an agent should retry this error with backoff. True for\n * transient failures (network, rate limit, 5xx); false for auth,\n * validation, or 4xx-not-429. Canonical mapping lives in\n * docs/CONTRACT_V1.md.\n */\n retryable: boolean;\n hint?: string;\n doc_url?: string;\n details?: unknown;\n };\n };\n exitCode: ExitCode;\n}\n\nexport function formatError(err: unknown): FormattedError {\n if (err instanceof AuthRequiredError) {\n const message = sanitizeForTerminal(err.message);\n return {\n human: chalk.red(\"✗ \") + message,\n json: {\n error: {\n code: \"NO_TOKEN\",\n message: err.message,\n retryable: false,\n hint: \"Run `papermark login` to authenticate.\",\n },\n },\n exitCode: ExitCode.AuthError,\n };\n }\n if (err instanceof NetworkError) {\n const message = sanitizeForTerminal(err.message);\n return {\n human:\n chalk.red(\"✗ \") +\n message +\n chalk.dim(\n \"\\n Hint: check `papermark config show` and your internet connection.\",\n ),\n json: {\n error: {\n code: \"NETWORK_ERROR\",\n message: err.message,\n retryable: true,\n hint: \"check `papermark config show` and your internet connection\",\n },\n },\n exitCode: ExitCode.NetworkError,\n };\n }\n if (err instanceof ValidationError) {\n const message = sanitizeForTerminal(err.message);\n return {\n human: chalk.red(\"✗ \") + message,\n json: {\n error: {\n code: \"VALIDATION\",\n message: err.message,\n retryable: false,\n ...(err.details ? { details: err.details } : {}),\n },\n },\n exitCode: ExitCode.ValidationError,\n };\n }\n if (err instanceof ApiError) {\n const hint = hintForApiError(err);\n const safeMessage = sanitizeForTerminal(err.message);\n const safeDocUrl = err.docUrl ? sanitizeForTerminal(err.docUrl) : \"\";\n const safeDetails =\n err.details && typeof err.details === \"object\"\n ? sanitizeForTerminal(JSON.stringify(err.details))\n : \"\";\n const docs = safeDocUrl ? chalk.dim(`\\n See: ${safeDocUrl}`) : \"\";\n const hintLine = hint ? chalk.dim(`\\n Hint: ${hint}`) : \"\";\n const details = safeDetails ? chalk.dim(\"\\n \" + safeDetails) : \"\";\n return {\n human:\n chalk.red(`✗ [${err.status} ${err.code}] `) +\n safeMessage +\n hintLine +\n docs +\n details,\n json: {\n error: {\n code: err.code,\n message: err.message,\n status: err.status,\n retryable: isRetryableStatus(err.status),\n ...(hint ? { hint } : {}),\n ...(err.docUrl ? { doc_url: err.docUrl } : {}),\n ...(err.details ? { details: err.details } : {}),\n },\n },\n exitCode: exitCodeForApiError(err),\n };\n }\n const rawMessage = err instanceof Error ? err.message : String(err);\n return {\n human: chalk.red(\"✗ \") + sanitizeForTerminal(rawMessage),\n json: { error: { code: \"INTERNAL\", message: rawMessage, retryable: false } },\n exitCode: ExitCode.Internal,\n };\n}\n\n/**\n * Canonical retryable mapping per docs/CONTRACT_V1.md:\n * - 429 (rate-limit) and 5xx are retryable with backoff\n * - 401/403/404/422 are not\n * - anything else defaults to false so agents don't retry-storm novel codes\n */\nfunction isRetryableStatus(status: number): boolean {\n if (status === 429) return true;\n if (status >= 500 && status < 600) return true;\n return false;\n}\n\nfunction hintForApiError(err: ApiError): string | undefined {\n if (err.status === 401) return \"Run `papermark login` to re-authenticate.\";\n if (err.status === 403) {\n return \"Token is missing a required scope. Re-login to refresh grants.\";\n }\n if (err.status === 429) {\n return \"Rate limit exceeded. Check X-RateLimit-* headers and back off.\";\n }\n if (err.status === 422) return \"Check the input shape — details below.\";\n return undefined;\n}\n\nfunction exitCodeForApiError(err: ApiError): ExitCode {\n if (err.status === 401) return ExitCode.AuthError;\n if (err.status === 403) return ExitCode.AuthError;\n if (err.status === 422) return ExitCode.ValidationError;\n return ExitCode.ApiError;\n}\n\nexport function die(err: unknown): never {\n const fe = formatError(err);\n if (getRuntime().json) {\n process.stderr.write(\n JSON.stringify({ ok: false, error: fe.json.error }) + \"\\n\",\n );\n } else {\n process.stderr.write(fe.human + \"\\n\");\n }\n process.exit(fe.exitCode);\n}\n\n/**\n * Print success-shaped output, respecting --json / !isTTY. JSON output is\n * wrapped in the CONTRACT_V1 envelope `{ ok: true, data, meta? }`. List-\n * shaped payloads (`{ data: [...], next_cursor }` returned by every paginated\n * v1 endpoint) get their cursor lifted into `meta` automatically.\n */\nexport function emit(payload: unknown, human: () => string): void {\n const rt = getRuntime();\n // --dry-run short-circuits before a real response exists; the client\n // already wrote the request trace to stderr, and there's nothing for\n // the command to render.\n if (rt.dryRun) return;\n if (rt.json) {\n process.stdout.write(JSON.stringify(wrapSuccess(payload), null, 2) + \"\\n\");\n } else {\n process.stdout.write(human() + \"\\n\");\n }\n}\n\nfunction wrapSuccess(payload: unknown):\n | { ok: true; data: unknown }\n | { ok: true; data: unknown; meta: { next_cursor: string | null } } {\n if (\n payload !== null &&\n typeof payload === \"object\" &&\n \"data\" in payload &&\n \"next_cursor\" in payload &&\n Array.isArray((payload as { data: unknown }).data)\n ) {\n const p = payload as { data: unknown[]; next_cursor: string | null };\n return { ok: true, data: p.data, meta: { next_cursor: p.next_cursor } };\n }\n return { ok: true, data: payload };\n}\n\n// Minimal pretty table — enough for short lists, no external dep.\nexport function table(\n rows: Array<Record<string, string>>,\n columns: string[],\n): string {\n if (rows.length === 0) return chalk.dim(\"(no rows)\");\n const widths = columns.map((c) =>\n Math.max(c.length, ...rows.map((r) => (r[c] ?? \"\").length)),\n );\n const pad = (s: string, n: number) => s + \" \".repeat(Math.max(0, n - s.length));\n const header = columns.map((c, i) => chalk.bold(pad(c, widths[i]))).join(\" \");\n const sep = columns.map((_, i) => \"─\".repeat(widths[i])).join(\" \");\n const body = rows.map((r) =>\n columns.map((c, i) => pad(r[c] ?? \"\", widths[i])).join(\" \"),\n );\n return [header, chalk.dim(sep), ...body].join(\"\\n\");\n}\n\nexport function json(obj: unknown): string {\n return JSON.stringify(obj, null, 2);\n}\n\n/**\n * Strip escape sequences and invisible/bidi-override characters from a\n * string before printing. Documents and links in Papermark are named by\n * users — a malicious name could smuggle ANSI escapes (to fake a\n * different filename), bidirectional overrides (to reorder characters),\n * or zero-width joiners (to mask content) through the terminal. Apply\n * this before handing user-controlled strings to table() or a spinner.\n */\nexport function sanitizeForTerminal(input: string): string {\n return input\n // ANSI CSI sequences and OSC sequences (terminator: BEL or ESC \\).\n .replace(/\\x1B\\[[0-9;?]*[ -/]*[@-~]/g, \"\")\n .replace(/\\x1B\\][^\\x07\\x1B]*(\\x07|\\x1B\\\\)/g, \"\")\n // C0 controls minus TAB/LF — including CR which can rewrite the\n // current line, and DEL.\n .replace(/[\\x00-\\x08\\x0B-\\x1F\\x7F]/g, \"\")\n // Any leftover ESC byte (after the CSI/OSC patterns above stripped\n // the well-formed sequences) so an attacker can't smuggle a partial\n // escape that combines with subsequent legitimate text.\n .replace(/\\x1B/g, \"\")\n // C1 control range — 8-bit equivalents of ESC-prefixed sequences.\n // Some terminals still interpret these.\n .replace(/[\\x80-\\x9F]/g, \"\")\n // Bidi overrides + formatting marks\n .replace(/[\\u202A-\\u202E\\u2066-\\u2069\\u200E\\u200F]/g, \"\")\n // Zero-width joiner / non-joiner / word joiner\n .replace(/[\\u200B-\\u200D\\u2060]/g, \"\");\n}\n","// Structured exit codes so shell scripts can branch on failure type\n// without parsing stderr. Mirrors the pattern documented by Stripe CLI\n// and Google Workspace CLI.\n\nexport const ExitCode = {\n Ok: 0,\n /** Upstream API returned 4xx/5xx that isn't auth or validation. */\n ApiError: 1,\n /** No token, expired token, invalid token, missing scope. */\n AuthError: 2,\n /** Client-side input validation, or server-side 422. */\n ValidationError: 3,\n /** Network/DNS/connection refused, bad URL, etc. */\n NetworkError: 4,\n /** Unexpected — bug in the CLI itself. */\n Internal: 5,\n} as const;\n\nexport type ExitCode = (typeof ExitCode)[keyof typeof ExitCode];\n\nexport const EXIT_CODE_LEGEND: Readonly<Record<ExitCode, string>> = {\n [ExitCode.Ok]: \"success\",\n [ExitCode.ApiError]: \"API error (4xx/5xx)\",\n [ExitCode.AuthError]: \"authentication error\",\n [ExitCode.ValidationError]: \"validation error\",\n [ExitCode.NetworkError]: \"network error\",\n [ExitCode.Internal]: \"internal CLI error\",\n};\n","import chalk from \"chalk\";\nimport { Command } from \"commander\";\nimport ora from \"ora\";\n\nimport { AuthRequiredError, NetworkError, api } from \"../client.js\";\nimport {\n clearToken,\n configPath,\n getApiUrl,\n getToken,\n getTokenSource,\n setApiUrl,\n setToken,\n} from \"../config.js\";\nimport { die, emit, formatError, ValidationError } from \"../output.js\";\nimport { getRuntime } from \"../runtime.js\";\nimport {\n DEFAULT_SCOPES,\n deriveIssuer,\n discover,\n pollForToken,\n requestDeviceAuthorization,\n tryOpenBrowser,\n} from \"../oauth.js\";\n\nexport function registerAuthCommands(program: Command): void {\n program\n .command(\"login\")\n .description(\"Sign in to Papermark via the browser (OAuth device flow)\")\n .option(\n \"--token <token>\",\n \"paste an existing API token non-interactively (skip OAuth)\",\n )\n .option(\n \"--scopes <list>\",\n \"comma-separated scopes to request (defaults to read+write on documents/links plus analytics.read)\",\n )\n .option(\"--no-browser\", \"do not auto-open a browser; print the URL only\")\n .action(\n async (opts: {\n token?: string;\n scopes?: string;\n browser?: boolean;\n }) => {\n try {\n if (opts.token) {\n return await loginWithToken(opts.token);\n }\n const scopes = opts.scopes\n ? opts.scopes.split(/[\\s,]+/).filter(Boolean)\n : DEFAULT_SCOPES;\n return await loginWithDeviceFlow(scopes, {\n openBrowser: opts.browser !== false,\n });\n } catch (err) {\n die(err);\n }\n },\n );\n\n program\n .command(\"logout\")\n .description(\"Remove the stored API token\")\n .action(() => {\n clearToken();\n emit({ removed: true }, () => chalk.green(\"✓\") + \" Token removed.\");\n });\n\n program\n .command(\"whoami\")\n .description(\"Show the active token and API URL\")\n .action(() => {\n const token = getToken();\n if (!token) {\n die(new AuthRequiredError());\n }\n const partial = `${token.slice(0, 11)}...${token.slice(-4)}`;\n emit(\n {\n apiUrl: getApiUrl(),\n token: partial,\n source: getTokenSource(),\n config: configPath(),\n },\n () =>\n [\n `${chalk.bold(\"API URL:\")} ${getApiUrl()}`,\n `${chalk.bold(\"Token: \")} ${partial}`,\n `${chalk.bold(\"Source: \")} ${getTokenSource()}`,\n `${chalk.bold(\"Config: \")} ${configPath()}`,\n ].join(\"\\n\"),\n );\n });\n\n program\n .command(\"auth\")\n .description(\"Auth helpers (export, set, status)\")\n .addCommand(buildAuthExport())\n .addCommand(buildAuthSet());\n}\n\nfunction buildAuthExport(): Command {\n return new Command(\"export\")\n .description(\n \"Print current credentials as JSON. Useful for CI: redirect into a file and set PAPERMARK_CREDENTIALS_FILE.\",\n )\n .option(\n \"--unmasked\",\n \"include the full token (default: mask to first-6 + last-4 chars)\",\n )\n .action((opts: { unmasked?: boolean }) => {\n const token = getToken();\n if (!token) {\n die(new AuthRequiredError());\n }\n const payload = {\n token: opts.unmasked\n ? token\n : `${token.slice(0, 8)}***${token.slice(-4)}`,\n apiUrl: getApiUrl(),\n source: getTokenSource(),\n };\n process.stdout.write(JSON.stringify(payload, null, 2) + \"\\n\");\n if (!opts.unmasked) {\n process.stderr.write(\n chalk.dim(\n \"Token is masked. Pass --unmasked to include the full value (e.g. for writing to a secrets file).\\n\",\n ),\n );\n }\n });\n}\n\nfunction buildAuthSet(): Command {\n return new Command(\"set\")\n .description(\n \"Set credentials from stdin. Pipes a token (or JSON blob with {token, apiUrl}) into the CLI's config without leaving a tempfile on disk or exposing the value via `ps` / shell history. Ideal for CI runners pulling from a secret manager.\",\n )\n .option(\n \"--stdin\",\n \"read the token (or JSON blob with --json) from stdin until EOF\",\n )\n .option(\n \"--json\",\n \"interpret stdin as a JSON object of shape {token, apiUrl?} instead of a bare token\",\n )\n .action(async (opts: { stdin?: boolean; json?: boolean }) => {\n if (!opts.stdin) {\n die(\n new ValidationError(\n \"auth set currently requires --stdin. Pipe the token via stdin.\",\n ),\n );\n }\n\n if (process.stdin.isTTY) {\n die(\n new ValidationError(\n \"stdin is a TTY — pipe the token in (e.g. `op read op://vault/papermark | papermark auth set --stdin`).\",\n ),\n );\n }\n\n const raw = await readStdin();\n if (!raw.trim()) {\n die(\n new ValidationError(\n \"No data on stdin. Pipe a token, or exit with Ctrl-D.\",\n ),\n );\n }\n\n let token: string;\n let apiUrl: string | undefined;\n\n if (opts.json) {\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch (parseErr) {\n die(\n new ValidationError(\"stdin was not valid JSON.\", {\n parseError:\n parseErr instanceof Error ? parseErr.message : String(parseErr),\n }),\n );\n }\n if (!parsed || typeof parsed !== \"object\") {\n die(\n new ValidationError(\n 'Expected a JSON object like {\"token\":\"...\"}.',\n ),\n );\n }\n const p = parsed as { token?: unknown; apiUrl?: unknown; api_url?: unknown };\n if (typeof p.token !== \"string\" || !p.token) {\n die(\n new ValidationError('JSON is missing a non-empty \"token\" field.'),\n );\n }\n token = p.token;\n if (typeof p.apiUrl === \"string\") apiUrl = p.apiUrl;\n else if (typeof p.api_url === \"string\") apiUrl = p.api_url;\n } else {\n // Bare-token mode — strip surrounding whitespace / trailing newline.\n token = raw.trim();\n }\n\n // Snapshot prior credentials so a bad probe doesn't strand the user\n // with a half-applied apiUrl and no working token.\n const prevToken = getToken();\n const prevApiUrl = getApiUrl();\n\n setToken(token);\n if (apiUrl) setApiUrl(apiUrl);\n\n // Validate the token actually works so CI fails fast instead of passing\n // the preflight and blowing up three commands later.\n try {\n await api.listDocuments({ limit: 1 });\n } catch (err) {\n if (prevToken) setToken(prevToken);\n else clearToken();\n if (apiUrl) setApiUrl(prevApiUrl);\n die(err);\n }\n\n const partial = `${token.slice(0, 8)}***${token.slice(-4)}`;\n emit(\n { token: partial, source: getTokenSource(), config: configPath() },\n () =>\n chalk.green(\"✓\") +\n ` Token stored (${partial}). Config: ${chalk.dim(configPath())}`,\n );\n });\n}\n\nfunction readStdin(): Promise<string> {\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = [];\n process.stdin.on(\"data\", (c) => chunks.push(c));\n process.stdin.on(\"end\", () => resolve(Buffer.concat(chunks).toString(\"utf8\")));\n process.stdin.on(\"error\", reject);\n });\n}\n\nasync function loginWithToken(token: string): Promise<void> {\n const prevToken = getToken();\n setToken(token.trim());\n try {\n await api.listDocuments({ limit: 1 });\n } catch (err) {\n if (prevToken) setToken(prevToken);\n else clearToken();\n if (err instanceof NetworkError) {\n writeErrorWithHint(\n err,\n `\\n Current API URL: ${getApiUrl()}\\n` +\n \" If you're running Papermark locally, point the CLI at it:\\n\" +\n \" papermark config set api-url http://localhost:3000/api\",\n );\n }\n throw err;\n }\n emit(\n { apiUrl: getApiUrl(), config: configPath() },\n () =>\n chalk.green(\"✓\") +\n ` Logged in at ${chalk.bold(getApiUrl())}. Config: ${chalk.dim(configPath())}`,\n );\n}\n\n/**\n * Print a formatted error with an extra command-specific hint (e.g. \"your\n * api-url might be pointing at the wrong host\"), respecting --json mode,\n * then exit with the contract-mapped code (so retryable failures keep their\n * exit code 4 instead of being downgraded to 1).\n */\nfunction writeErrorWithHint(err: unknown, hint: string): never {\n const fe = formatError(err);\n if (getRuntime().json) {\n process.stderr.write(\n JSON.stringify({ ok: false, error: fe.json.error }) + \"\\n\",\n );\n } else {\n process.stderr.write(fe.human + chalk.dim(hint) + \"\\n\");\n }\n process.exit(fe.exitCode);\n}\n\nasync function loginWithDeviceFlow(\n scopes: string[],\n { openBrowser }: { openBrowser: boolean },\n): Promise<void> {\n const issuer = deriveIssuer();\n const issuerDisplay = issuer.toString().replace(/\\/$/, \"\");\n const discoverSpinner = ora(`Contacting ${issuerDisplay}`).start();\n let as;\n try {\n as = await discover(issuer);\n } catch (err) {\n discoverSpinner.fail();\n writeErrorWithHint(\n err,\n `\\n Fetched ${issuerDisplay}/.well-known/openid-configuration.\\n` +\n \" If this isn't a Papermark deployment, paste an API token instead:\\n\" +\n \" papermark login --token pm_live_xxx\",\n );\n }\n discoverSpinner.succeed(`Discovered ${as.issuer}`);\n\n const authSpinner = ora(\"Requesting device authorization\").start();\n let auth;\n try {\n auth = await requestDeviceAuthorization(as, scopes);\n } catch (err) {\n authSpinner.fail();\n throw err;\n }\n authSpinner.succeed(\"Got a user code\");\n\n const target = auth.verification_uri_complete ?? auth.verification_uri;\n console.log(\"\");\n console.log(\" \" + chalk.bold(\"Open this URL in your browser:\"));\n console.log(\" \" + chalk.cyan(target));\n console.log(\" \" + chalk.bold(\"And enter this code if prompted:\"));\n console.log(\" \" + chalk.bold(chalk.yellow(auth.user_code)));\n console.log(\"\");\n\n if (openBrowser) {\n await tryOpenBrowser(target);\n }\n\n const pollSpinner = ora(\"Waiting for you to approve in the browser…\").start();\n let token;\n try {\n token = await pollForToken(as, auth.device_code, {\n interval: auth.interval ?? 5,\n expiresIn: auth.expires_in,\n });\n } catch (err) {\n pollSpinner.fail();\n throw err;\n }\n pollSpinner.succeed(\"Access token granted\");\n\n const prevToken = getToken();\n setToken(token.access_token);\n\n // Probe the API to be sure the token actually works through withTeam.\n try {\n await api.listDocuments({ limit: 1 });\n } catch (err) {\n if (prevToken) setToken(prevToken);\n else clearToken();\n throw err;\n }\n\n const expiresIn = token.expires_in ?? null;\n const expiryLabel = formatExpiry(expiresIn);\n emit(\n {\n apiUrl: getApiUrl(),\n config: configPath(),\n ...(token.scope ? { scopes: token.scope.split(\" \") } : {}),\n ...(expiresIn != null ? { expires_in: expiresIn } : {}),\n },\n () => {\n const lines = [\n chalk.green(\"✓\") +\n ` Logged in at ${chalk.bold(getApiUrl())}. Config: ${chalk.dim(configPath())}`,\n ];\n if (token.scope) lines.push(chalk.dim(` Scopes: ${token.scope}`));\n if (expiryLabel) {\n // Stripe-style heads-up so users know re-auth is eventually required.\n lines.push(\n chalk.dim(\n ` Please note: this key will expire after ${expiryLabel}, at which point you'll need to re-authenticate.`,\n ),\n );\n }\n return lines.join(\"\\n\");\n },\n );\n}\n\nfunction formatExpiry(expiresInSeconds: number | null): string | null {\n if (expiresInSeconds == null) return null;\n const days = Math.round(expiresInSeconds / 86_400);\n if (days >= 2) return `${days} days`;\n const hours = Math.round(expiresInSeconds / 3600);\n if (hours >= 2) return `${hours} hours`;\n return `${expiresInSeconds}s`;\n}\n","import * as oauth from \"oauth4webapi\";\nimport open from \"open\";\n\nimport { getApiUrl } from \"./config.js\";\n\nexport const CLIENT_ID = \"papermark-cli\";\n\n// The scopes we ask for by default. The user can narrow these in the\n// consent screen; we never ask for write+read when read alone would do.\nexport const DEFAULT_SCOPES = [\n \"openid\",\n \"offline_access\",\n \"documents.read\",\n \"documents.write\",\n \"links.read\",\n \"links.write\",\n \"datarooms.read\",\n \"datarooms.write\",\n \"analytics.read\",\n \"visitors.read\",\n];\n\n/**\n * Derive the OAuth issuer from the configured api-url. If the api-url points\n * at a papermark deployment's `/api` (e.g. `http://localhost:3000/api` in dev)\n * we strip the trailing `/api`; if it's the canonical API subdomain\n * (`https://api.papermark.com`) we swap to the dashboard host.\n *\n * Note: the OAuth provider runs on the *dashboard* host (`app.papermark.com`),\n * not the API subdomain or the apex domain — `api.papermark.com` serves only\n * REST, and `papermark.com` is the marketing site with no OIDC discovery doc.\n * So `api.<domain>` maps to `app.<domain>`.\n */\nexport function deriveIssuer(apiUrl: string = getApiUrl()): URL {\n const url = new URL(apiUrl);\n if (url.pathname === \"/api\" || url.pathname === \"/api/\") {\n return new URL(`${url.origin}`);\n }\n if (url.hostname.startsWith(\"api.\")) {\n // Use url.host (host:port) so self-hosted deployments on a non-default\n // port don't lose it. url.hostname is host without port.\n return new URL(`${url.protocol}//${url.host.replace(/^api\\./, \"app.\")}`);\n }\n return new URL(url.origin);\n}\n\nexport interface DiscoveredAS {\n issuer: string;\n token_endpoint: string;\n device_authorization_endpoint: string;\n revocation_endpoint?: string;\n}\n\nexport async function discover(issuer: URL): Promise<oauth.AuthorizationServer> {\n const response = await oauth.discoveryRequest(issuer, {\n algorithm: \"oidc\",\n ...allowHttpIfLocal(issuer),\n });\n return oauth.processDiscoveryResponse(issuer, response);\n}\n\n/**\n * oauth4webapi refuses plain-HTTP requests for security. Local dev runs on\n * http://localhost, so we explicitly allow it in that case only. Never set\n * this for a public deployment.\n */\nfunction allowHttpIfLocal(u: URL) {\n const isLocal =\n u.protocol === \"http:\" &&\n (u.hostname === \"localhost\" ||\n u.hostname === \"127.0.0.1\" ||\n u.hostname.endsWith(\".local\"));\n return isLocal ? { [oauth.allowInsecureRequests]: true as const } : {};\n}\n\nexport interface DeviceAuthorizationResponse {\n device_code: string;\n user_code: string;\n verification_uri: string;\n verification_uri_complete?: string;\n expires_in: number;\n interval?: number;\n}\n\nexport async function requestDeviceAuthorization(\n as: oauth.AuthorizationServer,\n scopes: string[],\n): Promise<DeviceAuthorizationResponse> {\n if (!as.device_authorization_endpoint) {\n throw new Error(\n \"Authorization server does not advertise a device authorization endpoint.\",\n );\n }\n const body = new URLSearchParams({\n client_id: CLIENT_ID,\n scope: scopes.join(\" \"),\n });\n const json = await postFormJson(\n as.device_authorization_endpoint,\n body,\n \"device authorization\",\n );\n return json as unknown as DeviceAuthorizationResponse;\n}\n\n/**\n * POST a form-urlencoded body and parse the JSON response, normalizing the\n * three failure modes the device flow can hit:\n * - DNS / TLS / connect-refused → wrapped Error with the URL in the message\n * - non-2xx with a JSON body → Error preserving status + parsed payload\n * - non-2xx with HTML/text → Error preserving status + truncated body\n *\n * Returns parsed JSON on 2xx with a JSON body. The caller decides whether\n * specific error codes (e.g. authorization_pending) mean \"keep polling\".\n */\nasync function postFormJson(\n endpoint: string,\n body: URLSearchParams,\n what: string,\n): Promise<Record<string, unknown>> {\n let res: Response;\n try {\n res = await fetch(endpoint, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n Accept: \"application/json\",\n },\n body,\n });\n } catch (err) {\n const reason = err instanceof Error ? err.message : String(err);\n throw new Error(\n `${what}: network request to ${endpoint} failed (${reason}). Check connectivity and that the OAuth server is reachable.`,\n );\n }\n const text = await res.text();\n let parsed: Record<string, unknown> | null = null;\n try {\n parsed = text ? (JSON.parse(text) as Record<string, unknown>) : null;\n } catch {\n parsed = null;\n }\n if (!res.ok) {\n if (parsed) {\n const e = new Error(\n `${what} failed: ${res.status} ${JSON.stringify(parsed)}`,\n );\n // Stash the parsed body so callers (pollForToken) can branch on\n // OAuth-defined error codes without re-parsing.\n (e as Error & { body?: Record<string, unknown> }).body = parsed;\n throw e;\n }\n const snippet = text ? text.slice(0, 200) : \"(empty body)\";\n throw new Error(\n `${what} failed: HTTP ${res.status} (non-JSON response: ${snippet})`,\n );\n }\n if (!parsed) {\n throw new Error(\n `${what} succeeded but returned a non-JSON body — is the endpoint correct? URL: ${endpoint}`,\n );\n }\n return parsed;\n}\n\nexport interface TokenResponse {\n access_token: string;\n token_type: string;\n expires_in?: number;\n refresh_token?: string;\n scope?: string;\n}\n\n/**\n * Poll the token endpoint until the user approves, denies, or the device\n * code expires. Honors `authorization_pending` and `slow_down` per RFC 8628.\n */\nexport async function pollForToken(\n as: oauth.AuthorizationServer,\n deviceCode: string,\n {\n interval = 5,\n expiresIn = 600,\n onTick,\n }: { interval?: number; expiresIn?: number; onTick?: () => void } = {},\n): Promise<TokenResponse> {\n if (!as.token_endpoint) throw new Error(\"No token_endpoint in discovery\");\n const deadline = Date.now() + expiresIn * 1000;\n let wait = Math.max(interval, 1);\n\n while (Date.now() < deadline) {\n await new Promise((r) => setTimeout(r, wait * 1000));\n onTick?.();\n const body = new URLSearchParams({\n grant_type: \"urn:ietf:params:oauth:grant-type:device_code\",\n device_code: deviceCode,\n client_id: CLIENT_ID,\n });\n let parsed: Record<string, unknown>;\n try {\n parsed = await postFormJson(as.token_endpoint, body, \"token request\");\n } catch (err) {\n // OAuth defines two error codes that mean \"keep polling\": pending\n // (user hasn't approved yet) and slow_down (we're hitting too fast).\n // postFormJson stashed the parsed body on the Error.\n const errBody = (err as Error & { body?: Record<string, unknown> }).body;\n const errCode = errBody?.error as string | undefined;\n if (errCode === \"authorization_pending\") continue;\n if (errCode === \"slow_down\") {\n wait += 5;\n continue;\n }\n throw err;\n }\n return parsed as unknown as TokenResponse;\n }\n throw new Error(\"Device code expired before authorization completed.\");\n}\n\nexport async function tryOpenBrowser(url: string): Promise<void> {\n try {\n await open(url);\n } catch {\n // ignore — user can copy/paste\n }\n}\n","import chalk from \"chalk\";\nimport { Command } from \"commander\";\n\nimport {\n configPath,\n deleteKey,\n getAll,\n setApiUrl,\n} from \"../config.js\";\nimport { die } from \"../output.js\";\n\nconst KNOWN_KEYS = [\"api-url\"] as const;\ntype KnownKey = (typeof KNOWN_KEYS)[number];\n\nfunction isKnown(key: string): key is KnownKey {\n return (KNOWN_KEYS as readonly string[]).includes(key);\n}\n\nexport function registerConfigCommands(program: Command): void {\n const cfg = program.command(\"config\").description(\"Manage CLI configuration\");\n\n cfg\n .command(\"get [key]\")\n .description(\"Print one or all config values\")\n .action((key?: string) => {\n const all = getAll();\n if (!key) {\n console.log(`${chalk.dim(\"# \" + configPath())}`);\n console.log(`api-url ${all.apiUrl ?? \"\"}`);\n console.log(`token ${all.token ? \"(set)\" : \"(not set)\"}`);\n return;\n }\n if (!isKnown(key)) return die(new Error(`Unknown key: ${key}`));\n if (key === \"api-url\") console.log(all.apiUrl ?? \"\");\n });\n\n cfg\n .command(\"set <key> <value>\")\n .description(`Set a config value. Known keys: ${KNOWN_KEYS.join(\", \")}`)\n .action((key: string, value: string) => {\n if (!isKnown(key)) return die(new Error(`Unknown key: ${key}`));\n if (key === \"api-url\") setApiUrl(value);\n console.log(chalk.green(\"✓\") + ` ${key} = ${value}`);\n });\n\n cfg\n .command(\"unset <key>\")\n .description(\"Clear a config value\")\n .action((key: string) => {\n if (!isKnown(key)) return die(new Error(`Unknown key: ${key}`));\n if (key === \"api-url\") deleteKey(\"apiUrl\");\n console.log(chalk.green(\"✓\") + ` ${key} unset`);\n });\n}\n","import chalk from \"chalk\";\nimport { Command } from \"commander\";\n\nimport { api } from \"../client.js\";\nimport { die, emit, json, sanitizeForTerminal, table } from \"../output.js\";\nimport { parsePermissionEntries } from \"./permissions-input.js\";\nimport { setRuntime } from \"../runtime.js\";\n\nexport function registerDataroomsCommands(program: Command): void {\n const dr = program\n .command(\"datarooms\")\n .alias(\"dr\")\n .description(\"Manage datarooms\");\n\n dr\n .command(\"list\")\n .description(\"List datarooms\")\n .option(\"-l, --limit <n>\", \"max results (1-100)\", \"25\")\n .option(\"-c, --cursor <id>\", \"pagination cursor\")\n .option(\"-q, --query <substring>\", \"filter by dataroom name\")\n .option(\"--json\", \"output raw JSON (same as --json on the root command)\")\n .action(\n async (opts: {\n limit?: string;\n cursor?: string;\n query?: string;\n json?: boolean;\n }) => {\n if (opts.json) setRuntime({ json: true });\n try {\n const res = await api.listDatarooms({\n limit: opts.limit ? Number(opts.limit) : undefined,\n cursor: opts.cursor,\n query: opts.query,\n });\n emit(res, () => {\n const rows = res.data.map((d) => ({\n id: d.pid,\n name: truncate(d.name, 30),\n docs: String(d.document_count),\n folders: String(d.folder_count),\n created: d.created.slice(0, 10),\n }));\n const out = table(rows, [\"id\", \"name\", \"docs\", \"folders\", \"created\"]);\n return res.next_cursor\n ? out + chalk.dim(`\\n\\nMore results: --cursor ${res.next_cursor}`)\n : out;\n });\n } catch (err) {\n die(err);\n }\n },\n );\n\n dr\n .command(\"get <id>\")\n .description(\n \"Fetch one dataroom. `id` accepts the internal cuid or the `dr_...` public id.\",\n )\n .action(async (id: string) => {\n try {\n const room = await api.getDataroom(id);\n emit(room, () => json(room));\n } catch (err) {\n die(err);\n }\n });\n\n dr\n .command(\"create\")\n .description(\"Create a new (empty) dataroom\")\n .requiredOption(\"-n, --name <name>\", \"dataroom name\")\n .option(\n \"--internal-name <slug>\",\n \"private alias visible only to your team\",\n )\n .option(\"-d, --description <text>\", \"human-readable description\")\n .action(\n async (opts: {\n name: string;\n internalName?: string;\n description?: string;\n }) => {\n try {\n const room = await api.createDataroom({\n name: opts.name,\n internal_name: opts.internalName,\n description: opts.description,\n });\n emit(\n room,\n () =>\n chalk.green(\"✓\") +\n ` Dataroom created: ${chalk.bold(room.pid)}\\n` +\n json(room),\n );\n } catch (err) {\n die(err);\n }\n },\n );\n\n dr\n .command(\"update <id>\")\n .description(\n \"Update a dataroom. `id` accepts the internal cuid or the `dr_...` public id.\",\n )\n .option(\"-n, --name <name>\")\n .option(\"--internal-name <slug>\", \"set or clear (use empty string)\")\n .option(\"-d, --description <text>\", \"set or clear (use empty string)\")\n .option(\"--bulk-download <on|off>\", \"allow or block bulk download\")\n .action(\n async (\n id: string,\n opts: {\n name?: string;\n internalName?: string;\n description?: string;\n bulkDownload?: string;\n },\n ) => {\n try {\n const body: Parameters<typeof api.updateDataroom>[1] = {};\n if (opts.name !== undefined) body.name = opts.name;\n if (opts.internalName !== undefined)\n body.internal_name = opts.internalName === \"\" ? null : opts.internalName;\n if (opts.description !== undefined)\n body.description = opts.description === \"\" ? null : opts.description;\n const tri = (\n v: string | undefined,\n flag: string,\n ): boolean | undefined => {\n if (v === undefined) return undefined;\n const norm = v.toLowerCase();\n if (norm === \"on\") return true;\n if (norm === \"off\") return false;\n throw new Error(\n `Invalid value for ${flag}: ${JSON.stringify(v)} (expected \"on\" or \"off\").`,\n );\n };\n const bulk = tri(opts.bulkDownload, \"--bulk-download\");\n if (bulk !== undefined) body.allow_bulk_download = bulk;\n\n if (Object.keys(body).length === 0) {\n throw new Error(\n \"Pass at least one field to update (e.g. --name, --description, --bulk-download off).\",\n );\n }\n const room = await api.updateDataroom(id, body);\n emit(\n room,\n () =>\n chalk.green(\"✓\") +\n ` Dataroom updated: ${chalk.bold(room.pid)}\\n` +\n json(room),\n );\n } catch (err) {\n die(err);\n }\n },\n );\n\n dr\n .command(\"links <id>\")\n .description(\n \"List share links scoped to a dataroom. `id` accepts the internal cuid or the `dr_...` public id.\",\n )\n .option(\"-l, --limit <n>\", \"max results (1-100)\", \"25\")\n .option(\"-c, --cursor <id>\", \"pagination cursor\")\n .option(\"--json\", \"output raw JSON (same as --json on the root command)\")\n .action(\n async (\n id: string,\n opts: { limit?: string; cursor?: string; json?: boolean },\n ) => {\n if (opts.json) setRuntime({ json: true });\n try {\n const res = await api.listLinks({\n dataroom_id: id,\n limit: opts.limit ? Number(opts.limit) : undefined,\n cursor: opts.cursor,\n });\n emit(res, () => {\n const rows = res.data.map((l) => ({\n id: l.id,\n name: truncate(l.name ?? \"\", 30),\n url: truncate(l.url, 45),\n password: l.is_password_protected ? \"yes\" : \"\",\n expires: l.expires_at ? l.expires_at.slice(0, 10) : \"\",\n }));\n const out = table(rows, [\"id\", \"name\", \"url\", \"password\", \"expires\"]);\n return res.next_cursor\n ? out + chalk.dim(`\\n\\nMore results: --cursor ${res.next_cursor}`)\n : out;\n });\n } catch (err) {\n die(err);\n }\n },\n );\n\n dr\n .command(\"viewers <id>\")\n .description(\n \"List persistent visitors (Viewer rows) tied to a dataroom. `id` accepts the internal cuid or the `dr_...` public id.\",\n )\n .option(\"-l, --limit <n>\", \"max results (1-100)\", \"25\")\n .option(\"-c, --cursor <id>\", \"pagination cursor\")\n .option(\"--email <email>\", \"filter to a specific email (exact match)\")\n .option(\"--json\", \"output raw JSON (same as --json on the root command)\")\n .action(\n async (\n id: string,\n opts: {\n limit?: string;\n cursor?: string;\n email?: string;\n json?: boolean;\n },\n ) => {\n if (opts.json) setRuntime({ json: true });\n try {\n const res = await api.listVisitors({\n dataroom_id: id,\n limit: opts.limit ? Number(opts.limit) : undefined,\n cursor: opts.cursor,\n email: opts.email,\n });\n emit(res, () => {\n const rows = res.data.map((v) => ({\n id: v.id,\n email: sanitizeForTerminal(v.email),\n verified: v.verified ? \"yes\" : \"\",\n views: String(v.total_views),\n last_view: v.last_viewed_at?.slice(0, 10) ?? \"\",\n }));\n const out = table(rows, [\"id\", \"email\", \"verified\", \"views\", \"last_view\"]);\n return res.next_cursor\n ? out + chalk.dim(`\\n\\nMore results: --cursor ${res.next_cursor}`)\n : out;\n });\n } catch (err) {\n die(err);\n }\n },\n );\n\n dr\n .command(\"stats <id>\")\n .alias(\"analytics\")\n .description(\n \"Aggregate analytics for a dataroom: total views, unique viewers, total read time. Backed by Tinybird — subject to a stricter rate limit. `id` accepts the internal cuid or the `dr_...` public id.\",\n )\n .option(\n \"--since <unix-ms>\",\n \"window start (default: 30 days ago)\",\n (v) => Number(v),\n )\n .option(\n \"--until <unix-ms>\",\n \"window end (default: now)\",\n (v) => Number(v),\n )\n .option(\"--json\", \"output raw JSON (same as --json on the root command)\")\n .action(\n async (\n id: string,\n opts: { since?: number; until?: number; json?: boolean },\n ) => {\n if (opts.json) setRuntime({ json: true });\n try {\n const stats = await api.dataroomAnalytics(id, {\n since: opts.since,\n until: opts.until,\n });\n emit(stats, () => {\n const minutes = Math.round(stats.total_duration_seconds / 60);\n return [\n `${chalk.bold(\"Dataroom:\")} ${stats.dataroom_id}`,\n `${chalk.bold(\"Total views:\")} ${stats.total_views}`,\n `${chalk.bold(\"Unique viewers:\")} ${stats.unique_viewers}`,\n `${chalk.bold(\"Total read time:\")} ${minutes} min (${stats.total_duration_seconds.toFixed(1)} s)`,\n chalk.dim(\n `Window: ${stats.since.slice(0, 10)} → ${stats.until.slice(0, 10)}`,\n ),\n ].join(\"\\n\");\n });\n } catch (err) {\n die(err);\n }\n },\n );\n\n dr\n .command(\"delete <id>\")\n .description(\n \"Delete a dataroom. `id` accepts the internal cuid or the `dr_...` public id.\",\n )\n .action(async (id: string) => {\n try {\n const deleted = await api.deleteDataroom(id);\n emit(\n deleted,\n () => chalk.green(\"✓\") + ` Dataroom ${id} deleted.`,\n );\n } catch (err) {\n die(err);\n }\n });\n\n dr\n .command(\"attach <id>\")\n .description(\n \"Attach an existing document to a dataroom. The document stays in the team library; this just adds it to the dataroom contents.\",\n )\n .requiredOption(\"--document <id>\", \"document id to attach\")\n .option(\n \"--folder-id <fid>\",\n \"place under a specific dataroom folder (must belong to the same dataroom)\",\n )\n .action(\n async (\n id: string,\n opts: { document: string; folderId?: string },\n ) => {\n try {\n const item = await api.attachDataroomDocument(id, {\n document_id: opts.document,\n folder_id: opts.folderId,\n });\n emit(\n item,\n () =>\n chalk.green(\"✓\") +\n ` Attached document ${chalk.bold(item.document_id)} as item ${chalk.bold(item.id)}.\\n` +\n json(item),\n );\n } catch (err) {\n die(err);\n }\n },\n );\n\n dr\n .command(\"detach <id> <ddId>\")\n .description(\n \"Detach a document from a dataroom by its dataroom-document id (the item id from `attach` or `documents`, not the document id). The document stays in the team library and attached to any other datarooms.\",\n )\n .action(async (id: string, ddId: string) => {\n try {\n const deleted = await api.detachDataroomDocument(id, ddId);\n emit(\n deleted,\n () => chalk.green(\"✓\") + ` Document ${ddId} detached from dataroom.`,\n );\n } catch (err) {\n die(err);\n }\n });\n\n dr\n .command(\"move <id> <ddId>\")\n .description(\n 'Move a document to a different folder within the dataroom, by its dataroom-document id. Pass --folder-id <fid>, or --root (or --folder-id \"\" / --folder-id root) for the dataroom root.',\n )\n .option(\n \"--folder-id <fid>\",\n 'target dataroom folder id; pass \"\" or \"root\" for the dataroom root',\n )\n .option(\"--root\", \"move to the dataroom root (alias for --folder-id root)\")\n .action(\n async (\n id: string,\n ddId: string,\n opts: { folderId?: string; root?: boolean },\n ) => {\n try {\n // Root sentinels: --root, or --folder-id with \"\" or \"root\".\n const folderIsRoot =\n opts.folderId === \"\" || opts.folderId === \"root\";\n if (opts.root && opts.folderId !== undefined && !folderIsRoot) {\n throw new Error(\n \"Pass either --root or --folder-id <fid>, not both.\",\n );\n }\n if (!opts.root && opts.folderId === undefined) {\n throw new Error(\n 'Pass --folder-id <fid>, or --root (or --folder-id \"\") to move to the dataroom root.',\n );\n }\n const folder_id = opts.root || folderIsRoot ? null : opts.folderId!;\n const item = await api.moveDataroomDocument(id, ddId, { folder_id });\n emit(\n item,\n () =>\n chalk.green(\"✓\") +\n ` Document moved.${\n item.folder_path\n ? ` New folder: ${chalk.bold(item.folder_path)}`\n : \" Now at the dataroom root.\"\n }\\n` +\n json(item),\n );\n } catch (err) {\n die(err);\n }\n },\n );\n\n // ─── Dataroom groups ─────────────────────────────────────────────────\n const drGroups = dr\n .command(\"groups\")\n .description(\n \"Manage viewer groups: audiences with per-item permissions, shared via group links\",\n );\n\n drGroups\n .command(\"list <id>\")\n .description(\"List viewer groups in a dataroom\")\n .option(\"-l, --limit <n>\", \"max results (1-100)\", \"25\")\n .option(\"-c, --cursor <id>\", \"pagination cursor\")\n .option(\"--json\", \"output raw JSON\")\n .action(\n async (\n id: string,\n opts: { limit?: string; cursor?: string; json?: boolean },\n ) => {\n if (opts.json) setRuntime({ json: true });\n try {\n const res = await api.listDataroomGroups(id, {\n limit: opts.limit ? Number(opts.limit) : undefined,\n cursor: opts.cursor,\n });\n emit(res, () => {\n const rows = res.data.map((g) => ({\n id: g.id,\n name: truncate(g.name, 30),\n members: String(g.member_count),\n links: String(g.link_count),\n domains: truncate(g.domains.join(\",\"), 30),\n allow_all: g.allow_all ? \"yes\" : \"\",\n }));\n const out = table(rows, [\n \"id\",\n \"name\",\n \"members\",\n \"links\",\n \"domains\",\n \"allow_all\",\n ]);\n return res.next_cursor\n ? out + chalk.dim(`\\n\\nMore results: --cursor ${res.next_cursor}`)\n : out;\n });\n } catch (err) {\n die(err);\n }\n },\n );\n\n drGroups\n .command(\"get <id> <gid>\")\n .description(\"Fetch one viewer group\")\n .action(async (id: string, gid: string) => {\n try {\n const g = await api.getDataroomGroup(id, gid);\n emit(g, () => json(g));\n } catch (err) {\n die(err);\n }\n });\n\n drGroups\n .command(\"create <id>\")\n .description(\"Create a viewer group in a dataroom\")\n .requiredOption(\"-n, --name <name>\", \"group name\")\n .option(\n \"--domains <domains>\",\n \"comma-separated email domains treated as members (e.g. 'acme.com')\",\n )\n .option(\n \"--allow-all\",\n \"treat anyone passing the link's access gates as a member\",\n false,\n )\n .action(\n async (\n id: string,\n opts: { name: string; domains?: string; allowAll?: boolean },\n ) => {\n try {\n const g = await api.createDataroomGroup(id, {\n name: opts.name,\n allow_all: opts.allowAll || undefined,\n domains: opts.domains\n ? opts.domains.split(\",\").map((s) => s.trim()).filter(Boolean)\n : undefined,\n });\n emit(\n g,\n () =>\n chalk.green(\"✓\") +\n ` Group created: ${chalk.bold(g.id)}\\n` +\n json(g),\n );\n } catch (err) {\n die(err);\n }\n },\n );\n\n drGroups\n .command(\"update <id> <gid>\")\n .description(\"Update a viewer group\")\n .option(\"-n, --name <name>\")\n .option(\n \"--domains <domains>\",\n \"comma-separated email domains (empty string to clear)\",\n )\n .option(\"--allow-all <on|off>\", \"toggle the allow-anyone flag\")\n .action(\n async (\n id: string,\n gid: string,\n opts: { name?: string; domains?: string; allowAll?: string },\n ) => {\n try {\n const body: Parameters<typeof api.updateDataroomGroup>[2] = {};\n if (opts.name !== undefined) body.name = opts.name;\n if (opts.domains !== undefined)\n body.domains =\n opts.domains === \"\"\n ? []\n : opts.domains.split(\",\").map((s) => s.trim()).filter(Boolean);\n if (opts.allowAll !== undefined) {\n const norm = opts.allowAll.toLowerCase();\n if (norm !== \"on\" && norm !== \"off\") {\n throw new Error(\n `Invalid value for --allow-all: ${JSON.stringify(opts.allowAll)} (expected \"on\" or \"off\").`,\n );\n }\n body.allow_all = norm === \"on\";\n }\n if (Object.keys(body).length === 0) {\n throw new Error(\n \"Pass at least one of --name, --domains, --allow-all to update.\",\n );\n }\n const g = await api.updateDataroomGroup(id, gid, body);\n emit(\n g,\n () =>\n chalk.green(\"✓\") +\n ` Group updated: ${chalk.bold(g.id)}\\n` +\n json(g),\n );\n } catch (err) {\n die(err);\n }\n },\n );\n\n drGroups\n .command(\"delete <id> <gid>\")\n .description(\n \"Delete a viewer group. WARNING: also deletes every share link pointing at the group — active group links stop resolving immediately.\",\n )\n .action(async (id: string, gid: string) => {\n try {\n const deleted = await api.deleteDataroomGroup(id, gid);\n emit(\n deleted,\n () =>\n chalk.green(\"✓\") +\n ` Group ${gid} deleted (including its share links).`,\n );\n } catch (err) {\n die(err);\n }\n });\n\n const drGroupMembers = drGroups\n .command(\"members\")\n .description(\"Manage a group's email members\");\n\n drGroupMembers\n .command(\"list <id> <gid>\")\n .description(\n \"List a group's explicit email members (domain/allow-all admissions are not listed)\",\n )\n .option(\"-l, --limit <n>\", \"max results (1-100)\", \"50\")\n .option(\"-c, --cursor <id>\", \"pagination cursor\")\n .option(\"--json\", \"output raw JSON\")\n .action(\n async (\n id: string,\n gid: string,\n opts: { limit?: string; cursor?: string; json?: boolean },\n ) => {\n if (opts.json) setRuntime({ json: true });\n try {\n const res = await api.listDataroomGroupMembers(id, gid, {\n limit: opts.limit ? Number(opts.limit) : undefined,\n cursor: opts.cursor,\n });\n emit(res, () => {\n const rows = res.data.map((m) => ({\n id: m.id,\n email: sanitizeForTerminal(m.email),\n added: m.created.slice(0, 10),\n }));\n const out = table(rows, [\"id\", \"email\", \"added\"]);\n return res.next_cursor\n ? out + chalk.dim(`\\n\\nMore results: --cursor ${res.next_cursor}`)\n : out;\n });\n } catch (err) {\n die(err);\n }\n },\n );\n\n drGroupMembers\n .command(\"add <id> <gid>\")\n .description(\n \"Add members by email (idempotent; no invitation emails are sent)\",\n )\n .requiredOption(\n \"-e, --emails <emails>\",\n \"comma-separated email addresses (max 500)\",\n )\n .action(async (id: string, gid: string, opts: { emails: string }) => {\n try {\n const emails = opts.emails\n .split(\",\")\n .map((s) => s.trim())\n .filter(Boolean);\n if (emails.length === 0) {\n throw new Error(\"Pass at least one email via --emails.\");\n }\n const res = await api.addDataroomGroupMembers(id, gid, { emails });\n emit(\n res,\n () =>\n chalk.green(\"✓\") +\n ` ${res.data.length} member(s) in group after add:\\n` +\n table(\n res.data.map((m) => ({\n id: m.id,\n email: sanitizeForTerminal(m.email),\n })),\n [\"id\", \"email\"],\n ),\n );\n } catch (err) {\n die(err);\n }\n });\n\n drGroupMembers\n .command(\"remove <id> <gid> <mid>\")\n .description(\n \"Remove a member by membership id (from `members list`). The viewer itself is kept.\",\n )\n .action(async (id: string, gid: string, mid: string) => {\n try {\n const deleted = await api.removeDataroomGroupMember(id, gid, mid);\n emit(\n deleted,\n () => chalk.green(\"✓\") + ` Member ${mid} removed from group.`,\n );\n } catch (err) {\n die(err);\n }\n });\n\n const drGroupPermissions = drGroups\n .command(\"permissions\")\n .description(\"Manage a group's per-item view/download permissions\");\n\n drGroupPermissions\n .command(\"get <id> <gid>\")\n .description(\n \"List the group's access controls. Items without an entry are invisible to the group.\",\n )\n .option(\"-l, --limit <n>\", \"max results (1-100)\", \"100\")\n .option(\"-c, --cursor <id>\", \"pagination cursor\")\n .option(\"--json\", \"output raw JSON\")\n .action(\n async (\n id: string,\n gid: string,\n opts: { limit?: string; cursor?: string; json?: boolean },\n ) => {\n if (opts.json) setRuntime({ json: true });\n try {\n const res = await api.listDataroomGroupPermissions(id, gid, {\n limit: opts.limit ? Number(opts.limit) : undefined,\n cursor: opts.cursor,\n });\n emit(res, () => {\n const rows = res.data.map((p) => ({\n item_id: p.item_id,\n type: p.item_type === \"dataroom_document\" ? \"document\" : \"folder\",\n view: p.can_view ? \"yes\" : \"\",\n download: p.can_download ? \"yes\" : \"\",\n }));\n const out = table(rows, [\"item_id\", \"type\", \"view\", \"download\"]);\n return res.next_cursor\n ? out + chalk.dim(`\\n\\nMore results: --cursor ${res.next_cursor}`)\n : out;\n });\n } catch (err) {\n die(err);\n }\n },\n );\n\n drGroupPermissions\n .command(\"set <id> <gid>\")\n .description(\n \"Upsert per-item permissions (delta: omitted items keep their state; ancestor folders of visible items are auto-shown). Item ids come from `datarooms documents` / `datarooms folders list`.\",\n )\n .option(\n \"--file <path>\",\n \"JSON array of { item_id, item_type, can_view, can_download }\",\n )\n .option(\"--item <itemId>\", \"single item id (use with --type/--view/--download)\")\n .option(\"--type <document|folder>\", \"item type for --item\")\n .option(\"--view <on|off>\", \"allow viewing (default on)\")\n .option(\"--download <on|off>\", \"allow downloading (default off)\")\n .action(\n async (\n id: string,\n gid: string,\n opts: {\n file?: string;\n item?: string;\n type?: string;\n view?: string;\n download?: string;\n },\n ) => {\n try {\n const permissions = parsePermissionEntries(opts);\n const res = await api.setDataroomGroupPermissions(id, gid, {\n permissions,\n });\n emit(\n res,\n () =>\n chalk.green(\"✓\") +\n ` ${res.data.length} permission row(s) now effective:\\n` +\n table(\n res.data.map((p) => ({\n item_id: p.item_id,\n type:\n p.item_type === \"dataroom_document\" ? \"document\" : \"folder\",\n view: p.can_view ? \"yes\" : \"\",\n download: p.can_download ? \"yes\" : \"\",\n })),\n [\"item_id\", \"type\", \"view\", \"download\"],\n ),\n );\n } catch (err) {\n die(err);\n }\n },\n );\n\n // ─── Dataroom folders ────────────────────────────────────────────────\n const drFolders = dr\n .command(\"folders\")\n .description(\"Manage folders inside a dataroom\");\n\n drFolders\n .command(\"list <id>\")\n .description(\"List folders in a dataroom\")\n .option(\n \"--parent <fid>\",\n \"restrict to direct children of this folder (use 'root' for top-level)\",\n )\n .option(\"-l, --limit <n>\", \"max results (1-100)\", \"50\")\n .option(\"-c, --cursor <id>\", \"pagination cursor\")\n .option(\"--json\", \"output raw JSON\")\n .action(\n async (\n id: string,\n opts: {\n parent?: string;\n limit?: string;\n cursor?: string;\n json?: boolean;\n },\n ) => {\n if (opts.json) setRuntime({ json: true });\n try {\n const res = await api.listDataroomFolders(id, {\n limit: opts.limit ? Number(opts.limit) : undefined,\n cursor: opts.cursor,\n parent_id: opts.parent,\n });\n emit(res, () => {\n const rows = res.data.map((f) => ({\n id: f.id,\n name: truncate(f.name, 30),\n path: truncate(f.path, 40),\n docs: String(f.document_count),\n children: String(f.child_folder_count),\n }));\n const out = table(rows, [\"id\", \"name\", \"path\", \"docs\", \"children\"]);\n return res.next_cursor\n ? out + chalk.dim(`\\n\\nMore results: --cursor ${res.next_cursor}`)\n : out;\n });\n } catch (err) {\n die(err);\n }\n },\n );\n\n drFolders\n .command(\"create <id>\")\n .description(\"Create a folder inside a dataroom\")\n .requiredOption(\"-n, --name <name>\", \"folder name\")\n .option(\"--parent <fid>\", \"parent folder id (omit for dataroom root)\")\n .option(\"--icon <icon>\", \"icon name (e.g. folder, briefcase, lock)\")\n .option(\"--color <color>\", \"color token (gray, red, orange, yellow, green, blue, black)\")\n .action(\n async (\n id: string,\n opts: { name: string; parent?: string; icon?: string; color?: string },\n ) => {\n try {\n const f = await api.createDataroomFolder(id, {\n name: opts.name,\n parent_id: opts.parent ?? null,\n icon: opts.icon as never,\n color: opts.color as never,\n });\n emit(\n f,\n () =>\n chalk.green(\"✓\") +\n ` Dataroom folder created: ${chalk.bold(f.id)}\\n` +\n json(f),\n );\n } catch (err) {\n die(err);\n }\n },\n );\n\n drFolders\n .command(\"get <id> <fid>\")\n .description(\"Fetch one dataroom folder\")\n .action(async (id: string, fid: string) => {\n try {\n const f = await api.getDataroomFolder(id, fid);\n emit(f, () => json(f));\n } catch (err) {\n die(err);\n }\n });\n\n drFolders\n .command(\"update <id> <fid>\")\n .description(\"Update a dataroom folder\")\n .option(\"-n, --name <name>\")\n .option(\"--icon <icon>\", \"icon name (empty string to clear)\")\n .option(\"--color <color>\", \"color token (empty string to clear)\")\n .action(\n async (\n id: string,\n fid: string,\n opts: { name?: string; icon?: string; color?: string },\n ) => {\n try {\n const body: Parameters<typeof api.updateDataroomFolder>[2] = {};\n if (opts.name !== undefined) body.name = opts.name;\n if (opts.icon !== undefined)\n body.icon = (opts.icon === \"\" ? null : opts.icon) as never;\n if (opts.color !== undefined)\n body.color = (opts.color === \"\" ? null : opts.color) as never;\n if (Object.keys(body).length === 0) {\n throw new Error(\n \"Pass at least one of --name, --icon, --color to update.\",\n );\n }\n const f = await api.updateDataroomFolder(id, fid, body);\n emit(\n f,\n () =>\n chalk.green(\"✓\") +\n ` Dataroom folder updated: ${chalk.bold(f.id)}\\n` +\n json(f),\n );\n } catch (err) {\n die(err);\n }\n },\n );\n\n drFolders\n .command(\"delete <id> <fid>\")\n .description(\"Delete a dataroom folder\")\n .option(\n \"--cascade\",\n \"also delete nested folders + dataroom-document attachments\",\n false,\n )\n .action(\n async (id: string, fid: string, opts: { cascade?: boolean }) => {\n try {\n const deleted = await api.deleteDataroomFolder(id, fid, {\n cascade: opts.cascade,\n });\n emit(\n deleted,\n () => chalk.green(\"✓\") + ` Dataroom folder ${fid} deleted.`,\n );\n } catch (err) {\n die(err);\n }\n },\n );\n\n drFolders\n .command(\"move <id> <fid>\")\n .description(\"Move a dataroom folder under a different parent\")\n .option(\n \"--parent <fid>\",\n \"target parent folder id; pass empty string for the dataroom root\",\n )\n .action(\n async (id: string, fid: string, opts: { parent?: string }) => {\n try {\n if (opts.parent === undefined) {\n throw new Error(\n \"Pass --parent <fid> (use empty string to move to the root).\",\n );\n }\n const parent_id = opts.parent === \"\" ? null : opts.parent;\n const f = await api.moveDataroomFolder(id, fid, { parent_id });\n emit(\n f,\n () =>\n chalk.green(\"✓\") +\n ` Folder moved. New path: ${chalk.bold(f.path)}\\n` +\n json(f),\n );\n } catch (err) {\n die(err);\n }\n },\n );\n\n dr\n .command(\"documents <id>\")\n .description(\n \"List documents inside a dataroom. `id` accepts the internal cuid or the `dr_...` public id.\",\n )\n .option(\"-l, --limit <n>\", \"max results (1-100)\", \"50\")\n .option(\"-c, --cursor <id>\", \"pagination cursor\")\n .option(\"--folder <id>\", \"restrict to a folder\")\n .option(\"--json\", \"output raw JSON (same as --json on the root command)\")\n .action(\n async (\n id: string,\n opts: { limit?: string; cursor?: string; folder?: string; json?: boolean },\n ) => {\n if (opts.json) setRuntime({ json: true });\n try {\n const res = await api.listDataroomDocuments(id, {\n limit: opts.limit ? Number(opts.limit) : undefined,\n cursor: opts.cursor,\n folder_id: opts.folder,\n });\n emit(res, () => {\n const rows = res.data.map((it) => ({\n id: it.id,\n document: truncate(it.document_name, 32),\n folder: truncate(it.folder_path ?? \"/\", 64),\n type: it.content_type ?? \"\",\n pages: it.num_pages?.toString() ?? \"\",\n }));\n const out = table(rows, [\"id\", \"document\", \"folder\", \"type\", \"pages\"]);\n return res.next_cursor\n ? out + chalk.dim(`\\n\\nMore results: --cursor ${res.next_cursor}`)\n : out;\n });\n } catch (err) {\n die(err);\n }\n },\n );\n}\n\nfunction truncate(s: string, n: number): string {\n const clean = sanitizeForTerminal(s);\n return clean.length > n ? clean.slice(0, n - 1) + \"…\" : clean;\n}\n","import { readFileSync } from \"node:fs\";\n\nimport type { PermissionEntry, PermissionItemType } from \"../client.js\";\n\nexport interface PermissionFlagOpts {\n file?: string;\n item?: string;\n type?: string;\n view?: string;\n download?: string;\n}\n\nconst ITEM_TYPES: Record<string, PermissionItemType> = {\n document: \"dataroom_document\",\n dataroom_document: \"dataroom_document\",\n folder: \"dataroom_folder\",\n dataroom_folder: \"dataroom_folder\",\n};\n\nfunction onOff(v: string | undefined, flag: string, fallback: boolean): boolean {\n if (v === undefined) return fallback;\n const norm = v.toLowerCase();\n if (norm === \"on\") return true;\n if (norm === \"off\") return false;\n throw new Error(\n `Invalid value for ${flag}: ${JSON.stringify(v)} (expected \"on\" or \"off\").`,\n );\n}\n\n// Parse permission entries from either --file <path> (JSON array of\n// { item_id, item_type, can_view, can_download }) or the single-item flags\n// --item/--type/--view/--download. Exactly one input style is required.\nexport function parsePermissionEntries(opts: PermissionFlagOpts): PermissionEntry[] {\n if (opts.file && opts.item) {\n throw new Error(\"Pass either --file or --item, not both.\");\n }\n\n if (opts.file) {\n let raw: string;\n try {\n raw = readFileSync(opts.file, \"utf8\");\n } catch (err) {\n throw new Error(\n `Could not read ${opts.file}: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n throw new Error(`${opts.file} is not valid JSON.`);\n }\n if (!Array.isArray(parsed)) {\n throw new Error(\n `${opts.file} must contain a JSON array of { item_id, item_type, can_view, can_download }.`,\n );\n }\n return parsed.map((entry, i) => {\n const e = entry as Record<string, unknown>;\n const itemType = ITEM_TYPES[String(e.item_type)];\n if (typeof e.item_id !== \"string\" || !e.item_id) {\n throw new Error(`Entry ${i}: missing or invalid item_id.`);\n }\n if (!itemType) {\n throw new Error(\n `Entry ${i}: invalid item_type ${JSON.stringify(e.item_type)} (expected dataroom_document or dataroom_folder).`,\n );\n }\n if (typeof e.can_view !== \"boolean\" || typeof e.can_download !== \"boolean\") {\n throw new Error(`Entry ${i}: can_view and can_download must be booleans.`);\n }\n return {\n item_id: e.item_id,\n item_type: itemType,\n can_view: e.can_view,\n can_download: e.can_download,\n };\n });\n }\n\n if (opts.item) {\n const itemType = ITEM_TYPES[String(opts.type ?? \"\")];\n if (!itemType) {\n throw new Error(\n \"Pass --type document or --type folder together with --item.\",\n );\n }\n return [\n {\n item_id: opts.item,\n item_type: itemType,\n can_view: onOff(opts.view, \"--view\", true),\n can_download: onOff(opts.download, \"--download\", false),\n },\n ];\n }\n\n throw new Error(\n \"Pass --file <path> (JSON array) or --item <id> --type <document|folder> [--view on|off] [--download on|off].\",\n );\n}\n","import chalk from \"chalk\";\nimport { Command } from \"commander\";\n\nimport { ApiError, NetworkError, api } from \"../client.js\";\nimport { getApiUrl, getToken, getTokenSource } from \"../config.js\";\nimport { ExitCode } from \"../exit.js\";\nimport { emit } from \"../output.js\";\nimport { getRuntime } from \"../runtime.js\";\n\ninterface Check {\n name: string;\n ok: boolean;\n detail: string;\n hint?: string;\n}\n\nexport function registerDoctorCommand(program: Command): void {\n program\n .command(\"doctor\")\n .description(\n \"Run health checks against the CLI config + Papermark API. Returns a `checks` array (JSON) and a non-zero exit if anything fails — useful as a CI preflight before running real commands.\",\n )\n .action(async () => {\n const checks: Check[] = [];\n\n // 1) Auth present\n const token = getToken();\n checks.push({\n name: \"auth.present\",\n ok: Boolean(token),\n detail: token\n ? `token found (source: ${getTokenSource()})`\n : \"no token configured\",\n hint: token ? undefined : \"Run `papermark login` or set PAPERMARK_TOKEN.\",\n });\n\n // 2) API URL configured\n const apiUrl = getApiUrl();\n checks.push({\n name: \"config.api_url\",\n ok: Boolean(apiUrl),\n detail: apiUrl,\n });\n\n // 3) API reachable + token valid — one request covers both, but split\n // into separate checks so callers can distinguish \"the server is down\"\n // from \"the server is up but my token is wrong\". Reachability cares\n // only that we got *some* HTTP response; auth.valid is the gate on\n // whether that response was a non-4xx-auth one.\n if (token) {\n try {\n await api.listDocuments({ limit: 1 });\n checks.push({\n name: \"api.reachable\",\n ok: true,\n detail: `GET /v1/documents?limit=1 → 200 at ${apiUrl}`,\n });\n checks.push({\n name: \"api.auth\",\n ok: true,\n detail: \"token accepted\",\n });\n } catch (err) {\n if (err instanceof NetworkError) {\n checks.push({\n name: \"network.api\",\n ok: false,\n detail: err.message,\n hint: \"Check your internet connection and the configured api-url.\",\n });\n } else if (err instanceof ApiError) {\n const authIssue = err.status === 401 || err.status === 403;\n // The server responded — that's reachability, regardless of\n // what status it returned.\n checks.push({\n name: \"api.reachable\",\n ok: true,\n detail: `HTTP ${err.status} ${err.code}: ${err.message}`,\n });\n checks.push({\n name: \"api.auth\",\n ok: !authIssue,\n detail: authIssue\n ? `Token rejected: HTTP ${err.status} ${err.code}`\n : `non-auth API error: HTTP ${err.status} ${err.code}`,\n hint: authIssue\n ? \"Run `papermark login` to refresh.\"\n : undefined,\n });\n } else {\n checks.push({\n name: \"api.reachable\",\n ok: false,\n detail: err instanceof Error ? err.message : String(err),\n });\n }\n }\n } else {\n checks.push({\n name: \"api.reachable\",\n ok: false,\n detail: \"skipped (no token)\",\n });\n }\n\n const allOk = checks.every((c) => c.ok);\n\n emit({ ok: allOk, checks }, () => {\n const lines = checks.map((c) => {\n const glyph = c.ok ? chalk.green(\"✓\") : chalk.red(\"✗\");\n const hint = c.hint ? chalk.dim(`\\n Hint: ${c.hint}`) : \"\";\n return `${glyph} ${chalk.bold(c.name)} ${chalk.dim(c.detail)}${hint}`;\n });\n const footer = allOk\n ? chalk.green(\"\\nAll checks passed.\")\n : chalk.red(\"\\nOne or more checks failed.\");\n return lines.join(\"\\n\") + footer;\n });\n\n if (!allOk) {\n // Don't use die() — we've already printed the payload. Just exit with\n // the right code so CI scripts can branch on it. Network failures\n // win over auth/API since DNS/connectivity issues are the most\n // useful signal for retry logic.\n const anyNetworkFailure = checks.some(\n (c) => !c.ok && c.name.startsWith(\"network\"),\n );\n const anyAuthFailure = checks.some(\n (c) =>\n !c.ok && (c.name.startsWith(\"auth\") || c.name === \"api.auth\"),\n );\n process.exit(\n anyNetworkFailure\n ? ExitCode.NetworkError\n : anyAuthFailure\n ? ExitCode.AuthError\n : ExitCode.ApiError,\n );\n }\n });\n}\n\n// Tiny guard to quiet an unused-import warning in runtime when tree-shaking\n// skips the helper. (Referenced for documentation only.)\nexport const _internal = { getRuntime };\n","import { createReadStream } from \"node:fs\";\nimport { stat } from \"node:fs/promises\";\nimport { basename } from \"node:path\";\nimport { Readable } from \"node:stream\";\n\nimport chalk from \"chalk\";\nimport { Command } from \"commander\";\nimport { lookup as lookupMimeType } from \"mime-types\";\nimport ora from \"ora\";\n\nimport { api } from \"../client.js\";\nimport { die, emit, json, sanitizeForTerminal, table } from \"../output.js\";\nimport { setRuntime } from \"../runtime.js\";\n\nexport function registerDocumentsCommands(program: Command): void {\n const docs = program\n .command(\"documents\")\n .alias(\"doc\")\n .description(\"Manage documents\");\n\n docs\n .command(\"list\")\n .description(\"List documents\")\n .option(\"-l, --limit <n>\", \"max results (1-100)\", \"25\")\n .option(\"-c, --cursor <id>\", \"pagination cursor\")\n .option(\"--json\", \"output raw JSON (same as --json on the root command)\")\n .action(async (opts: { limit?: string; cursor?: string; json?: boolean }) => {\n if (opts.json) setRuntime({ json: true });\n try {\n const res = await api.listDocuments({\n limit: opts.limit ? Number(opts.limit) : undefined,\n cursor: opts.cursor,\n });\n emit(res, () => {\n const rows = res.data.map((d) => ({\n id: d.id,\n name: truncate(d.name, 40),\n type: d.type ?? \"\",\n pages: d.num_pages?.toString() ?? \"\",\n created: d.created.slice(0, 10),\n }));\n const out = table(rows, [\"id\", \"name\", \"type\", \"pages\", \"created\"]);\n return res.next_cursor\n ? out + chalk.dim(`\\n\\nMore results: --cursor ${res.next_cursor}`)\n : out;\n });\n } catch (err) {\n die(err);\n }\n });\n\n docs\n .command(\"get <id>\")\n .description(\"Fetch one document\")\n .action(async (id: string) => {\n try {\n const doc = await api.getDocument(id);\n emit(doc, () => json(doc));\n } catch (err) {\n die(err);\n }\n });\n\n docs\n .command(\"search <query>\")\n .description(\"Search documents by name\")\n .option(\"-l, --limit <n>\", \"max results (1-100)\", \"25\")\n .option(\"--json\", \"output raw JSON (same as --json on the root command)\")\n .action(async (query: string, opts: { limit?: string; json?: boolean }) => {\n if (opts.json) setRuntime({ json: true });\n try {\n const res = await api.searchDocuments(\n query,\n opts.limit ? Number(opts.limit) : undefined,\n );\n emit(res, () => {\n const rows = res.data.map((d) => ({\n id: d.id,\n name: truncate(d.name, 40),\n type: d.type ?? \"\",\n created: d.created.slice(0, 10),\n }));\n return table(rows, [\"id\", \"name\", \"type\", \"created\"]);\n });\n } catch (err) {\n die(err);\n }\n });\n\n docs\n .command(\"update <id>\")\n .description(\"Rename a document or move it to a different team-library folder\")\n .option(\"-n, --name <name>\", \"new document name\")\n .option(\"--folder-id <id>\", \"move into folder id (use empty string for root)\")\n .action(\n async (id: string, opts: { name?: string; folderId?: string }) => {\n try {\n const body: Parameters<typeof api.updateDocument>[1] = {};\n if (opts.name !== undefined) body.name = opts.name;\n if (opts.folderId !== undefined) {\n body.folder_id = opts.folderId === \"\" ? null : opts.folderId;\n }\n if (Object.keys(body).length === 0) {\n throw new Error(\n \"Pass at least one of --name or --folder-id to update.\",\n );\n }\n const doc = await api.updateDocument(id, body);\n emit(\n doc,\n () =>\n chalk.green(\"✓\") +\n ` Document updated: ${chalk.bold(doc.id)}\\n` +\n json(doc),\n );\n } catch (err) {\n die(err);\n }\n },\n );\n\n docs\n .command(\"delete <id>\")\n .description(\"Delete a document\")\n .action(async (id: string) => {\n try {\n const deleted = await api.deleteDocument(id);\n emit(\n deleted,\n () => chalk.green(\"✓\") + ` Document ${id} deleted.`,\n );\n } catch (err) {\n die(err);\n }\n });\n\n docs\n .command(\"upload <file>\")\n .description(\"Upload a local file and create a document\")\n .option(\"-n, --name <name>\", \"override document name (default: filename)\")\n .option(\"--link\", \"also create a default share link for this document\")\n .option(\"--folder-id <id>\", \"place in folder by id (create folders via `papermark folders create`)\")\n .action(\n async (\n filePath: string,\n opts: { name?: string; link?: boolean; folderId?: string },\n ) => {\n const spinner = ora();\n try {\n const stats = await stat(filePath);\n if (!stats.isFile()) throw new Error(`${filePath} is not a file.`);\n const fileName = opts.name ?? basename(filePath);\n const contentType =\n lookupMimeType(filePath) || \"application/octet-stream\";\n\n spinner.start(\"Requesting upload URL\");\n const upload = await api.uploadUrl({\n file_name: fileName,\n content_type: contentType,\n content_length: stats.size,\n });\n spinner.succeed(\"Got presigned URL\");\n\n spinner.start(`Uploading ${humanSize(stats.size)}`);\n // Stream the file directly to S3 instead of buffering in memory —\n // dataroom PDFs can easily be hundreds of MB. fetch needs the\n // explicit Content-Length so the request doesn't fall back to\n // chunked transfer-encoding (which presigned PUT URLs reject),\n // and `duplex: \"half\"` is required by undici for any streamed\n // request body.\n const fileStream = Readable.toWeb(createReadStream(filePath));\n const putRes = await fetch(upload.upload_url, {\n method: \"PUT\",\n headers: {\n ...upload.required_headers,\n \"Content-Length\": String(stats.size),\n },\n body: fileStream as unknown as BodyInit,\n duplex: \"half\",\n } as RequestInit & { duplex: \"half\" });\n if (!putRes.ok) {\n const errText = await putRes.text().catch(() => \"\");\n throw new Error(\n `Upload failed: HTTP ${putRes.status} ${putRes.statusText}${\n errText ? \"\\n\" + errText.slice(0, 500) : \"\"\n }`,\n );\n }\n spinner.succeed(\"Uploaded to storage\");\n\n spinner.start(\"Creating document\");\n const doc = await api.createDocument({\n name: fileName,\n upload_id: upload.upload_id,\n folder_id: opts.folderId,\n create_link: opts.link ?? false,\n });\n spinner.succeed(`Document created: ${chalk.bold(doc.id)}`);\n\n await finalizeDocumentCreation(doc, opts.link ?? false);\n } catch (err) {\n spinner.fail();\n die(err);\n }\n },\n );\n\n docs\n .command(\"create-link <url>\")\n .description(\n \"Create a document that points to an external URL (no file upload)\",\n )\n .requiredOption(\"-n, --name <name>\", \"document name\")\n .option(\"--link\", \"also create a default share link for this document\")\n .option(\"--folder-id <id>\", \"place in folder by id\")\n .action(\n async (\n url: string,\n opts: { name: string; link?: boolean; folderId?: string },\n ) => {\n try {\n const doc = await api.createDocument({\n name: opts.name,\n type: \"link\",\n external_url: url,\n folder_id: opts.folderId,\n create_link: opts.link ?? false,\n });\n await finalizeDocumentCreation(doc, opts.link ?? false);\n } catch (err) {\n die(err);\n }\n },\n );\n\n docs\n .command(\"create-notion <url>\")\n .description(\n \"Create a document from a public Notion page URL (no file upload)\",\n )\n .requiredOption(\"-n, --name <name>\", \"document name\")\n .option(\"--link\", \"also create a default share link for this document\")\n .option(\"--folder-id <id>\", \"place in folder by id\")\n .action(\n async (\n url: string,\n opts: { name: string; link?: boolean; folderId?: string },\n ) => {\n try {\n const doc = await api.createDocument({\n name: opts.name,\n type: \"notion\",\n external_url: url,\n folder_id: opts.folderId,\n create_link: opts.link ?? false,\n });\n await finalizeDocumentCreation(doc, opts.link ?? false);\n } catch (err) {\n die(err);\n }\n },\n );\n\n // ─── Versions ────────────────────────────────────────────────────────\n const versions = docs\n .command(\"versions\")\n .description(\"Manage document versions\");\n\n versions\n .command(\"list <id>\")\n .description(\"List versions of a document, primary first\")\n .option(\"--json\", \"output raw JSON\")\n .action(async (id: string, opts: { json?: boolean }) => {\n if (opts.json) setRuntime({ json: true });\n try {\n const res = await api.listDocumentVersions(id);\n emit(res, () => {\n const rows = res.data.map((v) => ({\n id: v.id,\n version: String(v.version_number),\n primary: v.is_primary ? \"★\" : \"\",\n type: v.type ?? \"\",\n pages: v.num_pages?.toString() ?? \"\",\n size: v.file_size !== null ? humanSize(v.file_size) : \"\",\n created: v.created.slice(0, 10),\n }));\n return table(rows, [\n \"id\",\n \"version\",\n \"primary\",\n \"type\",\n \"pages\",\n \"size\",\n \"created\",\n ]);\n });\n } catch (err) {\n die(err);\n }\n });\n\n versions\n .command(\"get <id> <vid>\")\n .description(\"Fetch a single document version\")\n .action(async (id: string, vid: string) => {\n try {\n const v = await api.getDocumentVersion(id, vid);\n emit(v, () => json(v));\n } catch (err) {\n die(err);\n }\n });\n\n versions\n .command(\"add <id> <file>\")\n .description(\"Upload a new version of an existing document\")\n .action(async (id: string, filePath: string) => {\n const spinner = ora();\n try {\n const stats = await stat(filePath);\n if (!stats.isFile()) throw new Error(`${filePath} is not a file.`);\n const fileName = basename(filePath);\n const contentType =\n lookupMimeType(filePath) || \"application/octet-stream\";\n\n spinner.start(\"Requesting upload URL\");\n const upload = await api.uploadUrl({\n file_name: fileName,\n content_type: contentType,\n content_length: stats.size,\n });\n spinner.succeed(\"Got presigned URL\");\n\n spinner.start(`Uploading ${humanSize(stats.size)}`);\n const fileStream = Readable.toWeb(createReadStream(filePath));\n const putRes = await fetch(upload.upload_url, {\n method: \"PUT\",\n headers: {\n ...upload.required_headers,\n \"Content-Length\": String(stats.size),\n },\n body: fileStream as unknown as BodyInit,\n duplex: \"half\",\n } as RequestInit & { duplex: \"half\" });\n if (!putRes.ok) {\n const errText = await putRes.text().catch(() => \"\");\n throw new Error(\n `Upload failed: HTTP ${putRes.status} ${putRes.statusText}${\n errText ? \"\\n\" + errText.slice(0, 500) : \"\"\n }`,\n );\n }\n spinner.succeed(\"Uploaded to storage\");\n\n spinner.start(\"Adding version\");\n const v = await api.addDocumentVersion(id, { upload_id: upload.upload_id });\n spinner.succeed(`Version ${v.version_number} added: ${chalk.bold(v.id)}`);\n\n emit(v, () => json(v));\n } catch (err) {\n spinner.fail();\n die(err);\n }\n });\n\n versions\n .command(\"add-link <id> <url>\")\n .description(\"Repoint a link document at a new URL (adds a new version)\")\n .action(async (id: string, url: string) => {\n try {\n const v = await api.addDocumentVersion(id, { external_url: url });\n emit(\n v,\n () =>\n chalk.green(\"✓\") +\n ` Version ${v.version_number} added: ${chalk.bold(v.id)}\\n` +\n json(v),\n );\n } catch (err) {\n die(err);\n }\n });\n\n versions\n .command(\"add-notion <id> <url>\")\n .description(\n \"Repoint a notion document at a new Notion page URL (adds a new version)\",\n )\n .action(async (id: string, url: string) => {\n try {\n const v = await api.addDocumentVersion(id, { external_url: url });\n emit(\n v,\n () =>\n chalk.green(\"✓\") +\n ` Version ${v.version_number} added: ${chalk.bold(v.id)}\\n` +\n json(v),\n );\n } catch (err) {\n die(err);\n }\n });\n\n versions\n .command(\"promote <id> <vid>\")\n .description(\"Promote a version to primary\")\n .action(async (id: string, vid: string) => {\n try {\n const v = await api.promoteDocumentVersion(id, vid);\n emit(\n v,\n () =>\n chalk.green(\"✓\") +\n ` Version ${v.version_number} promoted to primary.\\n` +\n json(v),\n );\n } catch (err) {\n die(err);\n }\n });\n}\n\n// Shared tail for the document-creation commands (upload / create-link /\n// create-notion). When a share link was requested, the document already\n// exists, so a list-links failure is surfaced as a warning rather than failing\n// the command, and a single combined payload keeps the JSON envelope well-formed.\nasync function finalizeDocumentCreation(\n doc: Awaited<ReturnType<typeof api.createDocument>>,\n wantLink: boolean,\n): Promise<void> {\n let link: Awaited<ReturnType<typeof api.listLinks>>[\"data\"][number] | null =\n null;\n let linkWarning: string | null = null;\n if (wantLink) {\n try {\n const links = await api.listLinks({ document_id: doc.id, limit: 1 });\n link = links.data[0] ?? null;\n if (!link) {\n linkWarning =\n \"--link was set but no link was returned. Try `papermark links list --document \" +\n doc.id +\n \"`.\";\n }\n } catch (warnErr) {\n linkWarning = `Document created, but listing the share link failed: ${\n warnErr instanceof Error ? warnErr.message : String(warnErr)\n }`;\n }\n if (linkWarning) {\n process.stderr.write(chalk.yellow(\"! \") + linkWarning + \"\\n\");\n }\n }\n\n emit({ document: doc, link }, () => {\n const blocks = [json(doc)];\n if (link) {\n blocks.push(chalk.green(\"✓\") + \" Share link: \" + chalk.bold(link.url));\n }\n return blocks.join(\"\\n\");\n });\n}\n\nfunction truncate(s: string, n: number): string {\n const clean = sanitizeForTerminal(s);\n return clean.length > n ? clean.slice(0, n - 1) + \"…\" : clean;\n}\n\nfunction humanSize(bytes: number): string {\n const units = [\"B\", \"KB\", \"MB\", \"GB\"];\n let n = bytes;\n let i = 0;\n while (n >= 1024 && i < units.length - 1) {\n n /= 1024;\n i++;\n }\n return `${n.toFixed(i === 0 ? 0 : 1)}${units[i]}`;\n}\n","import chalk from \"chalk\";\nimport { Command } from \"commander\";\n\nimport { api } from \"../client.js\";\nimport { die, emit, json, sanitizeForTerminal, table } from \"../output.js\";\nimport { setRuntime } from \"../runtime.js\";\n\nexport function registerFoldersCommands(program: Command): void {\n const folders = program\n .command(\"folders\")\n .description(\"Manage team-library folders\");\n\n folders\n .command(\"list\")\n .description(\"List folders in the team library\")\n .option(\n \"--parent <id>\",\n \"restrict to direct children of this folder (use 'root' for top-level)\",\n )\n .option(\"-l, --limit <n>\", \"max results (1-100)\", \"50\")\n .option(\"-c, --cursor <id>\", \"pagination cursor\")\n .option(\"--json\", \"output raw JSON\")\n .action(\n async (opts: {\n parent?: string;\n limit?: string;\n cursor?: string;\n json?: boolean;\n }) => {\n if (opts.json) setRuntime({ json: true });\n try {\n const res = await api.listFolders({\n limit: opts.limit ? Number(opts.limit) : undefined,\n cursor: opts.cursor,\n parent_id: opts.parent,\n });\n emit(res, () => {\n const rows = res.data.map((f) => ({\n id: f.id,\n name: truncate(f.name, 30),\n path: truncate(f.path, 40),\n docs: String(f.document_count),\n children: String(f.child_folder_count),\n }));\n const out = table(rows, [\"id\", \"name\", \"path\", \"docs\", \"children\"]);\n return res.next_cursor\n ? out + chalk.dim(`\\n\\nMore results: --cursor ${res.next_cursor}`)\n : out;\n });\n } catch (err) {\n die(err);\n }\n },\n );\n\n folders\n .command(\"create\")\n .description(\"Create a folder in the team library\")\n .requiredOption(\"-n, --name <name>\", \"folder name\")\n .option(\"--parent <id>\", \"parent folder id (omit for library root)\")\n .option(\"--icon <icon>\", \"icon name (e.g. folder, briefcase, lock)\")\n .option(\"--color <color>\", \"color token (gray, red, orange, yellow, green, blue, black)\")\n .action(\n async (opts: {\n name: string;\n parent?: string;\n icon?: string;\n color?: string;\n }) => {\n try {\n const f = await api.createFolder({\n name: opts.name,\n parent_id: opts.parent ?? null,\n icon: opts.icon as never,\n color: opts.color as never,\n });\n emit(\n f,\n () =>\n chalk.green(\"✓\") +\n ` Folder created: ${chalk.bold(f.id)}\\n` +\n json(f),\n );\n } catch (err) {\n die(err);\n }\n },\n );\n\n folders\n .command(\"get <id>\")\n .description(\"Fetch one folder\")\n .action(async (id: string) => {\n try {\n const f = await api.getFolder(id);\n emit(f, () => json(f));\n } catch (err) {\n die(err);\n }\n });\n\n folders\n .command(\"update <id>\")\n .description(\"Update a folder\")\n .option(\"-n, --name <name>\")\n .option(\"--icon <icon>\", \"icon name (empty string to clear)\")\n .option(\"--color <color>\", \"color token (empty string to clear)\")\n .action(\n async (\n id: string,\n opts: { name?: string; icon?: string; color?: string },\n ) => {\n try {\n const body: Parameters<typeof api.updateFolder>[1] = {};\n if (opts.name !== undefined) body.name = opts.name;\n if (opts.icon !== undefined)\n body.icon = (opts.icon === \"\" ? null : opts.icon) as never;\n if (opts.color !== undefined)\n body.color = (opts.color === \"\" ? null : opts.color) as never;\n if (Object.keys(body).length === 0) {\n throw new Error(\n \"Pass at least one of --name, --icon, --color to update.\",\n );\n }\n const f = await api.updateFolder(id, body);\n emit(\n f,\n () =>\n chalk.green(\"✓\") +\n ` Folder updated: ${chalk.bold(f.id)}\\n` +\n json(f),\n );\n } catch (err) {\n die(err);\n }\n },\n );\n\n folders\n .command(\"delete <id>\")\n .description(\"Delete a folder\")\n .option(\n \"--cascade\",\n \"also delete nested folders and every document inside them\",\n false,\n )\n .action(async (id: string, opts: { cascade?: boolean }) => {\n try {\n const deleted = await api.deleteFolder(id, { cascade: opts.cascade });\n emit(\n deleted,\n () => chalk.green(\"✓\") + ` Folder ${id} deleted.`,\n );\n } catch (err) {\n die(err);\n }\n });\n\n folders\n .command(\"move <id>\")\n .description(\"Move a folder under a different parent\")\n .option(\n \"--parent <id>\",\n \"target parent folder id; pass empty string to move to the library root\",\n )\n .action(async (id: string, opts: { parent?: string }) => {\n try {\n if (opts.parent === undefined) {\n throw new Error(\n \"Pass --parent <id> (use empty string to move to the root).\",\n );\n }\n const parent_id = opts.parent === \"\" ? null : opts.parent;\n const f = await api.moveFolder(id, { parent_id });\n emit(\n f,\n () =>\n chalk.green(\"✓\") +\n ` Folder moved. New path: ${chalk.bold(f.path)}\\n` +\n json(f),\n );\n } catch (err) {\n die(err);\n }\n });\n}\n\nfunction truncate(s: string, n: number): string {\n const clean = sanitizeForTerminal(s);\n return clean.length > n ? clean.slice(0, n - 1) + \"…\" : clean;\n}\n","import chalk from \"chalk\";\nimport { Command } from \"commander\";\n\nimport {\n api,\n WatermarkConfig,\n WatermarkPosition,\n WatermarkRotation,\n} from \"../client.js\";\nimport { die, emit, json, sanitizeForTerminal, table } from \"../output.js\";\nimport { parsePermissionEntries } from \"./permissions-input.js\";\nimport { setRuntime } from \"../runtime.js\";\n\nconst WATERMARK_POSITIONS: readonly WatermarkPosition[] = [\n \"top-left\",\n \"top-center\",\n \"top-right\",\n \"middle-left\",\n \"middle-center\",\n \"middle-right\",\n \"bottom-left\",\n \"bottom-center\",\n \"bottom-right\",\n];\nconst WATERMARK_ROTATIONS: readonly WatermarkRotation[] = [0, 30, 45, 90, 180];\n\ninterface WatermarkOpts {\n watermarkText?: string;\n watermarkTiled?: string;\n watermarkPosition?: string;\n watermarkRotation?: string;\n watermarkColor?: string;\n watermarkFontSize?: string;\n watermarkOpacity?: string;\n}\n\n// Parse the seven --watermark-* flags into a public WatermarkConfig, or\n// return undefined when none were passed. Throws on partial/invalid input.\nfunction parseWatermarkConfig(opts: WatermarkOpts): WatermarkConfig | undefined {\n const fields = {\n text: opts.watermarkText,\n is_tiled: opts.watermarkTiled,\n position: opts.watermarkPosition,\n rotation: opts.watermarkRotation,\n color: opts.watermarkColor,\n font_size: opts.watermarkFontSize,\n opacity: opts.watermarkOpacity,\n };\n const flagNames: Record<keyof typeof fields, string> = {\n text: \"--watermark-text\",\n is_tiled: \"--watermark-tiled\",\n position: \"--watermark-position\",\n rotation: \"--watermark-rotation\",\n color: \"--watermark-color\",\n font_size: \"--watermark-font-size\",\n opacity: \"--watermark-opacity\",\n };\n const provided = Object.entries(fields).filter(([, v]) => v !== undefined);\n if (provided.length === 0) return undefined;\n\n const missing = Object.entries(fields)\n .filter(([, v]) => v === undefined)\n .map(([k]) => flagNames[k as keyof typeof fields]);\n if (missing.length > 0) {\n throw new Error(\n `Watermark config is partial. Missing: ${missing.join(\", \")}.`,\n );\n }\n\n const tiled =\n fields.is_tiled!.toLowerCase() === \"true\" ||\n fields.is_tiled!.toLowerCase() === \"on\";\n const tiledOff =\n fields.is_tiled!.toLowerCase() === \"false\" ||\n fields.is_tiled!.toLowerCase() === \"off\";\n if (!tiled && !tiledOff) {\n throw new Error(\n `Invalid --watermark-tiled value ${JSON.stringify(fields.is_tiled)} (expected on/off).`,\n );\n }\n\n if (!WATERMARK_POSITIONS.includes(fields.position as WatermarkPosition)) {\n throw new Error(\n `Invalid --watermark-position ${JSON.stringify(fields.position)}. Expected one of: ${WATERMARK_POSITIONS.join(\", \")}.`,\n );\n }\n const rotation = Number(fields.rotation);\n if (\n !Number.isFinite(rotation) ||\n !WATERMARK_ROTATIONS.includes(rotation as WatermarkRotation)\n ) {\n throw new Error(\n `Invalid --watermark-rotation ${JSON.stringify(fields.rotation)}. Expected one of: ${WATERMARK_ROTATIONS.join(\", \")}.`,\n );\n }\n if (!/^#([0-9A-Fa-f]{3}){1,2}$/.test(fields.color!)) {\n throw new Error(\n `Invalid --watermark-color ${JSON.stringify(fields.color)}. Expected #RGB or #RRGGBB.`,\n );\n }\n const fontSize = Number(fields.font_size);\n if (!Number.isInteger(fontSize) || fontSize < 1 || fontSize > 96) {\n throw new Error(\n `Invalid --watermark-font-size ${JSON.stringify(fields.font_size)}. Expected integer 1-96.`,\n );\n }\n const opacity = Number(fields.opacity);\n if (!Number.isFinite(opacity) || opacity < 0 || opacity > 1) {\n throw new Error(\n `Invalid --watermark-opacity ${JSON.stringify(fields.opacity)}. Expected 0-1.`,\n );\n }\n\n return {\n text: fields.text!,\n is_tiled: tiled,\n position: fields.position as WatermarkPosition,\n rotation: rotation as WatermarkRotation,\n color: fields.color!,\n font_size: fontSize,\n opacity,\n };\n}\n\nfunction addWatermarkOptions(cmd: Command): Command {\n return cmd\n .option(\n \"--watermark-text <text>\",\n \"watermark text; tokens {{email}} {{date}} {{time}} {{link}} {{ipAddress}} interpolated per view\",\n )\n .option(\"--watermark-tiled <on|off>\", \"tile the watermark across the page\")\n .option(\n \"--watermark-position <pos>\",\n `anchor position (${WATERMARK_POSITIONS.join(\"|\")})`,\n )\n .option(\n \"--watermark-rotation <deg>\",\n `rotation in degrees (${WATERMARK_ROTATIONS.join(\"|\")})`,\n )\n .option(\"--watermark-color <hex>\", \"text color as #RGB or #RRGGBB\")\n .option(\"--watermark-font-size <n>\", \"font size 1-96\")\n .option(\"--watermark-opacity <n>\", \"opacity 0-1\");\n}\n\nexport function registerLinksCommands(program: Command): void {\n const links = program.command(\"links\").description(\"Manage share links\");\n\n links\n .command(\"list\")\n .description(\"List share links\")\n .option(\"-l, --limit <n>\", \"max results (1-100)\", \"25\")\n .option(\"-c, --cursor <id>\", \"pagination cursor\")\n .option(\"--document <id>\", \"filter by document id\")\n .option(\"--dataroom <id>\", \"filter by dataroom id\")\n .option(\"--group <gid>\", \"filter by dataroom group id (group links only)\")\n .option(\"--json\", \"output raw JSON (same as --json on the root command)\")\n .action(\n async (opts: {\n limit?: string;\n cursor?: string;\n document?: string;\n dataroom?: string;\n group?: string;\n json?: boolean;\n }) => {\n if (opts.json) setRuntime({ json: true });\n try {\n const res = await api.listLinks({\n limit: opts.limit ? Number(opts.limit) : undefined,\n cursor: opts.cursor,\n document_id: opts.document,\n dataroom_id: opts.dataroom,\n group_id: opts.group,\n });\n emit(res, () => {\n const rows = res.data.map((l) => ({\n id: l.id,\n name: truncate(l.name ?? \"\", 30),\n url: truncate(l.url, 45),\n password: l.is_password_protected ? \"yes\" : \"\",\n expires: l.expires_at ? l.expires_at.slice(0, 10) : \"\",\n }));\n const out = table(rows, [\"id\", \"name\", \"url\", \"password\", \"expires\"]);\n return res.next_cursor\n ? out + chalk.dim(`\\n\\nMore results: --cursor ${res.next_cursor}`)\n : out;\n });\n } catch (err) {\n die(err);\n }\n },\n );\n\n links\n .command(\"get <id>\")\n .description(\"Fetch one share link\")\n .action(async (id: string) => {\n try {\n const link = await api.getLink(id);\n emit(link, () => json(link));\n } catch (err) {\n die(err);\n }\n });\n\n addWatermarkOptions(\n links\n .command(\"create\")\n .description(\"Create a share link for a document or dataroom\")\n .option(\"--document <id>\", \"document id\")\n .option(\"--dataroom <id>\", \"dataroom id\")\n .option(\n \"--group <gid>\",\n \"scope to a dataroom group (dataroom links only; forces email protection)\",\n )\n .option(\"-n, --name <name>\", \"link name\")\n .option(\"--expires <iso-date>\", \"expiration date (ISO 8601)\")\n .option(\"--password <pw>\", \"require a password to view\")\n .option(\"--email-protected\", \"require email before viewing\", false)\n .option(\"--allow-download\", \"allow viewer to download the file\", false)\n .option(\n \"--confidential-view\",\n \"reveal only a narrow band of each page at a time; blurs the rest to prevent full-page screenshots\",\n false,\n )\n .option(\"--watermark\", \"enable watermark overlay (use with --watermark-*)\", false),\n )\n .action(\n async (opts: {\n document?: string;\n dataroom?: string;\n group?: string;\n name?: string;\n expires?: string;\n password?: string;\n emailProtected?: boolean;\n allowDownload?: boolean;\n confidentialView?: boolean;\n watermark?: boolean;\n } & WatermarkOpts) => {\n try {\n if (!opts.document && !opts.dataroom) {\n throw new Error(\"Either --document <id> or --dataroom <id> is required.\");\n }\n if (opts.group && !opts.dataroom) {\n throw new Error(\"--group requires --dataroom <id>.\");\n }\n const watermarkConfig = parseWatermarkConfig(opts);\n // Implicit enable: passing any --watermark-* flag turns the watermark\n // on without needing --watermark on top.\n const enableWatermark = opts.watermark || watermarkConfig !== undefined;\n const link = await api.createLink({\n document_id: opts.document,\n dataroom_id: opts.dataroom,\n audience_type: opts.group ? \"group\" : undefined,\n group_id: opts.group,\n name: opts.name,\n expires_at: opts.expires,\n password: opts.password,\n email_protected: opts.emailProtected,\n allow_download: opts.allowDownload,\n enable_confidential_view: opts.confidentialView,\n enable_watermark: enableWatermark || undefined,\n watermark_config: watermarkConfig,\n });\n emit(\n link,\n () =>\n chalk.green(\"✓\") +\n \" Link created\\n\" +\n chalk.bold(\"URL: \") +\n link.url +\n \"\\n\" +\n json(link),\n );\n } catch (err) {\n die(err);\n }\n },\n );\n\n addWatermarkOptions(\n links\n .command(\"update <id>\")\n .description(\"Update an existing share link\")\n .option(\n \"--audience <general|group>\",\n \"switch the link's audience (group links need --group or an existing group)\",\n )\n .option(\n \"--group <gid>\",\n \"dataroom group id (with --audience group, or alone to swap the group of a group link)\",\n )\n .option(\"-n, --name <name>\")\n .option(\"--expires <iso-date>\", \"expiration date (ISO 8601), or empty string to clear\")\n .option(\"--password <pw>\", \"set a password (empty string to clear)\")\n .option(\"--email-protected <on|off>\")\n .option(\"--email-authenticated <on|off>\")\n .option(\"--allow-download <on|off>\")\n .option(\n \"--allow-list <items>\",\n \"comma-separated email/domain allow list (e.g. '@acme.com,bob@x.com')\",\n )\n .option(\"--deny-list <items>\", \"comma-separated email/domain deny list\")\n .option(\"--watermark <on|off>\", \"enable watermark overlay\")\n .option(\"--watermark-clear\", \"clear the existing watermark config\", false)\n .option(\"--screenshot-protection <on|off>\", \"blur on screenshot\")\n .option(\n \"--confidential-view <on|off>\",\n \"reveal only a narrow band of each page at a time; blurs the rest to prevent full-page screenshots\",\n ),\n )\n .action(\n async (\n id: string,\n opts: {\n audience?: string;\n group?: string;\n name?: string;\n expires?: string;\n password?: string;\n emailProtected?: string;\n emailAuthenticated?: string;\n allowDownload?: string;\n allowList?: string;\n denyList?: string;\n watermark?: string;\n watermarkClear?: boolean;\n screenshotProtection?: string;\n confidentialView?: string;\n } & WatermarkOpts,\n ) => {\n try {\n const tri = (\n v: string | undefined,\n flag: string,\n ): boolean | undefined => {\n if (v === undefined) return undefined;\n const norm = v.toLowerCase();\n if (norm === \"on\") return true;\n if (norm === \"off\") return false;\n throw new Error(\n `Invalid value for ${flag}: ${JSON.stringify(v)} (expected \"on\" or \"off\").`,\n );\n };\n const list = (v: string | undefined): string[] | undefined =>\n v === undefined\n ? undefined\n : v === \"\"\n ? []\n : v.split(\",\").map((s) => s.trim()).filter(Boolean);\n\n const body: Parameters<typeof api.updateLink>[1] = {};\n if (opts.audience !== undefined) {\n const norm = opts.audience.toLowerCase();\n if (norm !== \"general\" && norm !== \"group\") {\n throw new Error(\n `Invalid value for --audience: ${JSON.stringify(opts.audience)} (expected \"general\" or \"group\").`,\n );\n }\n body.audience_type = norm;\n }\n if (opts.group !== undefined) body.group_id = opts.group;\n if (opts.name !== undefined) body.name = opts.name;\n if (opts.expires !== undefined)\n body.expires_at = opts.expires === \"\" ? null : opts.expires;\n if (opts.password !== undefined)\n body.password = opts.password === \"\" ? null : opts.password;\n const ep = tri(opts.emailProtected, \"--email-protected\");\n if (ep !== undefined) body.email_protected = ep;\n const ea = tri(opts.emailAuthenticated, \"--email-authenticated\");\n if (ea !== undefined) body.email_authenticated = ea;\n const ad = tri(opts.allowDownload, \"--allow-download\");\n if (ad !== undefined) body.allow_download = ad;\n const al = list(opts.allowList);\n if (al !== undefined) body.allow_list = al;\n const dl = list(opts.denyList);\n if (dl !== undefined) body.deny_list = dl;\n const wm = tri(opts.watermark, \"--watermark\");\n if (wm !== undefined) body.enable_watermark = wm;\n const watermarkConfig = parseWatermarkConfig(opts);\n if (opts.watermarkClear && watermarkConfig !== undefined) {\n throw new Error(\n \"Pass either --watermark-clear or --watermark-* flags, not both.\",\n );\n }\n if (opts.watermarkClear) {\n body.watermark_config = null;\n } else if (watermarkConfig !== undefined) {\n body.watermark_config = watermarkConfig;\n // Implicit enable on update too: passing a config without an\n // explicit --watermark on|off turns the toggle on. Mirrors create.\n if (wm === undefined) body.enable_watermark = true;\n }\n const sp = tri(opts.screenshotProtection, \"--screenshot-protection\");\n if (sp !== undefined) body.enable_screenshot_protection = sp;\n const cv = tri(opts.confidentialView, \"--confidential-view\");\n if (cv !== undefined) body.enable_confidential_view = cv;\n\n if (Object.keys(body).length === 0) {\n throw new Error(\n \"Pass at least one field to update (e.g. --name, --expires, --password).\",\n );\n }\n const link = await api.updateLink(id, body);\n emit(\n link,\n () =>\n chalk.green(\"✓\") + ` Link updated: ${chalk.bold(link.id)}\\n` +\n json(link),\n );\n } catch (err) {\n die(err);\n }\n },\n );\n\n links\n .command(\"delete <id>\")\n .description(\"Revoke a share link\")\n .action(async (id: string) => {\n try {\n const deleted = await api.deleteLink(id);\n emit(\n deleted,\n () => chalk.green(\"✓\") + ` Link ${id} revoked.`,\n );\n } catch (err) {\n die(err);\n }\n });\n\n // ─── Link permissions ────────────────────────────────────────────────\n const linkPermissions = links\n .command(\"permissions\")\n .description(\n \"Per-item file permissions for dataroom links (ignored on group-audience links — the group's permissions win)\",\n );\n\n linkPermissions\n .command(\"get <id>\")\n .description(\"List a dataroom link's per-item permission overrides\")\n .option(\"--json\", \"output raw JSON\")\n .action(async (id: string, opts: { json?: boolean }) => {\n if (opts.json) setRuntime({ json: true });\n try {\n const res = await api.getLinkPermissions(id);\n emit(res, () => {\n if (res.data.length === 0) {\n return chalk.dim(\n \"No per-link overrides — viewers see the full dataroom.\",\n );\n }\n const rows = res.data.map((p) => ({\n item_id: p.item_id,\n type: p.item_type === \"dataroom_document\" ? \"document\" : \"folder\",\n view: p.can_view ? \"yes\" : \"\",\n download: p.can_download ? \"yes\" : \"\",\n }));\n return table(rows, [\"item_id\", \"type\", \"view\", \"download\"]);\n });\n } catch (err) {\n die(err);\n }\n });\n\n linkPermissions\n .command(\"set <id>\")\n .description(\n \"Replace a dataroom link's per-item permissions (full replace: items not listed lose their override; --clear removes all overrides and hides every item). Item ids come from `datarooms documents` / `datarooms folders list`.\",\n )\n .option(\n \"--file <path>\",\n \"JSON array of { item_id, item_type, can_view, can_download }\",\n )\n .option(\"--item <itemId>\", \"single item id (use with --type/--view/--download)\")\n .option(\"--type <document|folder>\", \"item type for --item\")\n .option(\"--view <on|off>\", \"allow viewing (default on)\")\n .option(\"--download <on|off>\", \"allow downloading (default off)\")\n .option(\"--clear\", \"remove all overrides (hides every item on this link)\", false)\n .action(\n async (\n id: string,\n opts: {\n file?: string;\n item?: string;\n type?: string;\n view?: string;\n download?: string;\n clear?: boolean;\n },\n ) => {\n try {\n if (opts.clear && (opts.file || opts.item)) {\n throw new Error(\"Pass either --clear or permission input, not both.\");\n }\n const permissions = opts.clear ? [] : parsePermissionEntries(opts);\n const res = await api.setLinkPermissions(id, { permissions });\n emit(res, () => {\n if (res.data.length === 0) {\n return (\n chalk.green(\"✓\") +\n \" All overrides cleared — every item on this link is now hidden.\"\n );\n }\n return (\n chalk.green(\"✓\") +\n ` ${res.data.length} permission row(s) now effective:\\n` +\n table(\n res.data.map((p) => ({\n item_id: p.item_id,\n type:\n p.item_type === \"dataroom_document\" ? \"document\" : \"folder\",\n view: p.can_view ? \"yes\" : \"\",\n download: p.can_download ? \"yes\" : \"\",\n })),\n [\"item_id\", \"type\", \"view\", \"download\"],\n )\n );\n });\n } catch (err) {\n die(err);\n }\n },\n );\n}\n\nfunction truncate(s: string, n: number): string {\n const clean = sanitizeForTerminal(s);\n return clean.length > n ? clean.slice(0, n - 1) + \"…\" : clean;\n}\n","import chalk from \"chalk\";\nimport { Command } from \"commander\";\n\nimport { api } from \"../client.js\";\nimport { die, emit, sanitizeForTerminal, table } from \"../output.js\";\nimport { setRuntime } from \"../runtime.js\";\n\nexport function registerViewsCommands(program: Command): void {\n const views = program.command(\"views\").description(\"Read link view analytics\");\n\n views\n .command(\"list\")\n .description(\"List views for a share link\")\n .requiredOption(\"--link <id>\", \"link id\")\n .option(\"-l, --limit <n>\", \"max results (1-100)\", \"25\")\n .option(\"-c, --cursor <id>\", \"pagination cursor\")\n .option(\"--json\", \"output raw JSON (same as --json on the root command)\")\n .action(\n async (opts: { link: string; limit?: string; cursor?: string; json?: boolean }) => {\n if (opts.json) setRuntime({ json: true });\n try {\n const res = await api.listViews(opts.link, {\n limit: opts.limit ? Number(opts.limit) : undefined,\n cursor: opts.cursor,\n });\n emit(res, () => {\n const rows = res.data.map((v) => ({\n id: v.id,\n viewer: sanitizeForTerminal(v.viewer_email ?? \"\"),\n type: v.view_type ?? \"\",\n viewed: v.viewed_at.replace(\"T\", \" \").slice(0, 16),\n downloaded: v.downloaded_at ? v.downloaded_at.slice(0, 10) : \"\",\n }));\n const out = table(rows, [\"id\", \"viewer\", \"type\", \"viewed\", \"downloaded\"]);\n return res.next_cursor\n ? out + chalk.dim(`\\n\\nMore results: --cursor ${res.next_cursor}`)\n : out;\n });\n } catch (err) {\n die(err);\n }\n },\n );\n}\n","import chalk from \"chalk\";\nimport { Command } from \"commander\";\n\nimport { api } from \"../client.js\";\nimport { die, emit, json, sanitizeForTerminal, table } from \"../output.js\";\nimport { setRuntime } from \"../runtime.js\";\n\nexport function registerVisitorsCommands(program: Command): void {\n const visitors = program\n .command(\"visitors\")\n .description(\"Manage persistent visitors (Viewer rows)\");\n\n visitors\n .command(\"list\")\n .description(\"List visitors\")\n .option(\"-l, --limit <n>\", \"max results (1-100)\", \"25\")\n .option(\"-c, --cursor <id>\", \"pagination cursor\")\n .option(\"--email <email>\", \"exact email match (case-insensitive)\")\n .option(\"--dataroom <id>\", \"filter by dataroom id\")\n .option(\"--json\", \"output raw JSON\")\n .action(\n async (opts: {\n limit?: string;\n cursor?: string;\n email?: string;\n dataroom?: string;\n json?: boolean;\n }) => {\n if (opts.json) setRuntime({ json: true });\n try {\n const res = await api.listVisitors({\n limit: opts.limit ? Number(opts.limit) : undefined,\n cursor: opts.cursor,\n email: opts.email,\n dataroom_id: opts.dataroom,\n });\n emit(res, () => {\n const rows = res.data.map((v) => ({\n id: v.id,\n email: sanitizeForTerminal(v.email),\n verified: v.verified ? \"yes\" : \"\",\n views: String(v.total_views),\n last_view: v.last_viewed_at?.slice(0, 10) ?? \"\",\n }));\n const out = table(rows, [\"id\", \"email\", \"verified\", \"views\", \"last_view\"]);\n return res.next_cursor\n ? out + chalk.dim(`\\n\\nMore results: --cursor ${res.next_cursor}`)\n : out;\n });\n } catch (err) {\n die(err);\n }\n },\n );\n\n visitors\n .command(\"get <id>\")\n .description(\"Fetch one visitor\")\n .action(async (id: string) => {\n try {\n const v = await api.getVisitor(id);\n emit(v, () => json(v));\n } catch (err) {\n die(err);\n }\n });\n\n visitors\n .command(\"views <id>\")\n .description(\"List view events tied to a visitor\")\n .option(\"-l, --limit <n>\", \"max results (1-100)\", \"25\")\n .option(\"-c, --cursor <id>\", \"pagination cursor\")\n .option(\"--json\", \"output raw JSON\")\n .action(\n async (\n id: string,\n opts: { limit?: string; cursor?: string; json?: boolean },\n ) => {\n if (opts.json) setRuntime({ json: true });\n try {\n const res = await api.listVisitorViews(id, {\n limit: opts.limit ? Number(opts.limit) : undefined,\n cursor: opts.cursor,\n });\n emit(res, () => {\n const rows = res.data.map((v) => ({\n id: v.id,\n link: v.link_id,\n type: v.view_type,\n viewed: v.viewed_at.replace(\"T\", \" \").slice(0, 16),\n downloaded: v.downloaded_at ? v.downloaded_at.slice(0, 10) : \"\",\n }));\n const out = table(rows, [\"id\", \"link\", \"type\", \"viewed\", \"downloaded\"]);\n return res.next_cursor\n ? out + chalk.dim(`\\n\\nMore results: --cursor ${res.next_cursor}`)\n : out;\n });\n } catch (err) {\n die(err);\n }\n },\n );\n}\n"],"mappings":";;;AAAA,SAAS,WAAAA,gBAAe;;;ACAxB,OAAOC,YAAW;;;ACAlB,SAAS,oBAAoB;AAE7B,OAAO,UAAU;AASjB,IAAM,QAAQ,IAAI,KAAgB;AAAA,EAChC,aAAa;AAAA,EACb,gBAAgB;AAAA,EAChB,UAAU;AAAA,IACR,QAAQ;AAAA,EACV;AACF,CAAC;AAID,IAAI;AACJ,SAAS,sBAAwC;AAC/C,MAAI,oBAAoB,OAAW,QAAO;AAC1C,QAAM,OAAO,QAAQ,IAAI;AACzB,MAAI,CAAC,KAAM,QAAQ,kBAAkB;AACrC,MAAI;AACF,UAAM,SAAS,KAAK,MAAM,aAAa,MAAM,MAAM,CAAC;AACpD,QAAI,UAAU,OAAO,WAAW,UAAU;AACxC,aAAQ,kBAAkB;AAAA,QACxB,OAAO,OAAO,OAAO,UAAU,WAAW,OAAO,QAAQ;AAAA,QACzD,QACE,OAAO,OAAO,WAAW,WACrB,OAAO,SACP,OAAO,OAAO,YAAY,WACxB,OAAO,UACP;AAAA,MACV;AAAA,IACF;AAAA,EACF,SAAS,KAAK;AACZ,YAAQ,OAAO;AAAA,MACb,uDAAuD,IAAI,MACzD,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CACjD;AAAA;AAAA,IACF;AAAA,EACF;AACA,SAAQ,kBAAkB;AAC5B;AAGA,SAAS,MAAM,MAAkC;AAC/C,QAAM,IAAI,QAAQ,IAAI,IAAI;AAC1B,SAAO,KAAK,EAAE,SAAS,IAAI,IAAI;AACjC;AAQO,SAAS,WAA+B;AAC7C,SACE,MAAM,iBAAiB,KACvB,oBAAoB,GAAG,SACvB,MAAM,IAAI,OAAO;AAErB;AAGO,SAAS,iBAA8B;AAC5C,MAAI,MAAM,iBAAiB,EAAG,QAAO;AACrC,MAAI,oBAAoB,GAAG,MAAO,QAAO;AACzC,MAAI,MAAM,IAAI,OAAO,EAAG,QAAO;AAC/B,SAAO;AACT;AAEO,SAAS,SAAS,OAAqB;AAC5C,QAAM,IAAI,SAAS,KAAK;AAC1B;AAEO,SAAS,aAAmB;AACjC,QAAM,OAAO,OAAO;AACtB;AAEO,SAAS,YAAoB;AAClC,SACE,MAAM,mBAAmB,KACzB,oBAAoB,GAAG,UACvB,MAAM,IAAI,QAAQ,KAClB;AAEJ;AAEO,SAAS,UAAU,KAAmB;AAC3C,QAAM,IAAI,UAAU,GAAG;AACzB;AAEO,SAAS,SAAoB;AAClC,SAAO,EAAE,OAAO,MAAM,IAAI,OAAO,GAAG,QAAQ,MAAM,IAAI,QAAQ,EAAE;AAClE;AAEO,SAAS,aAAqB;AACnC,SAAO,MAAM;AACf;AAEO,SAAS,UAAU,KAA4B;AACpD,QAAM,OAAO,GAAG;AAClB;;;ACxGA,IAAM,UACJ,QAAQ,IAAI,oBAAoB,OAChC,QAAQ,IAAI,oBAAoB;AAE3B,SAAS,MAAM,aAAqB,OAAwB;AACjE,MAAI,CAAC,QAAS;AACd,QAAM,OAAO,MACV,IAAI,CAAC,MAAO,OAAO,MAAM,WAAW,IAAI,KAAK,UAAU,CAAC,CAAE,EAC1D,KAAK,GAAG;AACX,UAAQ,OAAO,MAAM,cAAc,QAAQ,KAAK,IAAI;AAAA,CAAI;AAC1D;;;ACIA,IAAI,UAAmB;AAAA,EACrB,MAAM,CAAC,QAAQ,OAAO;AAAA,EACtB,QAAQ;AAAA,EACR,OAAO,QAAQ,OAAO,SAAS,CAAC,QAAQ,IAAI;AAC9C;AAEO,SAAS,WAAW,OAA+B;AACxD,YAAU,EAAE,GAAG,SAAS,GAAG,MAAM;AACnC;AAEO,SAAS,aAAsB;AACpC,SAAO;AACT;;;ACjBO,IAAM,WAAN,cAAuB,MAAM;AAAA,EAClC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEA,YAAY,QAAgB,MAAsC;AAChE,UAAM,UAAU,OAAO,SAAS,WAAW,OAAO,KAAK;AACvD,UAAM,OAAO;AACb,SAAK,SAAS;AACd,QAAI,OAAO,SAAS,UAAU;AAC5B,WAAK,OAAO;AAAA,IACd,OAAO;AACL,WAAK,OAAO,KAAK;AACjB,WAAK,SAAS,KAAK;AACnB,WAAK,UAAU,KAAK;AAAA,IACtB;AAAA,EACF;AACF;AAEO,IAAM,oBAAN,cAAgC,MAAM;AAAA,EAC3C,cAAc;AACZ,UAAM,kDAAkD;AACxD,SAAK,OAAO;AAAA,EACd;AACF;AAEO,IAAM,eAAN,cAA2B,MAAM;AAAA,EACtC;AAAA,EACA;AAAA,EACA,YAAY,KAAa,OAAgB;AACvC,UAAM,SAAS,qBAAqB,KAAK;AACzC,UAAM,sBAAsB,GAAG,YAAY,MAAM,EAAE;AACnD,SAAK,OAAO;AACZ,SAAK,MAAM;AACX,SAAK,QAAQ;AAAA,EACf;AACF;AAEA,SAAS,qBAAqB,KAAsB;AAClD,MAAI,OAAO,OAAO,QAAQ,YAAY,WAAW,KAAK;AACpD,UAAM,IAAK,IAA2B;AACtC,QAAI,KAAK,OAAO,MAAM,UAAU;AAC9B,YAAM,OAAQ,EAAwB;AACtC,YAAM,MAAO,EAA2B;AACxC,UAAI,QAAQ,IAAK,QAAO,GAAG,QAAQ,EAAE,GAAG,QAAQ,MAAM,aAAQ,EAAE,GAAG,OAAO,EAAE,GAAG,KAAK;AAAA,IACtF;AAAA,EACF;AACA,MAAI,eAAe,MAAO,QAAO,IAAI;AACrC,SAAO,OAAO,GAAG;AACnB;AAWA,SAAS,SAAS,MAAc,OAAyC;AACvE,QAAM,OAAO,UAAU,EAAE,QAAQ,OAAO,EAAE;AAI1C,MAAI,WAAW,KAAK,WAAW,GAAG,IAAI,OAAO,IAAI,IAAI;AACrD,MAAI,KAAK,SAAS,MAAM,KAAK,SAAS,WAAW,OAAO,GAAG;AACzD,eAAW,SAAS,MAAM,CAAC;AAAA,EAC7B;AACA,QAAM,MAAM,IAAI,IAAI,OAAO,QAAQ;AACnC,MAAI,OAAO;AACT,eAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,KAAK,GAAG;AAC1C,UAAI,MAAM,UAAa,MAAM,QAAQ,MAAM,IAAI;AAC7C,YAAI,aAAa,IAAI,GAAG,OAAO,CAAC,CAAC;AAAA,MACnC;AAAA,IACF;AAAA,EACF;AACA,SAAO,IAAI,SAAS;AACtB;AAEA,eAAsB,QACpB,MACA,OAAuB,CAAC,GACZ;AACZ,QAAM,UAAkC;AAAA,IACtC,QAAQ;AAAA,IACR,GAAI,KAAK,WAAW,CAAC;AAAA,EACvB;AACA,MAAI,CAAC,KAAK,WAAW;AACnB,UAAM,QAAQ,SAAS;AACvB,QAAI,OAAO;AACT,cAAQ,gBAAgB,UAAU,KAAK;AAAA,IACzC,WAAW,CAAC,WAAW,EAAE,QAAQ;AAI/B,YAAM,IAAI,kBAAkB;AAAA,IAC9B,OAAO;AACL,cAAQ,gBAAgB;AAAA,IAC1B;AAAA,EACF;AACA,MAAI;AACJ,MAAI,KAAK,SAAS,QAAW;AAC3B,QAAI,KAAK,gBAAgB,cAAc,KAAK,gBAAgB,aAAa;AACvE,aAAO,KAAK;AAAA,IACd,OAAO;AACL,aAAO,KAAK,UAAU,KAAK,IAAI;AAC/B,cAAQ,cAAc,IAAI;AAAA,IAC5B;AAAA,EACF;AAEA,QAAM,MAAM,SAAS,MAAM,KAAK,KAAK;AACrC,QAAM,SAAS,KAAK,WAAW,KAAK,OAAO,SAAS;AAEpD,MAAI,WAAW,EAAE,QAAQ;AAGvB,UAAM,kBAAkB,EAAE,GAAG,QAAQ;AACrC,QAAI,gBAAgB,eAAe;AACjC,sBAAgB,gBAAgB;AAAA,IAClC;AACA,YAAQ,OAAO;AAAA,MACb,aAAa,MAAM,IAAI,GAAG;AAAA,IACxB,OAAO,QAAQ,eAAe,EAC3B,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,eAAe,CAAC,KAAK,CAAC,EAAE,EACxC,KAAK,IAAI,KACX,OAAO;AAAA,kBAAqB,SAAS,OAAO,IAAI,GAAG,GAAG,CAAC,KAAK,MAC7D;AAAA,IACJ;AACA,WAAO;AAAA,EACT;AAEA,QAAM,QAAQ,QAAQ,KAAK,OAAO,WAAW,EAAE;AAC/C,QAAM,UAAU,KAAK,IAAI;AACzB,MAAI;AACJ,MAAI;AACF,UAAM,MAAM,MAAM,KAAK,EAAE,QAAQ,SAAS,KAAK,CAAC;AAAA,EAClD,SAAS,KAAK;AACZ,UAAM,QAAQ,uBAAuB,GAAG,KAAK,IAAI,IAAI,OAAO,MAAM,OAAO,GAAG,CAAC;AAC7E,UAAM,IAAI,aAAa,KAAK,GAAG;AAAA,EACjC;AACA,QAAM,QAAQ,QAAQ,KAAK,UAAK,IAAI,MAAM,IAAI,IAAI,KAAK,IAAI,IAAI,OAAO,KAAK;AAE3E,MAAI,IAAI,WAAW,IAAK,QAAO;AAE/B,QAAM,OAAO,MAAM,IAAI,KAAK;AAC5B,QAAM,SAAS,OAAO,cAAc,IAAI,IAAI;AAE5C,MAAI,CAAC,IAAI,IAAI;AACX,QAAI,UAAU,OAAO,WAAW,YAAY,WAAW,QAAQ;AAC7D,YAAM,IAAI,SAAS,IAAI,QAAS,OAAwB,KAAK;AAAA,IAC/D;AAGA,UAAM,gBAAgB,KAAK,UAAU,EAAE,YAAY,EAAE,WAAW,GAAG;AACnE,UAAM,MAAM,gBACR,QAAQ,IAAI,MAAM,wEAClB,QAAQ,QAAQ,IAAI,MAAM;AAC9B,UAAM,IAAI,SAAS,IAAI,QAAQ,GAAG;AAAA,EACpC;AAKA,MAAI,WAAW,QAAQ,KAAK,KAAK,MAAM,IAAI;AACzC,UAAM,gBAAgB,KAAK,UAAU,EAAE,YAAY,EAAE,WAAW,GAAG;AACnE,UAAM,MAAM,gBACR,QAAQ,IAAI,MAAM,uFAClB,QAAQ,IAAI,MAAM,4BAA4B,SAAS,MAAM,GAAG,CAAC;AACrE,UAAM,IAAI,SAAS,IAAI,QAAQ,GAAG;AAAA,EACpC;AAEA,SAAQ,UAAiB;AAC3B;AAEA,SAAS,cAAc,GAAoB;AACzC,MAAI;AACF,WAAO,KAAK,MAAM,CAAC;AAAA,EACrB,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAAS,SAAS,GAAW,GAAmB;AAC9C,SAAO,EAAE,SAAS,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC,IAAI,WAAM;AAClD;AAkbO,IAAM,MAAM;AAAA;AAAA,EAEjB,eAAe,CAAC,UACd,QAAsB,iBAAiB,EAAE,MAAM,CAAC;AAAA,EAClD,aAAa,CAAC,OAAe,QAAwB,iBAAiB,EAAE,EAAE;AAAA,EAC1E,iBAAiB,CAAC,GAAW,UAC3B,QAAsB,wBAAwB,EAAE,OAAO,EAAE,GAAG,MAAM,EAAE,CAAC;AAAA,EACvE,gBAAgB,CAAC,IAAY,SAC3B,QAAwB,iBAAiB,EAAE,IAAI,EAAE,QAAQ,SAAS,KAAK,CAAC;AAAA,EAC1E,gBAAgB,CAAC,OACf,QAAuB,iBAAiB,EAAE,IAAI,EAAE,QAAQ,SAAS,CAAC;AAAA,EACpE,WAAW,CAAC,SACV,QAA2B,4BAA4B,EAAE,QAAQ,QAAQ,KAAK,CAAC;AAAA,EACjF,gBAAgB,CAAC,SAWX,QAAwB,iBAAiB,EAAE,QAAQ,QAAQ,KAAK,CAAC;AAAA,EACvE,sBAAsB,CAAC,OACrB,QAA6B,iBAAiB,EAAE,WAAW;AAAA,EAC7D,oBAAoB,CAClB,IAGA,SAEA,QAA+B,iBAAiB,EAAE,aAAa;AAAA,IAC7D,QAAQ;AAAA,IACR;AAAA,EACF,CAAC;AAAA,EACH,oBAAoB,CAAC,IAAY,QAC/B,QAA+B,iBAAiB,EAAE,aAAa,GAAG,EAAE;AAAA,EACtE,wBAAwB,CAAC,IAAY,QACnC,QAA+B,iBAAiB,EAAE,aAAa,GAAG,IAAI;AAAA,IACpE,QAAQ;AAAA,IACR,MAAM,EAAE,YAAY,KAAK;AAAA,EAC3B,CAAC;AAAA;AAAA,EAGH,aAAa,CAAC,UACZ,QAAoB,eAAe,EAAE,MAAM,CAAC;AAAA,EAC9C,cAAc,CAAC,SAKT,QAAsB,eAAe,EAAE,QAAQ,QAAQ,KAAK,CAAC;AAAA,EACnE,WAAW,CAAC,OAAe,QAAsB,eAAe,EAAE,EAAE;AAAA,EACpE,cAAc,CACZ,IACA,SACG,QAAsB,eAAe,EAAE,IAAI,EAAE,QAAQ,SAAS,KAAK,CAAC;AAAA,EACzE,cAAc,CAAC,IAAY,SACzB,QAAuB,eAAe,EAAE,IAAI;AAAA,IAC1C,QAAQ;AAAA,IACR,OAAO,MAAM,UAAU,EAAE,SAAS,OAAO,IAAI;AAAA,EAC/C,CAAC;AAAA,EACH,YAAY,CAAC,IAAY,SACvB,QAAsB,eAAe,EAAE,SAAS,EAAE,QAAQ,QAAQ,KAAK,CAAC;AAAA;AAAA,EAG1E,WAAW,CAAC,UACV,QAAkB,aAAa,EAAE,MAAM,CAAC;AAAA,EAC1C,SAAS,CAAC,OAAe,QAAoB,aAAa,EAAE,EAAE;AAAA,EAC9D,YAAY,CAAC,SAeP,QAAoB,aAAa,EAAE,QAAQ,QAAQ,KAAK,CAAC;AAAA,EAC/D,YAAY,CAAC,IAAY,SACvB,QAAoB,aAAa,EAAE,IAAI,EAAE,QAAQ,SAAS,KAAK,CAAC;AAAA,EAClE,YAAY,CAAC,OACX,QAAuB,aAAa,EAAE,IAAI,EAAE,QAAQ,SAAS,CAAC;AAAA,EAChE,oBAAoB,CAAC,OACnB,QAA4B,aAAa,EAAE,cAAc;AAAA;AAAA;AAAA,EAG3D,oBAAoB,CAAC,IAAY,SAC/B,QAA4B,aAAa,EAAE,gBAAgB;AAAA,IACzD,QAAQ;AAAA,IACR;AAAA,EACF,CAAC;AAAA;AAAA,EAGH,WAAW,CAAC,QAAgB,UAC1B,QAAkB,aAAa,MAAM,UAAU,EAAE,MAAM,CAAC;AAAA;AAAA,EAG1D,eAAe,CAAC,UACd,QAAsB,iBAAiB,EAAE,MAAM,CAAC;AAAA,EAClD,aAAa,CAAC,OACZ,QAAwB,iBAAiB,EAAE,EAAE;AAAA,EAC/C,gBAAgB,CAAC,SAIX,QAAwB,iBAAiB,EAAE,QAAQ,QAAQ,KAAK,CAAC;AAAA,EACvE,gBAAgB,CACd,IACA,SAOA,QAAwB,iBAAiB,EAAE,IAAI,EAAE,QAAQ,SAAS,KAAK,CAAC;AAAA,EAC1E,gBAAgB,CAAC,OACf,QAAuB,iBAAiB,EAAE,IAAI,EAAE,QAAQ,SAAS,CAAC;AAAA,EACpE,uBAAuB,CACrB,IACA,UAEA,QAA0B,iBAAiB,EAAE,cAAc,EAAE,MAAM,CAAC;AAAA,EACtE,wBAAwB,CACtB,IACA,SAEA,QAA4B,iBAAiB,EAAE,cAAc;AAAA,IAC3D,QAAQ;AAAA,IACR;AAAA,EACF,CAAC;AAAA,EACH,wBAAwB,CAAC,IAAY,SACnC,QAAuB,iBAAiB,EAAE,cAAc,IAAI,IAAI;AAAA,IAC9D,QAAQ;AAAA,EACV,CAAC;AAAA,EACH,sBAAsB,CACpB,IACA,MACA,SAEA,QAA4B,iBAAiB,EAAE,cAAc,IAAI,SAAS;AAAA,IACxE,QAAQ;AAAA,IACR;AAAA,EACF,CAAC;AAAA;AAAA,EAGH,qBAAqB,CACnB,IACA,UAEA,QAA4B,iBAAiB,EAAE,YAAY,EAAE,MAAM,CAAC;AAAA,EACtE,sBAAsB,CACpB,IACA,SAOA,QAA8B,iBAAiB,EAAE,YAAY;AAAA,IAC3D,QAAQ;AAAA,IACR;AAAA,EACF,CAAC;AAAA,EACH,mBAAmB,CAAC,IAAY,QAC9B,QAA8B,iBAAiB,EAAE,YAAY,GAAG,EAAE;AAAA,EACpE,sBAAsB,CACpB,IACA,KACA,SAEA,QAA8B,iBAAiB,EAAE,YAAY,GAAG,IAAI;AAAA,IAClE,QAAQ;AAAA,IACR;AAAA,EACF,CAAC;AAAA,EACH,sBAAsB,CAAC,IAAY,KAAa,SAC9C,QAAuB,iBAAiB,EAAE,YAAY,GAAG,IAAI;AAAA,IAC3D,QAAQ;AAAA,IACR,OAAO,MAAM,UAAU,EAAE,SAAS,OAAO,IAAI;AAAA,EAC/C,CAAC;AAAA,EACH,oBAAoB,CAClB,IACA,KACA,SAEA,QAA8B,iBAAiB,EAAE,YAAY,GAAG,SAAS;AAAA,IACvE,QAAQ;AAAA,IACR;AAAA,EACF,CAAC;AAAA;AAAA,EAGH,oBAAoB,CAClB,IACA,UAEA,QAA2B,iBAAiB,EAAE,WAAW,EAAE,MAAM,CAAC;AAAA,EACpE,qBAAqB,CACnB,IACA,SAEA,QAA6B,iBAAiB,EAAE,WAAW;AAAA,IACzD,QAAQ;AAAA,IACR;AAAA,EACF,CAAC;AAAA,EACH,kBAAkB,CAAC,IAAY,QAC7B,QAA6B,iBAAiB,EAAE,WAAW,GAAG,EAAE;AAAA,EAClE,qBAAqB,CACnB,IACA,KACA,SAEA,QAA6B,iBAAiB,EAAE,WAAW,GAAG,IAAI;AAAA,IAChE,QAAQ;AAAA,IACR;AAAA,EACF,CAAC;AAAA;AAAA;AAAA,EAGH,qBAAqB,CAAC,IAAY,QAChC,QAAuB,iBAAiB,EAAE,WAAW,GAAG,IAAI;AAAA,IAC1D,QAAQ;AAAA,EACV,CAAC;AAAA,EACH,0BAA0B,CACxB,IACA,KACA,UAEA;AAAA,IACE,iBAAiB,EAAE,WAAW,GAAG;AAAA,IACjC,EAAE,MAAM;AAAA,EACV;AAAA,EACF,yBAAyB,CAAC,IAAY,KAAa,SACjD;AAAA,IACE,iBAAiB,EAAE,WAAW,GAAG;AAAA,IACjC,EAAE,QAAQ,QAAQ,KAAK;AAAA,EACzB;AAAA,EACF,2BAA2B,CAAC,IAAY,KAAa,QACnD;AAAA,IACE,iBAAiB,EAAE,WAAW,GAAG,YAAY,GAAG;AAAA,IAChD,EAAE,QAAQ,SAAS;AAAA,EACrB;AAAA,EACF,8BAA8B,CAC5B,IACA,KACA,UAEA;AAAA,IACE,iBAAiB,EAAE,WAAW,GAAG;AAAA,IACjC,EAAE,MAAM;AAAA,EACV;AAAA;AAAA;AAAA,EAGF,6BAA6B,CAC3B,IACA,KACA,SAEA;AAAA,IACE,iBAAiB,EAAE,WAAW,GAAG;AAAA,IACjC,EAAE,QAAQ,OAAO,KAAK;AAAA,EACxB;AAAA;AAAA,EAGF,cAAc,CAAC,UAKT,QAAqB,gBAAgB,EAAE,MAAM,CAAC;AAAA,EACpD,YAAY,CAAC,OAAe,QAAuB,gBAAgB,EAAE,EAAE;AAAA,EACvE,kBAAkB,CAAC,IAAY,UAC7B,QAAyB,gBAAgB,EAAE,UAAU,EAAE,MAAM,CAAC;AAAA;AAAA,EAGhE,mBAAmB,CACjB,IACA,UAEA,QAA2B,2BAA2B,EAAE,IAAI,EAAE,MAAM,CAAC;AAAA,EACvE,eAAe,CAAC,IAAY,UAC1B,QAAuB,uBAAuB,EAAE,IAAI,EAAE,MAAM,CAAC;AAAA,EAC/D,mBAAmB,CACjB,IACA,UAEA,QAA2B,2BAA2B,EAAE,IAAI,EAAE,MAAM,CAAC;AAAA,EACvE,eAAe,CAAC,OACd,QAAuB,uBAAuB,EAAE,EAAE;AACtD;;;ACj6BA,OAAO,WAAW;;;ACIX,IAAM,WAAW;AAAA,EACtB,IAAI;AAAA;AAAA,EAEJ,UAAU;AAAA;AAAA,EAEV,WAAW;AAAA;AAAA,EAEX,iBAAiB;AAAA;AAAA,EAEjB,cAAc;AAAA;AAAA,EAEd,UAAU;AACZ;AAIO,IAAM,mBAAuD;AAAA,EAClE,CAAC,SAAS,EAAE,GAAG;AAAA,EACf,CAAC,SAAS,QAAQ,GAAG;AAAA,EACrB,CAAC,SAAS,SAAS,GAAG;AAAA,EACtB,CAAC,SAAS,eAAe,GAAG;AAAA,EAC5B,CAAC,SAAS,YAAY,GAAG;AAAA,EACzB,CAAC,SAAS,QAAQ,GAAG;AACvB;;;ADhBO,IAAM,kBAAN,cAA8B,MAAM;AAAA,EACzC;AAAA,EACA,YAAY,SAAiB,SAAmB;AAC9C,UAAM,OAAO;AACb,SAAK,OAAO;AACZ,SAAK,UAAU;AAAA,EACjB;AACF;AA0BO,SAAS,YAAY,KAA8B;AACxD,MAAI,eAAe,mBAAmB;AACpC,UAAM,UAAU,oBAAoB,IAAI,OAAO;AAC/C,WAAO;AAAA,MACL,OAAO,MAAM,IAAI,SAAI,IAAI;AAAA,MACzB,MAAM;AAAA,QACJ,OAAO;AAAA,UACL,MAAM;AAAA,UACN,SAAS,IAAI;AAAA,UACb,WAAW;AAAA,UACX,MAAM;AAAA,QACR;AAAA,MACF;AAAA,MACA,UAAU,SAAS;AAAA,IACrB;AAAA,EACF;AACA,MAAI,eAAe,cAAc;AAC/B,UAAM,UAAU,oBAAoB,IAAI,OAAO;AAC/C,WAAO;AAAA,MACL,OACE,MAAM,IAAI,SAAI,IACd,UACA,MAAM;AAAA,QACJ;AAAA,MACF;AAAA,MACF,MAAM;AAAA,QACJ,OAAO;AAAA,UACL,MAAM;AAAA,UACN,SAAS,IAAI;AAAA,UACb,WAAW;AAAA,UACX,MAAM;AAAA,QACR;AAAA,MACF;AAAA,MACA,UAAU,SAAS;AAAA,IACrB;AAAA,EACF;AACA,MAAI,eAAe,iBAAiB;AAClC,UAAM,UAAU,oBAAoB,IAAI,OAAO;AAC/C,WAAO;AAAA,MACL,OAAO,MAAM,IAAI,SAAI,IAAI;AAAA,MACzB,MAAM;AAAA,QACJ,OAAO;AAAA,UACL,MAAM;AAAA,UACN,SAAS,IAAI;AAAA,UACb,WAAW;AAAA,UACX,GAAI,IAAI,UAAU,EAAE,SAAS,IAAI,QAAQ,IAAI,CAAC;AAAA,QAChD;AAAA,MACF;AAAA,MACA,UAAU,SAAS;AAAA,IACrB;AAAA,EACF;AACA,MAAI,eAAe,UAAU;AAC3B,UAAM,OAAO,gBAAgB,GAAG;AAChC,UAAM,cAAc,oBAAoB,IAAI,OAAO;AACnD,UAAM,aAAa,IAAI,SAAS,oBAAoB,IAAI,MAAM,IAAI;AAClE,UAAM,cACJ,IAAI,WAAW,OAAO,IAAI,YAAY,WAClC,oBAAoB,KAAK,UAAU,IAAI,OAAO,CAAC,IAC/C;AACN,UAAM,OAAO,aAAa,MAAM,IAAI;AAAA,UAAa,UAAU,EAAE,IAAI;AACjE,UAAM,WAAW,OAAO,MAAM,IAAI;AAAA,UAAa,IAAI,EAAE,IAAI;AACzD,UAAM,UAAU,cAAc,MAAM,IAAI,SAAS,WAAW,IAAI;AAChE,WAAO;AAAA,MACL,OACE,MAAM,IAAI,WAAM,IAAI,MAAM,IAAI,IAAI,IAAI,IAAI,IAC1C,cACA,WACA,OACA;AAAA,MACF,MAAM;AAAA,QACJ,OAAO;AAAA,UACL,MAAM,IAAI;AAAA,UACV,SAAS,IAAI;AAAA,UACb,QAAQ,IAAI;AAAA,UACZ,WAAW,kBAAkB,IAAI,MAAM;AAAA,UACvC,GAAI,OAAO,EAAE,KAAK,IAAI,CAAC;AAAA,UACvB,GAAI,IAAI,SAAS,EAAE,SAAS,IAAI,OAAO,IAAI,CAAC;AAAA,UAC5C,GAAI,IAAI,UAAU,EAAE,SAAS,IAAI,QAAQ,IAAI,CAAC;AAAA,QAChD;AAAA,MACF;AAAA,MACA,UAAU,oBAAoB,GAAG;AAAA,IACnC;AAAA,EACF;AACA,QAAM,aAAa,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAClE,SAAO;AAAA,IACL,OAAO,MAAM,IAAI,SAAI,IAAI,oBAAoB,UAAU;AAAA,IACvD,MAAM,EAAE,OAAO,EAAE,MAAM,YAAY,SAAS,YAAY,WAAW,MAAM,EAAE;AAAA,IAC3E,UAAU,SAAS;AAAA,EACrB;AACF;AAQA,SAAS,kBAAkB,QAAyB;AAClD,MAAI,WAAW,IAAK,QAAO;AAC3B,MAAI,UAAU,OAAO,SAAS,IAAK,QAAO;AAC1C,SAAO;AACT;AAEA,SAAS,gBAAgB,KAAmC;AAC1D,MAAI,IAAI,WAAW,IAAK,QAAO;AAC/B,MAAI,IAAI,WAAW,KAAK;AACtB,WAAO;AAAA,EACT;AACA,MAAI,IAAI,WAAW,KAAK;AACtB,WAAO;AAAA,EACT;AACA,MAAI,IAAI,WAAW,IAAK,QAAO;AAC/B,SAAO;AACT;AAEA,SAAS,oBAAoB,KAAyB;AACpD,MAAI,IAAI,WAAW,IAAK,QAAO,SAAS;AACxC,MAAI,IAAI,WAAW,IAAK,QAAO,SAAS;AACxC,MAAI,IAAI,WAAW,IAAK,QAAO,SAAS;AACxC,SAAO,SAAS;AAClB;AAEO,SAAS,IAAI,KAAqB;AACvC,QAAM,KAAK,YAAY,GAAG;AAC1B,MAAI,WAAW,EAAE,MAAM;AACrB,YAAQ,OAAO;AAAA,MACb,KAAK,UAAU,EAAE,IAAI,OAAO,OAAO,GAAG,KAAK,MAAM,CAAC,IAAI;AAAA,IACxD;AAAA,EACF,OAAO;AACL,YAAQ,OAAO,MAAM,GAAG,QAAQ,IAAI;AAAA,EACtC;AACA,UAAQ,KAAK,GAAG,QAAQ;AAC1B;AAQO,SAAS,KAAK,SAAkB,OAA2B;AAChE,QAAM,KAAK,WAAW;AAItB,MAAI,GAAG,OAAQ;AACf,MAAI,GAAG,MAAM;AACX,YAAQ,OAAO,MAAM,KAAK,UAAU,YAAY,OAAO,GAAG,MAAM,CAAC,IAAI,IAAI;AAAA,EAC3E,OAAO;AACL,YAAQ,OAAO,MAAM,MAAM,IAAI,IAAI;AAAA,EACrC;AACF;AAEA,SAAS,YAAY,SAEiD;AACpE,MACE,YAAY,QACZ,OAAO,YAAY,YACnB,UAAU,WACV,iBAAiB,WACjB,MAAM,QAAS,QAA8B,IAAI,GACjD;AACA,UAAM,IAAI;AACV,WAAO,EAAE,IAAI,MAAM,MAAM,EAAE,MAAM,MAAM,EAAE,aAAa,EAAE,YAAY,EAAE;AAAA,EACxE;AACA,SAAO,EAAE,IAAI,MAAM,MAAM,QAAQ;AACnC;AAGO,SAAS,MACd,MACA,SACQ;AACR,MAAI,KAAK,WAAW,EAAG,QAAO,MAAM,IAAI,WAAW;AACnD,QAAM,SAAS,QAAQ;AAAA,IAAI,CAAC,MAC1B,KAAK,IAAI,EAAE,QAAQ,GAAG,KAAK,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,IAAI,MAAM,CAAC;AAAA,EAC5D;AACA,QAAM,MAAM,CAAC,GAAW,MAAc,IAAI,IAAI,OAAO,KAAK,IAAI,GAAG,IAAI,EAAE,MAAM,CAAC;AAC9E,QAAM,SAAS,QAAQ,IAAI,CAAC,GAAG,MAAM,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,IAAI;AAC7E,QAAM,MAAM,QAAQ,IAAI,CAAC,GAAG,MAAM,SAAI,OAAO,OAAO,CAAC,CAAC,CAAC,EAAE,KAAK,IAAI;AAClE,QAAM,OAAO,KAAK;AAAA,IAAI,CAAC,MACrB,QAAQ,IAAI,CAAC,GAAG,MAAM,IAAI,EAAE,CAAC,KAAK,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,KAAK,IAAI;AAAA,EAC7D;AACA,SAAO,CAAC,QAAQ,MAAM,IAAI,GAAG,GAAG,GAAG,IAAI,EAAE,KAAK,IAAI;AACpD;AAEO,SAAS,KAAK,KAAsB;AACzC,SAAO,KAAK,UAAU,KAAK,MAAM,CAAC;AACpC;AAUO,SAAS,oBAAoB,OAAuB;AACzD,SAAO,MAEJ,QAAQ,8BAA8B,EAAE,EACxC,QAAQ,oCAAoC,EAAE,EAG9C,QAAQ,6BAA6B,EAAE,EAIvC,QAAQ,SAAS,EAAE,EAGnB,QAAQ,gBAAgB,EAAE,EAE1B,QAAQ,6CAA6C,EAAE,EAEvD,QAAQ,0BAA0B,EAAE;AACzC;;;AL3PO,SAAS,0BAA0BC,UAAwB;AAChE,QAAM,YAAYA,SACf,QAAQ,WAAW,EACnB,YAAY,2DAA2D;AAE1E,YACG,QAAQ,eAAe,EACvB;AAAA,IACC;AAAA,EACF,EACC,OAAO,qBAAqB,uCAAuC,CAAC,MAAM,OAAO,CAAC,CAAC,EACnF,OAAO,qBAAqB,6BAA6B,CAAC,MAAM,OAAO,CAAC,CAAC,EACzE,OAAO,UAAU,iBAAiB,EAClC;AAAA,IACC,OACE,IACA,SACG;AACH,UAAI,KAAK,KAAM,YAAW,EAAE,MAAM,KAAK,CAAC;AACxC,UAAI;AACF,cAAM,QAAQ,MAAM,IAAI,kBAAkB,IAAI;AAAA,UAC5C,OAAO,KAAK;AAAA,UACZ,OAAO,KAAK;AAAA,QACd,CAAC;AACD,aAAK,OAAO,MAAM,wBAAwB,KAAK,CAAC;AAAA,MAClD,SAAS,KAAK;AACZ,YAAI,GAAG;AAAA,MACT;AAAA,IACF;AAAA,EACF;AAEF,YACG,QAAQ,WAAW,EACnB,YAAY,8CAA8C,EAC1D,OAAO,qBAAqB,uCAAuC,CAAC,MAAM,OAAO,CAAC,CAAC,EACnF,OAAO,qBAAqB,6BAA6B,CAAC,MAAM,OAAO,CAAC,CAAC,EACzE,OAAO,UAAU,iBAAiB,EAClC;AAAA,IACC,OACE,IACA,SACG;AACH,UAAI,KAAK,KAAM,YAAW,EAAE,MAAM,KAAK,CAAC;AACxC,UAAI;AACF,cAAM,QAAQ,MAAM,IAAI,cAAc,IAAI;AAAA,UACxC,OAAO,KAAK;AAAA,UACZ,OAAO,KAAK;AAAA,QACd,CAAC;AACD,aAAK,OAAO,MAAM,oBAAoB,KAAK,CAAC;AAAA,MAC9C,SAAS,KAAK;AACZ,YAAI,GAAG;AAAA,MACT;AAAA,IACF;AAAA,EACF;AAEF,YACG,QAAQ,eAAe,EACvB,YAAY,qEAAqE,EACjF,OAAO,qBAAqB,uCAAuC,CAAC,MAAM,OAAO,CAAC,CAAC,EACnF,OAAO,qBAAqB,6BAA6B,CAAC,MAAM,OAAO,CAAC,CAAC,EACzE,OAAO,UAAU,iBAAiB,EAClC;AAAA,IACC,OACE,IACA,SACG;AACH,UAAI,KAAK,KAAM,YAAW,EAAE,MAAM,KAAK,CAAC;AACxC,UAAI;AACF,cAAM,QAAQ,MAAM,IAAI,kBAAkB,IAAI;AAAA,UAC5C,OAAO,KAAK;AAAA,UACZ,OAAO,KAAK;AAAA,QACd,CAAC;AACD,aAAK,OAAO,MAAM,wBAAwB,KAAK,CAAC;AAAA,MAClD,SAAS,KAAK;AACZ,YAAI,GAAG;AAAA,MACT;AAAA,IACF;AAAA,EACF;AAEF,YACG,QAAQ,WAAW,EACnB;AAAA,IACC;AAAA,EACF,EACC,OAAO,UAAU,iBAAiB,EAClC,OAAO,OAAO,IAAY,SAA6B;AACtD,QAAI,KAAK,KAAM,YAAW,EAAE,MAAM,KAAK,CAAC;AACxC,QAAI;AACF,YAAM,QAAQ,MAAM,IAAI,cAAc,EAAE;AACxC,WAAK,OAAO,MAAM,KAAK,KAAK,CAAC;AAAA,IAC/B,SAAS,KAAK;AACZ,UAAI,GAAG;AAAA,IACT;AAAA,EACF,CAAC;AACL;AAEA,SAAS,wBAAwB,OAAkE;AACjG,QAAM,UAAU,KAAK,MAAM,MAAM,yBAAyB,EAAE;AAC5D,QAAM,QAAQ;AAAA,IACZ,GAAGC,OAAM,KAAK,WAAW,CAAC,UAAU,MAAM,WAAW;AAAA,IACrD,GAAGA,OAAM,KAAK,cAAc,CAAC,OAAO,MAAM,WAAW;AAAA,IACrD,GAAGA,OAAM,KAAK,iBAAiB,CAAC,IAAI,MAAM,cAAc;AAAA,IACxD,GAAGA,OAAM,KAAK,kBAAkB,CAAC,IAAI,OAAO,SAAS,MAAM,uBAAuB,QAAQ,CAAC,CAAC;AAAA,IAC5FA,OAAM,IAAI,WAAW,MAAM,MAAM,MAAM,GAAG,EAAE,CAAC,WAAM,MAAM,MAAM,MAAM,GAAG,EAAE,CAAC,EAAE;AAAA,EAC/E;AACA,MAAI,MAAM,0BAA0B,SAAS,GAAG;AAC9C,UAAM,OAAO,MAAM,0BAA0B,IAAI,CAAC,OAAO;AAAA,MACvD,MAAM,OAAO,EAAE,WAAW;AAAA,MAC1B,aAAa,EAAE,qBAAqB,QAAQ,CAAC;AAAA,IAC/C,EAAE;AACF,UAAM,KAAK,IAAIA,OAAM,KAAK,4BAA4B,CAAC;AACvD,UAAM,KAAK,MAAM,MAAM,CAAC,QAAQ,aAAa,CAAC,CAAC;AAAA,EACjD;AACA,SAAO,MAAM,KAAK,IAAI;AACxB;AAEA,SAAS,oBAAoB,OAA8D;AACzF,QAAM,UAAU,KAAK,MAAM,MAAM,yBAAyB,EAAE;AAC5D,SAAO;AAAA,IACL,GAAGA,OAAM,KAAK,OAAO,CAAC,cAAc,MAAM,OAAO;AAAA,IACjD,GAAGA,OAAM,KAAK,cAAc,CAAC,OAAO,MAAM,WAAW;AAAA,IACrD,GAAGA,OAAM,KAAK,iBAAiB,CAAC,IAAI,MAAM,cAAc;AAAA,IACxD,GAAGA,OAAM,KAAK,kBAAkB,CAAC,IAAI,OAAO,SAAS,MAAM,uBAAuB,QAAQ,CAAC,CAAC;AAAA,IAC5FA,OAAM,IAAI,WAAW,MAAM,MAAM,MAAM,GAAG,EAAE,CAAC,WAAM,MAAM,MAAM,MAAM,GAAG,EAAE,CAAC,EAAE;AAAA,EAC/E,EAAE,KAAK,IAAI;AACb;AAEA,SAAS,wBACP,OACQ;AACR,QAAM,UAAU,KAAK,MAAM,MAAM,yBAAyB,EAAE;AAC5D,SAAO;AAAA,IACL,GAAGA,OAAM,KAAK,WAAW,CAAC,UAAU,MAAM,WAAW;AAAA,IACrD,GAAGA,OAAM,KAAK,cAAc,CAAC,OAAO,MAAM,WAAW;AAAA,IACrD,GAAGA,OAAM,KAAK,iBAAiB,CAAC,IAAI,MAAM,cAAc;AAAA,IACxD,GAAGA,OAAM,KAAK,kBAAkB,CAAC,IAAI,OAAO,SAAS,MAAM,uBAAuB,QAAQ,CAAC,CAAC;AAAA,IAC5FA,OAAM,IAAI,WAAW,MAAM,MAAM,MAAM,GAAG,EAAE,CAAC,WAAM,MAAM,MAAM,MAAM,GAAG,EAAE,CAAC,EAAE;AAAA,EAC/E,EAAE,KAAK,IAAI;AACb;;;AOrJA,OAAOC,YAAW;AAClB,SAAS,eAAe;AACxB,OAAO,SAAS;;;ACFhB,YAAY,WAAW;AACvB,OAAO,UAAU;AAIV,IAAM,YAAY;AAIlB,IAAM,iBAAiB;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAaO,SAAS,aAAa,SAAiB,UAAU,GAAQ;AAC9D,QAAM,MAAM,IAAI,IAAI,MAAM;AAC1B,MAAI,IAAI,aAAa,UAAU,IAAI,aAAa,SAAS;AACvD,WAAO,IAAI,IAAI,GAAG,IAAI,MAAM,EAAE;AAAA,EAChC;AACA,MAAI,IAAI,SAAS,WAAW,MAAM,GAAG;AAGnC,WAAO,IAAI,IAAI,GAAG,IAAI,QAAQ,KAAK,IAAI,KAAK,QAAQ,UAAU,MAAM,CAAC,EAAE;AAAA,EACzE;AACA,SAAO,IAAI,IAAI,IAAI,MAAM;AAC3B;AASA,eAAsB,SAAS,QAAiD;AAC9E,QAAM,WAAW,MAAY,uBAAiB,QAAQ;AAAA,IACpD,WAAW;AAAA,IACX,GAAG,iBAAiB,MAAM;AAAA,EAC5B,CAAC;AACD,SAAa,+BAAyB,QAAQ,QAAQ;AACxD;AAOA,SAAS,iBAAiB,GAAQ;AAChC,QAAM,UACJ,EAAE,aAAa,YACd,EAAE,aAAa,eACd,EAAE,aAAa,eACf,EAAE,SAAS,SAAS,QAAQ;AAChC,SAAO,UAAU,EAAE,CAAO,2BAAqB,GAAG,KAAc,IAAI,CAAC;AACvE;AAWA,eAAsB,2BACpB,IACA,QACsC;AACtC,MAAI,CAAC,GAAG,+BAA+B;AACrC,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,QAAM,OAAO,IAAI,gBAAgB;AAAA,IAC/B,WAAW;AAAA,IACX,OAAO,OAAO,KAAK,GAAG;AAAA,EACxB,CAAC;AACD,QAAMC,QAAO,MAAM;AAAA,IACjB,GAAG;AAAA,IACH;AAAA,IACA;AAAA,EACF;AACA,SAAOA;AACT;AAYA,eAAe,aACb,UACA,MACA,MACkC;AAClC,MAAI;AACJ,MAAI;AACF,UAAM,MAAM,MAAM,UAAU;AAAA,MAC1B,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,gBAAgB;AAAA,QAChB,QAAQ;AAAA,MACV;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH,SAAS,KAAK;AACZ,UAAM,SAAS,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC9D,UAAM,IAAI;AAAA,MACR,GAAG,IAAI,wBAAwB,QAAQ,YAAY,MAAM;AAAA,IAC3D;AAAA,EACF;AACA,QAAM,OAAO,MAAM,IAAI,KAAK;AAC5B,MAAI,SAAyC;AAC7C,MAAI;AACF,aAAS,OAAQ,KAAK,MAAM,IAAI,IAAgC;AAAA,EAClE,QAAQ;AACN,aAAS;AAAA,EACX;AACA,MAAI,CAAC,IAAI,IAAI;AACX,QAAI,QAAQ;AACV,YAAM,IAAI,IAAI;AAAA,QACZ,GAAG,IAAI,YAAY,IAAI,MAAM,IAAI,KAAK,UAAU,MAAM,CAAC;AAAA,MACzD;AAGA,MAAC,EAAiD,OAAO;AACzD,YAAM;AAAA,IACR;AACA,UAAM,UAAU,OAAO,KAAK,MAAM,GAAG,GAAG,IAAI;AAC5C,UAAM,IAAI;AAAA,MACR,GAAG,IAAI,iBAAiB,IAAI,MAAM,wBAAwB,OAAO;AAAA,IACnE;AAAA,EACF;AACA,MAAI,CAAC,QAAQ;AACX,UAAM,IAAI;AAAA,MACR,GAAG,IAAI,gFAA2E,QAAQ;AAAA,IAC5F;AAAA,EACF;AACA,SAAO;AACT;AAcA,eAAsB,aACpB,IACA,YACA;AAAA,EACE,WAAW;AAAA,EACX,YAAY;AAAA,EACZ;AACF,IAAoE,CAAC,GAC7C;AACxB,MAAI,CAAC,GAAG,eAAgB,OAAM,IAAI,MAAM,gCAAgC;AACxE,QAAM,WAAW,KAAK,IAAI,IAAI,YAAY;AAC1C,MAAI,OAAO,KAAK,IAAI,UAAU,CAAC;AAE/B,SAAO,KAAK,IAAI,IAAI,UAAU;AAC5B,UAAM,IAAI,QAAQ,CAAC,MAAM,WAAW,GAAG,OAAO,GAAI,CAAC;AACnD,aAAS;AACT,UAAM,OAAO,IAAI,gBAAgB;AAAA,MAC/B,YAAY;AAAA,MACZ,aAAa;AAAA,MACb,WAAW;AAAA,IACb,CAAC;AACD,QAAI;AACJ,QAAI;AACF,eAAS,MAAM,aAAa,GAAG,gBAAgB,MAAM,eAAe;AAAA,IACtE,SAAS,KAAK;AAIZ,YAAM,UAAW,IAAmD;AACpE,YAAM,UAAU,SAAS;AACzB,UAAI,YAAY,wBAAyB;AACzC,UAAI,YAAY,aAAa;AAC3B,gBAAQ;AACR;AAAA,MACF;AACA,YAAM;AAAA,IACR;AACA,WAAO;AAAA,EACT;AACA,QAAM,IAAI,MAAM,qDAAqD;AACvE;AAEA,eAAsB,eAAe,KAA4B;AAC/D,MAAI;AACF,UAAM,KAAK,GAAG;AAAA,EAChB,QAAQ;AAAA,EAER;AACF;;;ADzMO,SAAS,qBAAqBC,UAAwB;AAC3D,EAAAA,SACG,QAAQ,OAAO,EACf,YAAY,0DAA0D,EACtE;AAAA,IACC;AAAA,IACA;AAAA,EACF,EACC;AAAA,IACC;AAAA,IACA;AAAA,EACF,EACC,OAAO,gBAAgB,gDAAgD,EACvE;AAAA,IACC,OAAO,SAID;AACJ,UAAI;AACF,YAAI,KAAK,OAAO;AACd,iBAAO,MAAM,eAAe,KAAK,KAAK;AAAA,QACxC;AACA,cAAM,SAAS,KAAK,SAChB,KAAK,OAAO,MAAM,QAAQ,EAAE,OAAO,OAAO,IAC1C;AACJ,eAAO,MAAM,oBAAoB,QAAQ;AAAA,UACvC,aAAa,KAAK,YAAY;AAAA,QAChC,CAAC;AAAA,MACH,SAAS,KAAK;AACZ,YAAI,GAAG;AAAA,MACT;AAAA,IACF;AAAA,EACF;AAEF,EAAAA,SACG,QAAQ,QAAQ,EAChB,YAAY,6BAA6B,EACzC,OAAO,MAAM;AACZ,eAAW;AACX,SAAK,EAAE,SAAS,KAAK,GAAG,MAAMC,OAAM,MAAM,QAAG,IAAI,iBAAiB;AAAA,EACpE,CAAC;AAEH,EAAAD,SACG,QAAQ,QAAQ,EAChB,YAAY,mCAAmC,EAC/C,OAAO,MAAM;AACZ,UAAM,QAAQ,SAAS;AACvB,QAAI,CAAC,OAAO;AACV,UAAI,IAAI,kBAAkB,CAAC;AAAA,IAC7B;AACA,UAAM,UAAU,GAAG,MAAM,MAAM,GAAG,EAAE,CAAC,MAAM,MAAM,MAAM,EAAE,CAAC;AAC1D;AAAA,MACE;AAAA,QACE,QAAQ,UAAU;AAAA,QAClB,OAAO;AAAA,QACP,QAAQ,eAAe;AAAA,QACvB,QAAQ,WAAW;AAAA,MACrB;AAAA,MACA,MACE;AAAA,QACE,GAAGC,OAAM,KAAK,UAAU,CAAC,IAAI,UAAU,CAAC;AAAA,QACxC,GAAGA,OAAM,KAAK,UAAU,CAAC,IAAI,OAAO;AAAA,QACpC,GAAGA,OAAM,KAAK,UAAU,CAAC,IAAI,eAAe,CAAC;AAAA,QAC7C,GAAGA,OAAM,KAAK,UAAU,CAAC,IAAI,WAAW,CAAC;AAAA,MAC3C,EAAE,KAAK,IAAI;AAAA,IACf;AAAA,EACF,CAAC;AAEH,EAAAD,SACG,QAAQ,MAAM,EACd,YAAY,oCAAoC,EAChD,WAAW,gBAAgB,CAAC,EAC5B,WAAW,aAAa,CAAC;AAC9B;AAEA,SAAS,kBAA2B;AAClC,SAAO,IAAI,QAAQ,QAAQ,EACxB;AAAA,IACC;AAAA,EACF,EACC;AAAA,IACC;AAAA,IACA;AAAA,EACF,EACC,OAAO,CAAC,SAAiC;AACxC,UAAM,QAAQ,SAAS;AACvB,QAAI,CAAC,OAAO;AACV,UAAI,IAAI,kBAAkB,CAAC;AAAA,IAC7B;AACA,UAAM,UAAU;AAAA,MACd,OAAO,KAAK,WACR,QACA,GAAG,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,MAAM,MAAM,EAAE,CAAC;AAAA,MAC7C,QAAQ,UAAU;AAAA,MAClB,QAAQ,eAAe;AAAA,IACzB;AACA,YAAQ,OAAO,MAAM,KAAK,UAAU,SAAS,MAAM,CAAC,IAAI,IAAI;AAC5D,QAAI,CAAC,KAAK,UAAU;AAClB,cAAQ,OAAO;AAAA,QACbC,OAAM;AAAA,UACJ;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF,CAAC;AACL;AAEA,SAAS,eAAwB;AAC/B,SAAO,IAAI,QAAQ,KAAK,EACrB;AAAA,IACC;AAAA,EACF,EACC;AAAA,IACC;AAAA,IACA;AAAA,EACF,EACC;AAAA,IACC;AAAA,IACA;AAAA,EACF,EACC,OAAO,OAAO,SAA8C;AAC3D,QAAI,CAAC,KAAK,OAAO;AACf;AAAA,QACE,IAAI;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,QAAI,QAAQ,MAAM,OAAO;AACvB;AAAA,QACE,IAAI;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,UAAM,MAAM,MAAM,UAAU;AAC5B,QAAI,CAAC,IAAI,KAAK,GAAG;AACf;AAAA,QACE,IAAI;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,QAAI;AACJ,QAAI;AAEJ,QAAI,KAAK,MAAM;AACb,UAAI;AACJ,UAAI;AACF,iBAAS,KAAK,MAAM,GAAG;AAAA,MACzB,SAAS,UAAU;AACjB;AAAA,UACE,IAAI,gBAAgB,6BAA6B;AAAA,YAC/C,YACE,oBAAoB,QAAQ,SAAS,UAAU,OAAO,QAAQ;AAAA,UAClE,CAAC;AAAA,QACH;AAAA,MACF;AACA,UAAI,CAAC,UAAU,OAAO,WAAW,UAAU;AACzC;AAAA,UACE,IAAI;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AACA,YAAM,IAAI;AACV,UAAI,OAAO,EAAE,UAAU,YAAY,CAAC,EAAE,OAAO;AAC3C;AAAA,UACE,IAAI,gBAAgB,4CAA4C;AAAA,QAClE;AAAA,MACF;AACA,cAAQ,EAAE;AACV,UAAI,OAAO,EAAE,WAAW,SAAU,UAAS,EAAE;AAAA,eACpC,OAAO,EAAE,YAAY,SAAU,UAAS,EAAE;AAAA,IACrD,OAAO;AAEL,cAAQ,IAAI,KAAK;AAAA,IACnB;AAIA,UAAM,YAAY,SAAS;AAC3B,UAAM,aAAa,UAAU;AAE7B,aAAS,KAAK;AACd,QAAI,OAAQ,WAAU,MAAM;AAI5B,QAAI;AACF,YAAM,IAAI,cAAc,EAAE,OAAO,EAAE,CAAC;AAAA,IACtC,SAAS,KAAK;AACZ,UAAI,UAAW,UAAS,SAAS;AAAA,UAC5B,YAAW;AAChB,UAAI,OAAQ,WAAU,UAAU;AAChC,UAAI,GAAG;AAAA,IACT;AAEA,UAAM,UAAU,GAAG,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,MAAM,MAAM,EAAE,CAAC;AACzD;AAAA,MACE,EAAE,OAAO,SAAS,QAAQ,eAAe,GAAG,QAAQ,WAAW,EAAE;AAAA,MACjE,MACEA,OAAM,MAAM,QAAG,IACf,kBAAkB,OAAO,cAAcA,OAAM,IAAI,WAAW,CAAC,CAAC;AAAA,IAClE;AAAA,EACF,CAAC;AACL;AAEA,SAAS,YAA6B;AACpC,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,UAAM,SAAmB,CAAC;AAC1B,YAAQ,MAAM,GAAG,QAAQ,CAAC,MAAM,OAAO,KAAK,CAAC,CAAC;AAC9C,YAAQ,MAAM,GAAG,OAAO,MAAM,QAAQ,OAAO,OAAO,MAAM,EAAE,SAAS,MAAM,CAAC,CAAC;AAC7E,YAAQ,MAAM,GAAG,SAAS,MAAM;AAAA,EAClC,CAAC;AACH;AAEA,eAAe,eAAe,OAA8B;AAC1D,QAAM,YAAY,SAAS;AAC3B,WAAS,MAAM,KAAK,CAAC;AACrB,MAAI;AACF,UAAM,IAAI,cAAc,EAAE,OAAO,EAAE,CAAC;AAAA,EACtC,SAAS,KAAK;AACZ,QAAI,UAAW,UAAS,SAAS;AAAA,QAC5B,YAAW;AAChB,QAAI,eAAe,cAAc;AAC/B;AAAA,QACE;AAAA,QACA;AAAA,qBAAwB,UAAU,CAAC;AAAA;AAAA;AAAA,MAGrC;AAAA,IACF;AACA,UAAM;AAAA,EACR;AACA;AAAA,IACE,EAAE,QAAQ,UAAU,GAAG,QAAQ,WAAW,EAAE;AAAA,IAC5C,MACEA,OAAM,MAAM,QAAG,IACf,iBAAiBA,OAAM,KAAK,UAAU,CAAC,CAAC,aAAaA,OAAM,IAAI,WAAW,CAAC,CAAC;AAAA,EAChF;AACF;AAQA,SAAS,mBAAmB,KAAc,MAAqB;AAC7D,QAAM,KAAK,YAAY,GAAG;AAC1B,MAAI,WAAW,EAAE,MAAM;AACrB,YAAQ,OAAO;AAAA,MACb,KAAK,UAAU,EAAE,IAAI,OAAO,OAAO,GAAG,KAAK,MAAM,CAAC,IAAI;AAAA,IACxD;AAAA,EACF,OAAO;AACL,YAAQ,OAAO,MAAM,GAAG,QAAQA,OAAM,IAAI,IAAI,IAAI,IAAI;AAAA,EACxD;AACA,UAAQ,KAAK,GAAG,QAAQ;AAC1B;AAEA,eAAe,oBACb,QACA,EAAE,YAAY,GACC;AACf,QAAM,SAAS,aAAa;AAC5B,QAAM,gBAAgB,OAAO,SAAS,EAAE,QAAQ,OAAO,EAAE;AACzD,QAAM,kBAAkB,IAAI,cAAc,aAAa,EAAE,EAAE,MAAM;AACjE,MAAI;AACJ,MAAI;AACF,SAAK,MAAM,SAAS,MAAM;AAAA,EAC5B,SAAS,KAAK;AACZ,oBAAgB,KAAK;AACrB;AAAA,MACE;AAAA,MACA;AAAA,YAAe,aAAa;AAAA;AAAA;AAAA,IAG9B;AAAA,EACF;AACA,kBAAgB,QAAQ,cAAc,GAAG,MAAM,EAAE;AAEjD,QAAM,cAAc,IAAI,iCAAiC,EAAE,MAAM;AACjE,MAAI;AACJ,MAAI;AACF,WAAO,MAAM,2BAA2B,IAAI,MAAM;AAAA,EACpD,SAAS,KAAK;AACZ,gBAAY,KAAK;AACjB,UAAM;AAAA,EACR;AACA,cAAY,QAAQ,iBAAiB;AAErC,QAAM,SAAS,KAAK,6BAA6B,KAAK;AACtD,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,OAAOA,OAAM,KAAK,gCAAgC,CAAC;AAC/D,UAAQ,IAAI,SAASA,OAAM,KAAK,MAAM,CAAC;AACvC,UAAQ,IAAI,OAAOA,OAAM,KAAK,kCAAkC,CAAC;AACjE,UAAQ,IAAI,SAASA,OAAM,KAAKA,OAAM,OAAO,KAAK,SAAS,CAAC,CAAC;AAC7D,UAAQ,IAAI,EAAE;AAEd,MAAI,aAAa;AACf,UAAM,eAAe,MAAM;AAAA,EAC7B;AAEA,QAAM,cAAc,IAAI,iDAA4C,EAAE,MAAM;AAC5E,MAAI;AACJ,MAAI;AACF,YAAQ,MAAM,aAAa,IAAI,KAAK,aAAa;AAAA,MAC/C,UAAU,KAAK,YAAY;AAAA,MAC3B,WAAW,KAAK;AAAA,IAClB,CAAC;AAAA,EACH,SAAS,KAAK;AACZ,gBAAY,KAAK;AACjB,UAAM;AAAA,EACR;AACA,cAAY,QAAQ,sBAAsB;AAE1C,QAAM,YAAY,SAAS;AAC3B,WAAS,MAAM,YAAY;AAG3B,MAAI;AACF,UAAM,IAAI,cAAc,EAAE,OAAO,EAAE,CAAC;AAAA,EACtC,SAAS,KAAK;AACZ,QAAI,UAAW,UAAS,SAAS;AAAA,QAC5B,YAAW;AAChB,UAAM;AAAA,EACR;AAEA,QAAM,YAAY,MAAM,cAAc;AACtC,QAAM,cAAc,aAAa,SAAS;AAC1C;AAAA,IACE;AAAA,MACE,QAAQ,UAAU;AAAA,MAClB,QAAQ,WAAW;AAAA,MACnB,GAAI,MAAM,QAAQ,EAAE,QAAQ,MAAM,MAAM,MAAM,GAAG,EAAE,IAAI,CAAC;AAAA,MACxD,GAAI,aAAa,OAAO,EAAE,YAAY,UAAU,IAAI,CAAC;AAAA,IACvD;AAAA,IACA,MAAM;AACJ,YAAM,QAAQ;AAAA,QACZA,OAAM,MAAM,QAAG,IACb,iBAAiBA,OAAM,KAAK,UAAU,CAAC,CAAC,aAAaA,OAAM,IAAI,WAAW,CAAC,CAAC;AAAA,MAChF;AACA,UAAI,MAAM,MAAO,OAAM,KAAKA,OAAM,IAAI,aAAa,MAAM,KAAK,EAAE,CAAC;AACjE,UAAI,aAAa;AAEf,cAAM;AAAA,UACJA,OAAM;AAAA,YACJ,6CAA6C,WAAW;AAAA,UAC1D;AAAA,QACF;AAAA,MACF;AACA,aAAO,MAAM,KAAK,IAAI;AAAA,IACxB;AAAA,EACF;AACF;AAEA,SAAS,aAAa,kBAAgD;AACpE,MAAI,oBAAoB,KAAM,QAAO;AACrC,QAAM,OAAO,KAAK,MAAM,mBAAmB,KAAM;AACjD,MAAI,QAAQ,EAAG,QAAO,GAAG,IAAI;AAC7B,QAAM,QAAQ,KAAK,MAAM,mBAAmB,IAAI;AAChD,MAAI,SAAS,EAAG,QAAO,GAAG,KAAK;AAC/B,SAAO,GAAG,gBAAgB;AAC5B;;;AEzYA,OAAOC,YAAW;AAWlB,IAAM,aAAa,CAAC,SAAS;AAG7B,SAAS,QAAQ,KAA8B;AAC7C,SAAQ,WAAiC,SAAS,GAAG;AACvD;AAEO,SAAS,uBAAuBC,UAAwB;AAC7D,QAAM,MAAMA,SAAQ,QAAQ,QAAQ,EAAE,YAAY,0BAA0B;AAE5E,MACG,QAAQ,WAAW,EACnB,YAAY,gCAAgC,EAC5C,OAAO,CAAC,QAAiB;AACxB,UAAM,MAAM,OAAO;AACnB,QAAI,CAAC,KAAK;AACR,cAAQ,IAAI,GAAGC,OAAM,IAAI,OAAO,WAAW,CAAC,CAAC,EAAE;AAC/C,cAAQ,IAAI,YAAY,IAAI,UAAU,EAAE,EAAE;AAC1C,cAAQ,IAAI,YAAY,IAAI,QAAQ,UAAU,WAAW,EAAE;AAC3D;AAAA,IACF;AACA,QAAI,CAAC,QAAQ,GAAG,EAAG,QAAO,IAAI,IAAI,MAAM,gBAAgB,GAAG,EAAE,CAAC;AAC9D,QAAI,QAAQ,UAAW,SAAQ,IAAI,IAAI,UAAU,EAAE;AAAA,EACrD,CAAC;AAEH,MACG,QAAQ,mBAAmB,EAC3B,YAAY,mCAAmC,WAAW,KAAK,IAAI,CAAC,EAAE,EACtE,OAAO,CAAC,KAAa,UAAkB;AACtC,QAAI,CAAC,QAAQ,GAAG,EAAG,QAAO,IAAI,IAAI,MAAM,gBAAgB,GAAG,EAAE,CAAC;AAC9D,QAAI,QAAQ,UAAW,WAAU,KAAK;AACtC,YAAQ,IAAIA,OAAM,MAAM,QAAG,IAAI,IAAI,GAAG,MAAM,KAAK,EAAE;AAAA,EACrD,CAAC;AAEH,MACG,QAAQ,aAAa,EACrB,YAAY,sBAAsB,EAClC,OAAO,CAAC,QAAgB;AACvB,QAAI,CAAC,QAAQ,GAAG,EAAG,QAAO,IAAI,IAAI,MAAM,gBAAgB,GAAG,EAAE,CAAC;AAC9D,QAAI,QAAQ,UAAW,WAAU,QAAQ;AACzC,YAAQ,IAAIA,OAAM,MAAM,QAAG,IAAI,IAAI,GAAG,QAAQ;AAAA,EAChD,CAAC;AACL;;;ACrDA,OAAOC,YAAW;;;ACAlB,SAAS,gBAAAC,qBAAoB;AAY7B,IAAM,aAAiD;AAAA,EACrD,UAAU;AAAA,EACV,mBAAmB;AAAA,EACnB,QAAQ;AAAA,EACR,iBAAiB;AACnB;AAEA,SAAS,MAAM,GAAuB,MAAc,UAA4B;AAC9E,MAAI,MAAM,OAAW,QAAO;AAC5B,QAAM,OAAO,EAAE,YAAY;AAC3B,MAAI,SAAS,KAAM,QAAO;AAC1B,MAAI,SAAS,MAAO,QAAO;AAC3B,QAAM,IAAI;AAAA,IACR,qBAAqB,IAAI,KAAK,KAAK,UAAU,CAAC,CAAC;AAAA,EACjD;AACF;AAKO,SAAS,uBAAuB,MAA6C;AAClF,MAAI,KAAK,QAAQ,KAAK,MAAM;AAC1B,UAAM,IAAI,MAAM,yCAAyC;AAAA,EAC3D;AAEA,MAAI,KAAK,MAAM;AACb,QAAI;AACJ,QAAI;AACF,YAAMA,cAAa,KAAK,MAAM,MAAM;AAAA,IACtC,SAAS,KAAK;AACZ,YAAM,IAAI;AAAA,QACR,kBAAkB,KAAK,IAAI,KAAK,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,MAClF;AAAA,IACF;AACA,QAAI;AACJ,QAAI;AACF,eAAS,KAAK,MAAM,GAAG;AAAA,IACzB,QAAQ;AACN,YAAM,IAAI,MAAM,GAAG,KAAK,IAAI,qBAAqB;AAAA,IACnD;AACA,QAAI,CAAC,MAAM,QAAQ,MAAM,GAAG;AAC1B,YAAM,IAAI;AAAA,QACR,GAAG,KAAK,IAAI;AAAA,MACd;AAAA,IACF;AACA,WAAO,OAAO,IAAI,CAAC,OAAO,MAAM;AAC9B,YAAM,IAAI;AACV,YAAM,WAAW,WAAW,OAAO,EAAE,SAAS,CAAC;AAC/C,UAAI,OAAO,EAAE,YAAY,YAAY,CAAC,EAAE,SAAS;AAC/C,cAAM,IAAI,MAAM,SAAS,CAAC,+BAA+B;AAAA,MAC3D;AACA,UAAI,CAAC,UAAU;AACb,cAAM,IAAI;AAAA,UACR,SAAS,CAAC,uBAAuB,KAAK,UAAU,EAAE,SAAS,CAAC;AAAA,QAC9D;AAAA,MACF;AACA,UAAI,OAAO,EAAE,aAAa,aAAa,OAAO,EAAE,iBAAiB,WAAW;AAC1E,cAAM,IAAI,MAAM,SAAS,CAAC,+CAA+C;AAAA,MAC3E;AACA,aAAO;AAAA,QACL,SAAS,EAAE;AAAA,QACX,WAAW;AAAA,QACX,UAAU,EAAE;AAAA,QACZ,cAAc,EAAE;AAAA,MAClB;AAAA,IACF,CAAC;AAAA,EACH;AAEA,MAAI,KAAK,MAAM;AACb,UAAM,WAAW,WAAW,OAAO,KAAK,QAAQ,EAAE,CAAC;AACnD,QAAI,CAAC,UAAU;AACb,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AACA,WAAO;AAAA,MACL;AAAA,QACE,SAAS,KAAK;AAAA,QACd,WAAW;AAAA,QACX,UAAU,MAAM,KAAK,MAAM,UAAU,IAAI;AAAA,QACzC,cAAc,MAAM,KAAK,UAAU,cAAc,KAAK;AAAA,MACxD;AAAA,IACF;AAAA,EACF;AAEA,QAAM,IAAI;AAAA,IACR;AAAA,EACF;AACF;;;AD5FO,SAAS,0BAA0BC,UAAwB;AAChE,QAAM,KAAKA,SACR,QAAQ,WAAW,EACnB,MAAM,IAAI,EACV,YAAY,kBAAkB;AAEjC,KACG,QAAQ,MAAM,EACd,YAAY,gBAAgB,EAC5B,OAAO,mBAAmB,uBAAuB,IAAI,EACrD,OAAO,qBAAqB,mBAAmB,EAC/C,OAAO,2BAA2B,yBAAyB,EAC3D,OAAO,UAAU,sDAAsD,EACvE;AAAA,IACC,OAAO,SAKD;AACJ,UAAI,KAAK,KAAM,YAAW,EAAE,MAAM,KAAK,CAAC;AACxC,UAAI;AACF,cAAM,MAAM,MAAM,IAAI,cAAc;AAAA,UAClC,OAAO,KAAK,QAAQ,OAAO,KAAK,KAAK,IAAI;AAAA,UACzC,QAAQ,KAAK;AAAA,UACb,OAAO,KAAK;AAAA,QACd,CAAC;AACD,aAAK,KAAK,MAAM;AACd,gBAAM,OAAO,IAAI,KAAK,IAAI,CAAC,OAAO;AAAA,YAChC,IAAI,EAAE;AAAA,YACN,MAAMC,UAAS,EAAE,MAAM,EAAE;AAAA,YACzB,MAAM,OAAO,EAAE,cAAc;AAAA,YAC7B,SAAS,OAAO,EAAE,YAAY;AAAA,YAC9B,SAAS,EAAE,QAAQ,MAAM,GAAG,EAAE;AAAA,UAChC,EAAE;AACF,gBAAM,MAAM,MAAM,MAAM,CAAC,MAAM,QAAQ,QAAQ,WAAW,SAAS,CAAC;AACpE,iBAAO,IAAI,cACP,MAAMC,OAAM,IAAI;AAAA;AAAA,yBAA8B,IAAI,WAAW,EAAE,IAC/D;AAAA,QACN,CAAC;AAAA,MACH,SAAS,KAAK;AACZ,YAAI,GAAG;AAAA,MACT;AAAA,IACF;AAAA,EACF;AAEF,KACG,QAAQ,UAAU,EAClB;AAAA,IACC;AAAA,EACF,EACC,OAAO,OAAO,OAAe;AAC5B,QAAI;AACF,YAAM,OAAO,MAAM,IAAI,YAAY,EAAE;AACrC,WAAK,MAAM,MAAM,KAAK,IAAI,CAAC;AAAA,IAC7B,SAAS,KAAK;AACZ,UAAI,GAAG;AAAA,IACT;AAAA,EACF,CAAC;AAEH,KACG,QAAQ,QAAQ,EAChB,YAAY,+BAA+B,EAC3C,eAAe,qBAAqB,eAAe,EACnD;AAAA,IACC;AAAA,IACA;AAAA,EACF,EACC,OAAO,4BAA4B,4BAA4B,EAC/D;AAAA,IACC,OAAO,SAID;AACJ,UAAI;AACF,cAAM,OAAO,MAAM,IAAI,eAAe;AAAA,UACpC,MAAM,KAAK;AAAA,UACX,eAAe,KAAK;AAAA,UACpB,aAAa,KAAK;AAAA,QACpB,CAAC;AACD;AAAA,UACE;AAAA,UACA,MACEA,OAAM,MAAM,QAAG,IACf,sBAAsBA,OAAM,KAAK,KAAK,GAAG,CAAC;AAAA,IAC1C,KAAK,IAAI;AAAA,QACb;AAAA,MACF,SAAS,KAAK;AACZ,YAAI,GAAG;AAAA,MACT;AAAA,IACF;AAAA,EACF;AAEF,KACG,QAAQ,aAAa,EACrB;AAAA,IACC;AAAA,EACF,EACC,OAAO,mBAAmB,EAC1B,OAAO,0BAA0B,iCAAiC,EAClE,OAAO,4BAA4B,iCAAiC,EACpE,OAAO,4BAA4B,8BAA8B,EACjE;AAAA,IACC,OACE,IACA,SAMG;AACH,UAAI;AACF,cAAM,OAAiD,CAAC;AACxD,YAAI,KAAK,SAAS,OAAW,MAAK,OAAO,KAAK;AAC9C,YAAI,KAAK,iBAAiB;AACxB,eAAK,gBAAgB,KAAK,iBAAiB,KAAK,OAAO,KAAK;AAC9D,YAAI,KAAK,gBAAgB;AACvB,eAAK,cAAc,KAAK,gBAAgB,KAAK,OAAO,KAAK;AAC3D,cAAM,MAAM,CACV,GACA,SACwB;AACxB,cAAI,MAAM,OAAW,QAAO;AAC5B,gBAAM,OAAO,EAAE,YAAY;AAC3B,cAAI,SAAS,KAAM,QAAO;AAC1B,cAAI,SAAS,MAAO,QAAO;AAC3B,gBAAM,IAAI;AAAA,YACR,qBAAqB,IAAI,KAAK,KAAK,UAAU,CAAC,CAAC;AAAA,UACjD;AAAA,QACF;AACA,cAAM,OAAO,IAAI,KAAK,cAAc,iBAAiB;AACrD,YAAI,SAAS,OAAW,MAAK,sBAAsB;AAEnD,YAAI,OAAO,KAAK,IAAI,EAAE,WAAW,GAAG;AAClC,gBAAM,IAAI;AAAA,YACR;AAAA,UACF;AAAA,QACF;AACA,cAAM,OAAO,MAAM,IAAI,eAAe,IAAI,IAAI;AAC9C;AAAA,UACE;AAAA,UACA,MACEA,OAAM,MAAM,QAAG,IACf,sBAAsBA,OAAM,KAAK,KAAK,GAAG,CAAC;AAAA,IAC1C,KAAK,IAAI;AAAA,QACb;AAAA,MACF,SAAS,KAAK;AACZ,YAAI,GAAG;AAAA,MACT;AAAA,IACF;AAAA,EACF;AAEF,KACG,QAAQ,YAAY,EACpB;AAAA,IACC;AAAA,EACF,EACC,OAAO,mBAAmB,uBAAuB,IAAI,EACrD,OAAO,qBAAqB,mBAAmB,EAC/C,OAAO,UAAU,sDAAsD,EACvE;AAAA,IACC,OACE,IACA,SACG;AACH,UAAI,KAAK,KAAM,YAAW,EAAE,MAAM,KAAK,CAAC;AACxC,UAAI;AACF,cAAM,MAAM,MAAM,IAAI,UAAU;AAAA,UAC9B,aAAa;AAAA,UACb,OAAO,KAAK,QAAQ,OAAO,KAAK,KAAK,IAAI;AAAA,UACzC,QAAQ,KAAK;AAAA,QACf,CAAC;AACD,aAAK,KAAK,MAAM;AACd,gBAAM,OAAO,IAAI,KAAK,IAAI,CAAC,OAAO;AAAA,YAChC,IAAI,EAAE;AAAA,YACN,MAAMD,UAAS,EAAE,QAAQ,IAAI,EAAE;AAAA,YAC/B,KAAKA,UAAS,EAAE,KAAK,EAAE;AAAA,YACvB,UAAU,EAAE,wBAAwB,QAAQ;AAAA,YAC5C,SAAS,EAAE,aAAa,EAAE,WAAW,MAAM,GAAG,EAAE,IAAI;AAAA,UACtD,EAAE;AACF,gBAAM,MAAM,MAAM,MAAM,CAAC,MAAM,QAAQ,OAAO,YAAY,SAAS,CAAC;AACpE,iBAAO,IAAI,cACP,MAAMC,OAAM,IAAI;AAAA;AAAA,yBAA8B,IAAI,WAAW,EAAE,IAC/D;AAAA,QACN,CAAC;AAAA,MACH,SAAS,KAAK;AACZ,YAAI,GAAG;AAAA,MACT;AAAA,IACF;AAAA,EACF;AAEF,KACG,QAAQ,cAAc,EACtB;AAAA,IACC;AAAA,EACF,EACC,OAAO,mBAAmB,uBAAuB,IAAI,EACrD,OAAO,qBAAqB,mBAAmB,EAC/C,OAAO,mBAAmB,0CAA0C,EACpE,OAAO,UAAU,sDAAsD,EACvE;AAAA,IACC,OACE,IACA,SAMG;AACH,UAAI,KAAK,KAAM,YAAW,EAAE,MAAM,KAAK,CAAC;AACxC,UAAI;AACF,cAAM,MAAM,MAAM,IAAI,aAAa;AAAA,UACjC,aAAa;AAAA,UACb,OAAO,KAAK,QAAQ,OAAO,KAAK,KAAK,IAAI;AAAA,UACzC,QAAQ,KAAK;AAAA,UACb,OAAO,KAAK;AAAA,QACd,CAAC;AACD,aAAK,KAAK,MAAM;AACd,gBAAM,OAAO,IAAI,KAAK,IAAI,CAAC,OAAO;AAAA,YAChC,IAAI,EAAE;AAAA,YACN,OAAO,oBAAoB,EAAE,KAAK;AAAA,YAClC,UAAU,EAAE,WAAW,QAAQ;AAAA,YAC/B,OAAO,OAAO,EAAE,WAAW;AAAA,YAC3B,WAAW,EAAE,gBAAgB,MAAM,GAAG,EAAE,KAAK;AAAA,UAC/C,EAAE;AACF,gBAAM,MAAM,MAAM,MAAM,CAAC,MAAM,SAAS,YAAY,SAAS,WAAW,CAAC;AACzE,iBAAO,IAAI,cACP,MAAMA,OAAM,IAAI;AAAA;AAAA,yBAA8B,IAAI,WAAW,EAAE,IAC/D;AAAA,QACN,CAAC;AAAA,MACH,SAAS,KAAK;AACZ,YAAI,GAAG;AAAA,MACT;AAAA,IACF;AAAA,EACF;AAEF,KACG,QAAQ,YAAY,EACpB,MAAM,WAAW,EACjB;AAAA,IACC;AAAA,EACF,EACC;AAAA,IACC;AAAA,IACA;AAAA,IACA,CAAC,MAAM,OAAO,CAAC;AAAA,EACjB,EACC;AAAA,IACC;AAAA,IACA;AAAA,IACA,CAAC,MAAM,OAAO,CAAC;AAAA,EACjB,EACC,OAAO,UAAU,sDAAsD,EACvE;AAAA,IACC,OACE,IACA,SACG;AACH,UAAI,KAAK,KAAM,YAAW,EAAE,MAAM,KAAK,CAAC;AACxC,UAAI;AACF,cAAM,QAAQ,MAAM,IAAI,kBAAkB,IAAI;AAAA,UAC5C,OAAO,KAAK;AAAA,UACZ,OAAO,KAAK;AAAA,QACd,CAAC;AACD,aAAK,OAAO,MAAM;AAChB,gBAAM,UAAU,KAAK,MAAM,MAAM,yBAAyB,EAAE;AAC5D,iBAAO;AAAA,YACL,GAAGA,OAAM,KAAK,WAAW,CAAC,WAAW,MAAM,WAAW;AAAA,YACtD,GAAGA,OAAM,KAAK,cAAc,CAAC,OAAO,MAAM,WAAW;AAAA,YACrD,GAAGA,OAAM,KAAK,iBAAiB,CAAC,IAAI,MAAM,cAAc;AAAA,YACxD,GAAGA,OAAM,KAAK,kBAAkB,CAAC,IAAI,OAAO,SAAS,MAAM,uBAAuB,QAAQ,CAAC,CAAC;AAAA,YAC5FA,OAAM;AAAA,cACJ,WAAW,MAAM,MAAM,MAAM,GAAG,EAAE,CAAC,WAAM,MAAM,MAAM,MAAM,GAAG,EAAE,CAAC;AAAA,YACnE;AAAA,UACF,EAAE,KAAK,IAAI;AAAA,QACb,CAAC;AAAA,MACH,SAAS,KAAK;AACZ,YAAI,GAAG;AAAA,MACT;AAAA,IACF;AAAA,EACF;AAEF,KACG,QAAQ,aAAa,EACrB;AAAA,IACC;AAAA,EACF,EACC,OAAO,OAAO,OAAe;AAC5B,QAAI;AACF,YAAM,UAAU,MAAM,IAAI,eAAe,EAAE;AAC3C;AAAA,QACE;AAAA,QACA,MAAMA,OAAM,MAAM,QAAG,IAAI,aAAa,EAAE;AAAA,MAC1C;AAAA,IACF,SAAS,KAAK;AACZ,UAAI,GAAG;AAAA,IACT;AAAA,EACF,CAAC;AAEH,KACG,QAAQ,aAAa,EACrB;AAAA,IACC;AAAA,EACF,EACC,eAAe,mBAAmB,uBAAuB,EACzD;AAAA,IACC;AAAA,IACA;AAAA,EACF,EACC;AAAA,IACC,OACE,IACA,SACG;AACH,UAAI;AACF,cAAM,OAAO,MAAM,IAAI,uBAAuB,IAAI;AAAA,UAChD,aAAa,KAAK;AAAA,UAClB,WAAW,KAAK;AAAA,QAClB,CAAC;AACD;AAAA,UACE;AAAA,UACA,MACEA,OAAM,MAAM,QAAG,IACf,sBAAsBA,OAAM,KAAK,KAAK,WAAW,CAAC,YAAYA,OAAM,KAAK,KAAK,EAAE,CAAC;AAAA,IACjF,KAAK,IAAI;AAAA,QACb;AAAA,MACF,SAAS,KAAK;AACZ,YAAI,GAAG;AAAA,MACT;AAAA,IACF;AAAA,EACF;AAEF,KACG,QAAQ,oBAAoB,EAC5B;AAAA,IACC;AAAA,EACF,EACC,OAAO,OAAO,IAAY,SAAiB;AAC1C,QAAI;AACF,YAAM,UAAU,MAAM,IAAI,uBAAuB,IAAI,IAAI;AACzD;AAAA,QACE;AAAA,QACA,MAAMA,OAAM,MAAM,QAAG,IAAI,aAAa,IAAI;AAAA,MAC5C;AAAA,IACF,SAAS,KAAK;AACZ,UAAI,GAAG;AAAA,IACT;AAAA,EACF,CAAC;AAEH,KACG,QAAQ,kBAAkB,EAC1B;AAAA,IACC;AAAA,EACF,EACC;AAAA,IACC;AAAA,IACA;AAAA,EACF,EACC,OAAO,UAAU,wDAAwD,EACzE;AAAA,IACC,OACE,IACA,MACA,SACG;AACH,UAAI;AAEF,cAAM,eACJ,KAAK,aAAa,MAAM,KAAK,aAAa;AAC5C,YAAI,KAAK,QAAQ,KAAK,aAAa,UAAa,CAAC,cAAc;AAC7D,gBAAM,IAAI;AAAA,YACR;AAAA,UACF;AAAA,QACF;AACA,YAAI,CAAC,KAAK,QAAQ,KAAK,aAAa,QAAW;AAC7C,gBAAM,IAAI;AAAA,YACR;AAAA,UACF;AAAA,QACF;AACA,cAAM,YAAY,KAAK,QAAQ,eAAe,OAAO,KAAK;AAC1D,cAAM,OAAO,MAAM,IAAI,qBAAqB,IAAI,MAAM,EAAE,UAAU,CAAC;AACnE;AAAA,UACE;AAAA,UACA,MACEA,OAAM,MAAM,QAAG,IACf,mBACE,KAAK,cACD,gBAAgBA,OAAM,KAAK,KAAK,WAAW,CAAC,KAC5C,4BACN;AAAA,IACA,KAAK,IAAI;AAAA,QACb;AAAA,MACF,SAAS,KAAK;AACZ,YAAI,GAAG;AAAA,MACT;AAAA,IACF;AAAA,EACF;AAGF,QAAM,WAAW,GACd,QAAQ,QAAQ,EAChB;AAAA,IACC;AAAA,EACF;AAEF,WACG,QAAQ,WAAW,EACnB,YAAY,kCAAkC,EAC9C,OAAO,mBAAmB,uBAAuB,IAAI,EACrD,OAAO,qBAAqB,mBAAmB,EAC/C,OAAO,UAAU,iBAAiB,EAClC;AAAA,IACC,OACE,IACA,SACG;AACH,UAAI,KAAK,KAAM,YAAW,EAAE,MAAM,KAAK,CAAC;AACxC,UAAI;AACF,cAAM,MAAM,MAAM,IAAI,mBAAmB,IAAI;AAAA,UAC3C,OAAO,KAAK,QAAQ,OAAO,KAAK,KAAK,IAAI;AAAA,UACzC,QAAQ,KAAK;AAAA,QACf,CAAC;AACD,aAAK,KAAK,MAAM;AACd,gBAAM,OAAO,IAAI,KAAK,IAAI,CAAC,OAAO;AAAA,YAChC,IAAI,EAAE;AAAA,YACN,MAAMD,UAAS,EAAE,MAAM,EAAE;AAAA,YACzB,SAAS,OAAO,EAAE,YAAY;AAAA,YAC9B,OAAO,OAAO,EAAE,UAAU;AAAA,YAC1B,SAASA,UAAS,EAAE,QAAQ,KAAK,GAAG,GAAG,EAAE;AAAA,YACzC,WAAW,EAAE,YAAY,QAAQ;AAAA,UACnC,EAAE;AACF,gBAAM,MAAM,MAAM,MAAM;AAAA,YACtB;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UACF,CAAC;AACD,iBAAO,IAAI,cACP,MAAMC,OAAM,IAAI;AAAA;AAAA,yBAA8B,IAAI,WAAW,EAAE,IAC/D;AAAA,QACN,CAAC;AAAA,MACH,SAAS,KAAK;AACZ,YAAI,GAAG;AAAA,MACT;AAAA,IACF;AAAA,EACF;AAEF,WACG,QAAQ,gBAAgB,EACxB,YAAY,wBAAwB,EACpC,OAAO,OAAO,IAAY,QAAgB;AACzC,QAAI;AACF,YAAM,IAAI,MAAM,IAAI,iBAAiB,IAAI,GAAG;AAC5C,WAAK,GAAG,MAAM,KAAK,CAAC,CAAC;AAAA,IACvB,SAAS,KAAK;AACZ,UAAI,GAAG;AAAA,IACT;AAAA,EACF,CAAC;AAEH,WACG,QAAQ,aAAa,EACrB,YAAY,qCAAqC,EACjD,eAAe,qBAAqB,YAAY,EAChD;AAAA,IACC;AAAA,IACA;AAAA,EACF,EACC;AAAA,IACC;AAAA,IACA;AAAA,IACA;AAAA,EACF,EACC;AAAA,IACC,OACE,IACA,SACG;AACH,UAAI;AACF,cAAM,IAAI,MAAM,IAAI,oBAAoB,IAAI;AAAA,UAC1C,MAAM,KAAK;AAAA,UACX,WAAW,KAAK,YAAY;AAAA,UAC5B,SAAS,KAAK,UACV,KAAK,QAAQ,MAAM,GAAG,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,OAAO,IAC3D;AAAA,QACN,CAAC;AACD;AAAA,UACE;AAAA,UACA,MACEA,OAAM,MAAM,QAAG,IACf,mBAAmBA,OAAM,KAAK,EAAE,EAAE,CAAC;AAAA,IACnC,KAAK,CAAC;AAAA,QACV;AAAA,MACF,SAAS,KAAK;AACZ,YAAI,GAAG;AAAA,MACT;AAAA,IACF;AAAA,EACF;AAEF,WACG,QAAQ,mBAAmB,EAC3B,YAAY,uBAAuB,EACnC,OAAO,mBAAmB,EAC1B;AAAA,IACC;AAAA,IACA;AAAA,EACF,EACC,OAAO,wBAAwB,8BAA8B,EAC7D;AAAA,IACC,OACE,IACA,KACA,SACG;AACH,UAAI;AACF,cAAM,OAAsD,CAAC;AAC7D,YAAI,KAAK,SAAS,OAAW,MAAK,OAAO,KAAK;AAC9C,YAAI,KAAK,YAAY;AACnB,eAAK,UACH,KAAK,YAAY,KACb,CAAC,IACD,KAAK,QAAQ,MAAM,GAAG,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,OAAO;AACnE,YAAI,KAAK,aAAa,QAAW;AAC/B,gBAAM,OAAO,KAAK,SAAS,YAAY;AACvC,cAAI,SAAS,QAAQ,SAAS,OAAO;AACnC,kBAAM,IAAI;AAAA,cACR,kCAAkC,KAAK,UAAU,KAAK,QAAQ,CAAC;AAAA,YACjE;AAAA,UACF;AACA,eAAK,YAAY,SAAS;AAAA,QAC5B;AACA,YAAI,OAAO,KAAK,IAAI,EAAE,WAAW,GAAG;AAClC,gBAAM,IAAI;AAAA,YACR;AAAA,UACF;AAAA,QACF;AACA,cAAM,IAAI,MAAM,IAAI,oBAAoB,IAAI,KAAK,IAAI;AACrD;AAAA,UACE;AAAA,UACA,MACEA,OAAM,MAAM,QAAG,IACf,mBAAmBA,OAAM,KAAK,EAAE,EAAE,CAAC;AAAA,IACnC,KAAK,CAAC;AAAA,QACV;AAAA,MACF,SAAS,KAAK;AACZ,YAAI,GAAG;AAAA,MACT;AAAA,IACF;AAAA,EACF;AAEF,WACG,QAAQ,mBAAmB,EAC3B;AAAA,IACC;AAAA,EACF,EACC,OAAO,OAAO,IAAY,QAAgB;AACzC,QAAI;AACF,YAAM,UAAU,MAAM,IAAI,oBAAoB,IAAI,GAAG;AACrD;AAAA,QACE;AAAA,QACA,MACEA,OAAM,MAAM,QAAG,IACf,UAAU,GAAG;AAAA,MACjB;AAAA,IACF,SAAS,KAAK;AACZ,UAAI,GAAG;AAAA,IACT;AAAA,EACF,CAAC;AAEH,QAAM,iBAAiB,SACpB,QAAQ,SAAS,EACjB,YAAY,gCAAgC;AAE/C,iBACG,QAAQ,iBAAiB,EACzB;AAAA,IACC;AAAA,EACF,EACC,OAAO,mBAAmB,uBAAuB,IAAI,EACrD,OAAO,qBAAqB,mBAAmB,EAC/C,OAAO,UAAU,iBAAiB,EAClC;AAAA,IACC,OACE,IACA,KACA,SACG;AACH,UAAI,KAAK,KAAM,YAAW,EAAE,MAAM,KAAK,CAAC;AACxC,UAAI;AACF,cAAM,MAAM,MAAM,IAAI,yBAAyB,IAAI,KAAK;AAAA,UACtD,OAAO,KAAK,QAAQ,OAAO,KAAK,KAAK,IAAI;AAAA,UACzC,QAAQ,KAAK;AAAA,QACf,CAAC;AACD,aAAK,KAAK,MAAM;AACd,gBAAM,OAAO,IAAI,KAAK,IAAI,CAAC,OAAO;AAAA,YAChC,IAAI,EAAE;AAAA,YACN,OAAO,oBAAoB,EAAE,KAAK;AAAA,YAClC,OAAO,EAAE,QAAQ,MAAM,GAAG,EAAE;AAAA,UAC9B,EAAE;AACF,gBAAM,MAAM,MAAM,MAAM,CAAC,MAAM,SAAS,OAAO,CAAC;AAChD,iBAAO,IAAI,cACP,MAAMA,OAAM,IAAI;AAAA;AAAA,yBAA8B,IAAI,WAAW,EAAE,IAC/D;AAAA,QACN,CAAC;AAAA,MACH,SAAS,KAAK;AACZ,YAAI,GAAG;AAAA,MACT;AAAA,IACF;AAAA,EACF;AAEF,iBACG,QAAQ,gBAAgB,EACxB;AAAA,IACC;AAAA,EACF,EACC;AAAA,IACC;AAAA,IACA;AAAA,EACF,EACC,OAAO,OAAO,IAAY,KAAa,SAA6B;AACnE,QAAI;AACF,YAAM,SAAS,KAAK,OACjB,MAAM,GAAG,EACT,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,EACnB,OAAO,OAAO;AACjB,UAAI,OAAO,WAAW,GAAG;AACvB,cAAM,IAAI,MAAM,uCAAuC;AAAA,MACzD;AACA,YAAM,MAAM,MAAM,IAAI,wBAAwB,IAAI,KAAK,EAAE,OAAO,CAAC;AACjE;AAAA,QACE;AAAA,QACA,MACEA,OAAM,MAAM,QAAG,IACf,IAAI,IAAI,KAAK,MAAM;AAAA,IACnB;AAAA,UACE,IAAI,KAAK,IAAI,CAAC,OAAO;AAAA,YACnB,IAAI,EAAE;AAAA,YACN,OAAO,oBAAoB,EAAE,KAAK;AAAA,UACpC,EAAE;AAAA,UACF,CAAC,MAAM,OAAO;AAAA,QAChB;AAAA,MACJ;AAAA,IACF,SAAS,KAAK;AACZ,UAAI,GAAG;AAAA,IACT;AAAA,EACF,CAAC;AAEH,iBACG,QAAQ,yBAAyB,EACjC;AAAA,IACC;AAAA,EACF,EACC,OAAO,OAAO,IAAY,KAAa,QAAgB;AACtD,QAAI;AACF,YAAM,UAAU,MAAM,IAAI,0BAA0B,IAAI,KAAK,GAAG;AAChE;AAAA,QACE;AAAA,QACA,MAAMA,OAAM,MAAM,QAAG,IAAI,WAAW,GAAG;AAAA,MACzC;AAAA,IACF,SAAS,KAAK;AACZ,UAAI,GAAG;AAAA,IACT;AAAA,EACF,CAAC;AAEH,QAAM,qBAAqB,SACxB,QAAQ,aAAa,EACrB,YAAY,qDAAqD;AAEpE,qBACG,QAAQ,gBAAgB,EACxB;AAAA,IACC;AAAA,EACF,EACC,OAAO,mBAAmB,uBAAuB,KAAK,EACtD,OAAO,qBAAqB,mBAAmB,EAC/C,OAAO,UAAU,iBAAiB,EAClC;AAAA,IACC,OACE,IACA,KACA,SACG;AACH,UAAI,KAAK,KAAM,YAAW,EAAE,MAAM,KAAK,CAAC;AACxC,UAAI;AACF,cAAM,MAAM,MAAM,IAAI,6BAA6B,IAAI,KAAK;AAAA,UAC1D,OAAO,KAAK,QAAQ,OAAO,KAAK,KAAK,IAAI;AAAA,UACzC,QAAQ,KAAK;AAAA,QACf,CAAC;AACD,aAAK,KAAK,MAAM;AACd,gBAAM,OAAO,IAAI,KAAK,IAAI,CAAC,OAAO;AAAA,YAChC,SAAS,EAAE;AAAA,YACX,MAAM,EAAE,cAAc,sBAAsB,aAAa;AAAA,YACzD,MAAM,EAAE,WAAW,QAAQ;AAAA,YAC3B,UAAU,EAAE,eAAe,QAAQ;AAAA,UACrC,EAAE;AACF,gBAAM,MAAM,MAAM,MAAM,CAAC,WAAW,QAAQ,QAAQ,UAAU,CAAC;AAC/D,iBAAO,IAAI,cACP,MAAMA,OAAM,IAAI;AAAA;AAAA,yBAA8B,IAAI,WAAW,EAAE,IAC/D;AAAA,QACN,CAAC;AAAA,MACH,SAAS,KAAK;AACZ,YAAI,GAAG;AAAA,MACT;AAAA,IACF;AAAA,EACF;AAEF,qBACG,QAAQ,gBAAgB,EACxB;AAAA,IACC;AAAA,EACF,EACC;AAAA,IACC;AAAA,IACA;AAAA,EACF,EACC,OAAO,mBAAmB,oDAAoD,EAC9E,OAAO,4BAA4B,sBAAsB,EACzD,OAAO,mBAAmB,4BAA4B,EACtD,OAAO,uBAAuB,iCAAiC,EAC/D;AAAA,IACC,OACE,IACA,KACA,SAOG;AACH,UAAI;AACF,cAAM,cAAc,uBAAuB,IAAI;AAC/C,cAAM,MAAM,MAAM,IAAI,4BAA4B,IAAI,KAAK;AAAA,UACzD;AAAA,QACF,CAAC;AACD;AAAA,UACE;AAAA,UACA,MACEA,OAAM,MAAM,QAAG,IACf,IAAI,IAAI,KAAK,MAAM;AAAA,IACnB;AAAA,YACE,IAAI,KAAK,IAAI,CAAC,OAAO;AAAA,cACnB,SAAS,EAAE;AAAA,cACX,MACE,EAAE,cAAc,sBAAsB,aAAa;AAAA,cACrD,MAAM,EAAE,WAAW,QAAQ;AAAA,cAC3B,UAAU,EAAE,eAAe,QAAQ;AAAA,YACrC,EAAE;AAAA,YACF,CAAC,WAAW,QAAQ,QAAQ,UAAU;AAAA,UACxC;AAAA,QACJ;AAAA,MACF,SAAS,KAAK;AACZ,YAAI,GAAG;AAAA,MACT;AAAA,IACF;AAAA,EACF;AAGF,QAAM,YAAY,GACf,QAAQ,SAAS,EACjB,YAAY,kCAAkC;AAEjD,YACG,QAAQ,WAAW,EACnB,YAAY,4BAA4B,EACxC;AAAA,IACC;AAAA,IACA;AAAA,EACF,EACC,OAAO,mBAAmB,uBAAuB,IAAI,EACrD,OAAO,qBAAqB,mBAAmB,EAC/C,OAAO,UAAU,iBAAiB,EAClC;AAAA,IACC,OACE,IACA,SAMG;AACH,UAAI,KAAK,KAAM,YAAW,EAAE,MAAM,KAAK,CAAC;AACxC,UAAI;AACF,cAAM,MAAM,MAAM,IAAI,oBAAoB,IAAI;AAAA,UAC5C,OAAO,KAAK,QAAQ,OAAO,KAAK,KAAK,IAAI;AAAA,UACzC,QAAQ,KAAK;AAAA,UACb,WAAW,KAAK;AAAA,QAClB,CAAC;AACD,aAAK,KAAK,MAAM;AACd,gBAAM,OAAO,IAAI,KAAK,IAAI,CAAC,OAAO;AAAA,YAChC,IAAI,EAAE;AAAA,YACN,MAAMD,UAAS,EAAE,MAAM,EAAE;AAAA,YACzB,MAAMA,UAAS,EAAE,MAAM,EAAE;AAAA,YACzB,MAAM,OAAO,EAAE,cAAc;AAAA,YAC7B,UAAU,OAAO,EAAE,kBAAkB;AAAA,UACvC,EAAE;AACF,gBAAM,MAAM,MAAM,MAAM,CAAC,MAAM,QAAQ,QAAQ,QAAQ,UAAU,CAAC;AAClE,iBAAO,IAAI,cACP,MAAMC,OAAM,IAAI;AAAA;AAAA,yBAA8B,IAAI,WAAW,EAAE,IAC/D;AAAA,QACN,CAAC;AAAA,MACH,SAAS,KAAK;AACZ,YAAI,GAAG;AAAA,MACT;AAAA,IACF;AAAA,EACF;AAEF,YACG,QAAQ,aAAa,EACrB,YAAY,mCAAmC,EAC/C,eAAe,qBAAqB,aAAa,EACjD,OAAO,kBAAkB,2CAA2C,EACpE,OAAO,iBAAiB,0CAA0C,EAClE,OAAO,mBAAmB,6DAA6D,EACvF;AAAA,IACC,OACE,IACA,SACG;AACH,UAAI;AACF,cAAM,IAAI,MAAM,IAAI,qBAAqB,IAAI;AAAA,UAC3C,MAAM,KAAK;AAAA,UACX,WAAW,KAAK,UAAU;AAAA,UAC1B,MAAM,KAAK;AAAA,UACX,OAAO,KAAK;AAAA,QACd,CAAC;AACD;AAAA,UACE;AAAA,UACA,MACEA,OAAM,MAAM,QAAG,IACf,6BAA6BA,OAAM,KAAK,EAAE,EAAE,CAAC;AAAA,IAC7C,KAAK,CAAC;AAAA,QACV;AAAA,MACF,SAAS,KAAK;AACZ,YAAI,GAAG;AAAA,MACT;AAAA,IACF;AAAA,EACF;AAEF,YACG,QAAQ,gBAAgB,EACxB,YAAY,2BAA2B,EACvC,OAAO,OAAO,IAAY,QAAgB;AACzC,QAAI;AACF,YAAM,IAAI,MAAM,IAAI,kBAAkB,IAAI,GAAG;AAC7C,WAAK,GAAG,MAAM,KAAK,CAAC,CAAC;AAAA,IACvB,SAAS,KAAK;AACZ,UAAI,GAAG;AAAA,IACT;AAAA,EACF,CAAC;AAEH,YACG,QAAQ,mBAAmB,EAC3B,YAAY,0BAA0B,EACtC,OAAO,mBAAmB,EAC1B,OAAO,iBAAiB,mCAAmC,EAC3D,OAAO,mBAAmB,qCAAqC,EAC/D;AAAA,IACC,OACE,IACA,KACA,SACG;AACH,UAAI;AACF,cAAM,OAAuD,CAAC;AAC9D,YAAI,KAAK,SAAS,OAAW,MAAK,OAAO,KAAK;AAC9C,YAAI,KAAK,SAAS;AAChB,eAAK,OAAQ,KAAK,SAAS,KAAK,OAAO,KAAK;AAC9C,YAAI,KAAK,UAAU;AACjB,eAAK,QAAS,KAAK,UAAU,KAAK,OAAO,KAAK;AAChD,YAAI,OAAO,KAAK,IAAI,EAAE,WAAW,GAAG;AAClC,gBAAM,IAAI;AAAA,YACR;AAAA,UACF;AAAA,QACF;AACA,cAAM,IAAI,MAAM,IAAI,qBAAqB,IAAI,KAAK,IAAI;AACtD;AAAA,UACE;AAAA,UACA,MACEA,OAAM,MAAM,QAAG,IACf,6BAA6BA,OAAM,KAAK,EAAE,EAAE,CAAC;AAAA,IAC7C,KAAK,CAAC;AAAA,QACV;AAAA,MACF,SAAS,KAAK;AACZ,YAAI,GAAG;AAAA,MACT;AAAA,IACF;AAAA,EACF;AAEF,YACG,QAAQ,mBAAmB,EAC3B,YAAY,0BAA0B,EACtC;AAAA,IACC;AAAA,IACA;AAAA,IACA;AAAA,EACF,EACC;AAAA,IACC,OAAO,IAAY,KAAa,SAAgC;AAC9D,UAAI;AACF,cAAM,UAAU,MAAM,IAAI,qBAAqB,IAAI,KAAK;AAAA,UACtD,SAAS,KAAK;AAAA,QAChB,CAAC;AACD;AAAA,UACE;AAAA,UACA,MAAMA,OAAM,MAAM,QAAG,IAAI,oBAAoB,GAAG;AAAA,QAClD;AAAA,MACF,SAAS,KAAK;AACZ,YAAI,GAAG;AAAA,MACT;AAAA,IACF;AAAA,EACF;AAEF,YACG,QAAQ,iBAAiB,EACzB,YAAY,iDAAiD,EAC7D;AAAA,IACC;AAAA,IACA;AAAA,EACF,EACC;AAAA,IACC,OAAO,IAAY,KAAa,SAA8B;AAC5D,UAAI;AACF,YAAI,KAAK,WAAW,QAAW;AAC7B,gBAAM,IAAI;AAAA,YACR;AAAA,UACF;AAAA,QACF;AACA,cAAM,YAAY,KAAK,WAAW,KAAK,OAAO,KAAK;AACnD,cAAM,IAAI,MAAM,IAAI,mBAAmB,IAAI,KAAK,EAAE,UAAU,CAAC;AAC7D;AAAA,UACE;AAAA,UACA,MACEA,OAAM,MAAM,QAAG,IACf,4BAA4BA,OAAM,KAAK,EAAE,IAAI,CAAC;AAAA,IAC9C,KAAK,CAAC;AAAA,QACV;AAAA,MACF,SAAS,KAAK;AACZ,YAAI,GAAG;AAAA,MACT;AAAA,IACF;AAAA,EACF;AAEF,KACG,QAAQ,gBAAgB,EACxB;AAAA,IACC;AAAA,EACF,EACC,OAAO,mBAAmB,uBAAuB,IAAI,EACrD,OAAO,qBAAqB,mBAAmB,EAC/C,OAAO,iBAAiB,sBAAsB,EAC9C,OAAO,UAAU,sDAAsD,EACvE;AAAA,IACC,OACE,IACA,SACG;AACH,UAAI,KAAK,KAAM,YAAW,EAAE,MAAM,KAAK,CAAC;AACxC,UAAI;AACF,cAAM,MAAM,MAAM,IAAI,sBAAsB,IAAI;AAAA,UAC9C,OAAO,KAAK,QAAQ,OAAO,KAAK,KAAK,IAAI;AAAA,UACzC,QAAQ,KAAK;AAAA,UACb,WAAW,KAAK;AAAA,QAClB,CAAC;AACD,aAAK,KAAK,MAAM;AACd,gBAAM,OAAO,IAAI,KAAK,IAAI,CAAC,QAAQ;AAAA,YACjC,IAAI,GAAG;AAAA,YACP,UAAUD,UAAS,GAAG,eAAe,EAAE;AAAA,YACvC,QAAQA,UAAS,GAAG,eAAe,KAAK,EAAE;AAAA,YAC1C,MAAM,GAAG,gBAAgB;AAAA,YACzB,OAAO,GAAG,WAAW,SAAS,KAAK;AAAA,UACrC,EAAE;AACF,gBAAM,MAAM,MAAM,MAAM,CAAC,MAAM,YAAY,UAAU,QAAQ,OAAO,CAAC;AACrE,iBAAO,IAAI,cACP,MAAMC,OAAM,IAAI;AAAA;AAAA,yBAA8B,IAAI,WAAW,EAAE,IAC/D;AAAA,QACN,CAAC;AAAA,MACH,SAAS,KAAK;AACZ,YAAI,GAAG;AAAA,MACT;AAAA,IACF;AAAA,EACF;AACJ;AAEA,SAASD,UAAS,GAAW,GAAmB;AAC9C,QAAM,QAAQ,oBAAoB,CAAC;AACnC,SAAO,MAAM,SAAS,IAAI,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,WAAM;AAC1D;;;AEz+BA,OAAOE,YAAW;AAgBX,SAAS,sBAAsBC,UAAwB;AAC5D,EAAAA,SACG,QAAQ,QAAQ,EAChB;AAAA,IACC;AAAA,EACF,EACC,OAAO,YAAY;AAClB,UAAM,SAAkB,CAAC;AAGzB,UAAM,QAAQ,SAAS;AACvB,WAAO,KAAK;AAAA,MACV,MAAM;AAAA,MACN,IAAI,QAAQ,KAAK;AAAA,MACjB,QAAQ,QACJ,wBAAwB,eAAe,CAAC,MACxC;AAAA,MACJ,MAAM,QAAQ,SAAY;AAAA,IAC5B,CAAC;AAGD,UAAM,SAAS,UAAU;AACzB,WAAO,KAAK;AAAA,MACV,MAAM;AAAA,MACN,IAAI,QAAQ,MAAM;AAAA,MAClB,QAAQ;AAAA,IACV,CAAC;AAOD,QAAI,OAAO;AACT,UAAI;AACF,cAAM,IAAI,cAAc,EAAE,OAAO,EAAE,CAAC;AACpC,eAAO,KAAK;AAAA,UACV,MAAM;AAAA,UACN,IAAI;AAAA,UACJ,QAAQ,2CAAsC,MAAM;AAAA,QACtD,CAAC;AACD,eAAO,KAAK;AAAA,UACV,MAAM;AAAA,UACN,IAAI;AAAA,UACJ,QAAQ;AAAA,QACV,CAAC;AAAA,MACH,SAAS,KAAK;AACZ,YAAI,eAAe,cAAc;AAC/B,iBAAO,KAAK;AAAA,YACV,MAAM;AAAA,YACN,IAAI;AAAA,YACJ,QAAQ,IAAI;AAAA,YACZ,MAAM;AAAA,UACR,CAAC;AAAA,QACH,WAAW,eAAe,UAAU;AAClC,gBAAM,YAAY,IAAI,WAAW,OAAO,IAAI,WAAW;AAGvD,iBAAO,KAAK;AAAA,YACV,MAAM;AAAA,YACN,IAAI;AAAA,YACJ,QAAQ,QAAQ,IAAI,MAAM,IAAI,IAAI,IAAI,KAAK,IAAI,OAAO;AAAA,UACxD,CAAC;AACD,iBAAO,KAAK;AAAA,YACV,MAAM;AAAA,YACN,IAAI,CAAC;AAAA,YACL,QAAQ,YACJ,wBAAwB,IAAI,MAAM,IAAI,IAAI,IAAI,KAC9C,4BAA4B,IAAI,MAAM,IAAI,IAAI,IAAI;AAAA,YACtD,MAAM,YACF,sCACA;AAAA,UACN,CAAC;AAAA,QACH,OAAO;AACL,iBAAO,KAAK;AAAA,YACV,MAAM;AAAA,YACN,IAAI;AAAA,YACJ,QAAQ,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,UACzD,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF,OAAO;AACL,aAAO,KAAK;AAAA,QACV,MAAM;AAAA,QACN,IAAI;AAAA,QACJ,QAAQ;AAAA,MACV,CAAC;AAAA,IACH;AAEA,UAAM,QAAQ,OAAO,MAAM,CAAC,MAAM,EAAE,EAAE;AAEtC,SAAK,EAAE,IAAI,OAAO,OAAO,GAAG,MAAM;AAChC,YAAM,QAAQ,OAAO,IAAI,CAAC,MAAM;AAC9B,cAAM,QAAQ,EAAE,KAAKC,OAAM,MAAM,QAAG,IAAIA,OAAM,IAAI,QAAG;AACrD,cAAM,OAAO,EAAE,OAAOA,OAAM,IAAI;AAAA,WAAc,EAAE,IAAI,EAAE,IAAI;AAC1D,eAAO,GAAG,KAAK,IAAIA,OAAM,KAAK,EAAE,IAAI,CAAC,KAAKA,OAAM,IAAI,EAAE,MAAM,CAAC,GAAG,IAAI;AAAA,MACtE,CAAC;AACD,YAAM,SAAS,QACXA,OAAM,MAAM,sBAAsB,IAClCA,OAAM,IAAI,8BAA8B;AAC5C,aAAO,MAAM,KAAK,IAAI,IAAI;AAAA,IAC5B,CAAC;AAED,QAAI,CAAC,OAAO;AAKV,YAAM,oBAAoB,OAAO;AAAA,QAC/B,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,KAAK,WAAW,SAAS;AAAA,MAC7C;AACA,YAAM,iBAAiB,OAAO;AAAA,QAC5B,CAAC,MACC,CAAC,EAAE,OAAO,EAAE,KAAK,WAAW,MAAM,KAAK,EAAE,SAAS;AAAA,MACtD;AACA,cAAQ;AAAA,QACN,oBACI,SAAS,eACT,iBACE,SAAS,YACT,SAAS;AAAA,MACjB;AAAA,IACF;AAAA,EACF,CAAC;AACL;;;AC5IA,SAAS,wBAAwB;AACjC,SAAS,YAAY;AACrB,SAAS,gBAAgB;AACzB,SAAS,gBAAgB;AAEzB,OAAOC,YAAW;AAElB,SAAS,UAAU,sBAAsB;AACzC,OAAOC,UAAS;AAMT,SAAS,0BAA0BC,UAAwB;AAChE,QAAM,OAAOA,SACV,QAAQ,WAAW,EACnB,MAAM,KAAK,EACX,YAAY,kBAAkB;AAEjC,OACG,QAAQ,MAAM,EACd,YAAY,gBAAgB,EAC5B,OAAO,mBAAmB,uBAAuB,IAAI,EACrD,OAAO,qBAAqB,mBAAmB,EAC/C,OAAO,UAAU,sDAAsD,EACvE,OAAO,OAAO,SAA8D;AAC3E,QAAI,KAAK,KAAM,YAAW,EAAE,MAAM,KAAK,CAAC;AACxC,QAAI;AACF,YAAM,MAAM,MAAM,IAAI,cAAc;AAAA,QAClC,OAAO,KAAK,QAAQ,OAAO,KAAK,KAAK,IAAI;AAAA,QACzC,QAAQ,KAAK;AAAA,MACf,CAAC;AACD,WAAK,KAAK,MAAM;AACd,cAAM,OAAO,IAAI,KAAK,IAAI,CAAC,OAAO;AAAA,UAChC,IAAI,EAAE;AAAA,UACN,MAAMC,UAAS,EAAE,MAAM,EAAE;AAAA,UACzB,MAAM,EAAE,QAAQ;AAAA,UAChB,OAAO,EAAE,WAAW,SAAS,KAAK;AAAA,UAClC,SAAS,EAAE,QAAQ,MAAM,GAAG,EAAE;AAAA,QAChC,EAAE;AACF,cAAM,MAAM,MAAM,MAAM,CAAC,MAAM,QAAQ,QAAQ,SAAS,SAAS,CAAC;AAClE,eAAO,IAAI,cACP,MAAMC,OAAM,IAAI;AAAA;AAAA,yBAA8B,IAAI,WAAW,EAAE,IAC/D;AAAA,MACN,CAAC;AAAA,IACH,SAAS,KAAK;AACZ,UAAI,GAAG;AAAA,IACT;AAAA,EACF,CAAC;AAEH,OACG,QAAQ,UAAU,EAClB,YAAY,oBAAoB,EAChC,OAAO,OAAO,OAAe;AAC5B,QAAI;AACF,YAAM,MAAM,MAAM,IAAI,YAAY,EAAE;AACpC,WAAK,KAAK,MAAM,KAAK,GAAG,CAAC;AAAA,IAC3B,SAAS,KAAK;AACZ,UAAI,GAAG;AAAA,IACT;AAAA,EACF,CAAC;AAEH,OACG,QAAQ,gBAAgB,EACxB,YAAY,0BAA0B,EACtC,OAAO,mBAAmB,uBAAuB,IAAI,EACrD,OAAO,UAAU,sDAAsD,EACvE,OAAO,OAAO,OAAe,SAA6C;AACzE,QAAI,KAAK,KAAM,YAAW,EAAE,MAAM,KAAK,CAAC;AACxC,QAAI;AACF,YAAM,MAAM,MAAM,IAAI;AAAA,QACpB;AAAA,QACA,KAAK,QAAQ,OAAO,KAAK,KAAK,IAAI;AAAA,MACpC;AACA,WAAK,KAAK,MAAM;AACd,cAAM,OAAO,IAAI,KAAK,IAAI,CAAC,OAAO;AAAA,UAChC,IAAI,EAAE;AAAA,UACN,MAAMD,UAAS,EAAE,MAAM,EAAE;AAAA,UACzB,MAAM,EAAE,QAAQ;AAAA,UAChB,SAAS,EAAE,QAAQ,MAAM,GAAG,EAAE;AAAA,QAChC,EAAE;AACF,eAAO,MAAM,MAAM,CAAC,MAAM,QAAQ,QAAQ,SAAS,CAAC;AAAA,MACtD,CAAC;AAAA,IACH,SAAS,KAAK;AACZ,UAAI,GAAG;AAAA,IACT;AAAA,EACF,CAAC;AAEH,OACG,QAAQ,aAAa,EACrB,YAAY,iEAAiE,EAC7E,OAAO,qBAAqB,mBAAmB,EAC/C,OAAO,oBAAoB,iDAAiD,EAC5E;AAAA,IACC,OAAO,IAAY,SAA+C;AAChE,UAAI;AACF,cAAM,OAAiD,CAAC;AACxD,YAAI,KAAK,SAAS,OAAW,MAAK,OAAO,KAAK;AAC9C,YAAI,KAAK,aAAa,QAAW;AAC/B,eAAK,YAAY,KAAK,aAAa,KAAK,OAAO,KAAK;AAAA,QACtD;AACA,YAAI,OAAO,KAAK,IAAI,EAAE,WAAW,GAAG;AAClC,gBAAM,IAAI;AAAA,YACR;AAAA,UACF;AAAA,QACF;AACA,cAAM,MAAM,MAAM,IAAI,eAAe,IAAI,IAAI;AAC7C;AAAA,UACE;AAAA,UACA,MACEC,OAAM,MAAM,QAAG,IACf,sBAAsBA,OAAM,KAAK,IAAI,EAAE,CAAC;AAAA,IACxC,KAAK,GAAG;AAAA,QACZ;AAAA,MACF,SAAS,KAAK;AACZ,YAAI,GAAG;AAAA,MACT;AAAA,IACF;AAAA,EACF;AAEF,OACG,QAAQ,aAAa,EACrB,YAAY,mBAAmB,EAC/B,OAAO,OAAO,OAAe;AAC5B,QAAI;AACF,YAAM,UAAU,MAAM,IAAI,eAAe,EAAE;AAC3C;AAAA,QACE;AAAA,QACA,MAAMA,OAAM,MAAM,QAAG,IAAI,aAAa,EAAE;AAAA,MAC1C;AAAA,IACF,SAAS,KAAK;AACZ,UAAI,GAAG;AAAA,IACT;AAAA,EACF,CAAC;AAEH,OACG,QAAQ,eAAe,EACvB,YAAY,2CAA2C,EACvD,OAAO,qBAAqB,4CAA4C,EACxE,OAAO,UAAU,oDAAoD,EACrE,OAAO,oBAAoB,uEAAuE,EAClG;AAAA,IACC,OACE,UACA,SACG;AACH,YAAM,UAAUC,KAAI;AACpB,UAAI;AACF,cAAM,QAAQ,MAAM,KAAK,QAAQ;AACjC,YAAI,CAAC,MAAM,OAAO,EAAG,OAAM,IAAI,MAAM,GAAG,QAAQ,iBAAiB;AACjE,cAAM,WAAW,KAAK,QAAQ,SAAS,QAAQ;AAC/C,cAAM,cACJ,eAAe,QAAQ,KAAK;AAE9B,gBAAQ,MAAM,uBAAuB;AACrC,cAAM,SAAS,MAAM,IAAI,UAAU;AAAA,UACjC,WAAW;AAAA,UACX,cAAc;AAAA,UACd,gBAAgB,MAAM;AAAA,QACxB,CAAC;AACD,gBAAQ,QAAQ,mBAAmB;AAEnC,gBAAQ,MAAM,aAAa,UAAU,MAAM,IAAI,CAAC,EAAE;AAOlD,cAAM,aAAa,SAAS,MAAM,iBAAiB,QAAQ,CAAC;AAC5D,cAAM,SAAS,MAAM,MAAM,OAAO,YAAY;AAAA,UAC5C,QAAQ;AAAA,UACR,SAAS;AAAA,YACP,GAAG,OAAO;AAAA,YACV,kBAAkB,OAAO,MAAM,IAAI;AAAA,UACrC;AAAA,UACA,MAAM;AAAA,UACN,QAAQ;AAAA,QACV,CAAqC;AACrC,YAAI,CAAC,OAAO,IAAI;AACd,gBAAM,UAAU,MAAM,OAAO,KAAK,EAAE,MAAM,MAAM,EAAE;AAClD,gBAAM,IAAI;AAAA,YACR,uBAAuB,OAAO,MAAM,IAAI,OAAO,UAAU,GACvD,UAAU,OAAO,QAAQ,MAAM,GAAG,GAAG,IAAI,EAC3C;AAAA,UACF;AAAA,QACF;AACA,gBAAQ,QAAQ,qBAAqB;AAErC,gBAAQ,MAAM,mBAAmB;AACjC,cAAM,MAAM,MAAM,IAAI,eAAe;AAAA,UACnC,MAAM;AAAA,UACN,WAAW,OAAO;AAAA,UAClB,WAAW,KAAK;AAAA,UAChB,aAAa,KAAK,QAAQ;AAAA,QAC5B,CAAC;AACD,gBAAQ,QAAQ,qBAAqBD,OAAM,KAAK,IAAI,EAAE,CAAC,EAAE;AAEzD,cAAM,yBAAyB,KAAK,KAAK,QAAQ,KAAK;AAAA,MACxD,SAAS,KAAK;AACZ,gBAAQ,KAAK;AACb,YAAI,GAAG;AAAA,MACT;AAAA,IACF;AAAA,EACF;AAEF,OACG,QAAQ,mBAAmB,EAC3B;AAAA,IACC;AAAA,EACF,EACC,eAAe,qBAAqB,eAAe,EACnD,OAAO,UAAU,oDAAoD,EACrE,OAAO,oBAAoB,uBAAuB,EAClD;AAAA,IACC,OACE,KACA,SACG;AACH,UAAI;AACF,cAAM,MAAM,MAAM,IAAI,eAAe;AAAA,UACnC,MAAM,KAAK;AAAA,UACX,MAAM;AAAA,UACN,cAAc;AAAA,UACd,WAAW,KAAK;AAAA,UAChB,aAAa,KAAK,QAAQ;AAAA,QAC5B,CAAC;AACD,cAAM,yBAAyB,KAAK,KAAK,QAAQ,KAAK;AAAA,MACxD,SAAS,KAAK;AACZ,YAAI,GAAG;AAAA,MACT;AAAA,IACF;AAAA,EACF;AAEF,OACG,QAAQ,qBAAqB,EAC7B;AAAA,IACC;AAAA,EACF,EACC,eAAe,qBAAqB,eAAe,EACnD,OAAO,UAAU,oDAAoD,EACrE,OAAO,oBAAoB,uBAAuB,EAClD;AAAA,IACC,OACE,KACA,SACG;AACH,UAAI;AACF,cAAM,MAAM,MAAM,IAAI,eAAe;AAAA,UACnC,MAAM,KAAK;AAAA,UACX,MAAM;AAAA,UACN,cAAc;AAAA,UACd,WAAW,KAAK;AAAA,UAChB,aAAa,KAAK,QAAQ;AAAA,QAC5B,CAAC;AACD,cAAM,yBAAyB,KAAK,KAAK,QAAQ,KAAK;AAAA,MACxD,SAAS,KAAK;AACZ,YAAI,GAAG;AAAA,MACT;AAAA,IACF;AAAA,EACF;AAGF,QAAM,WAAW,KACd,QAAQ,UAAU,EAClB,YAAY,0BAA0B;AAEzC,WACG,QAAQ,WAAW,EACnB,YAAY,4CAA4C,EACxD,OAAO,UAAU,iBAAiB,EAClC,OAAO,OAAO,IAAY,SAA6B;AACtD,QAAI,KAAK,KAAM,YAAW,EAAE,MAAM,KAAK,CAAC;AACxC,QAAI;AACF,YAAM,MAAM,MAAM,IAAI,qBAAqB,EAAE;AAC7C,WAAK,KAAK,MAAM;AACd,cAAM,OAAO,IAAI,KAAK,IAAI,CAAC,OAAO;AAAA,UAChC,IAAI,EAAE;AAAA,UACN,SAAS,OAAO,EAAE,cAAc;AAAA,UAChC,SAAS,EAAE,aAAa,WAAM;AAAA,UAC9B,MAAM,EAAE,QAAQ;AAAA,UAChB,OAAO,EAAE,WAAW,SAAS,KAAK;AAAA,UAClC,MAAM,EAAE,cAAc,OAAO,UAAU,EAAE,SAAS,IAAI;AAAA,UACtD,SAAS,EAAE,QAAQ,MAAM,GAAG,EAAE;AAAA,QAChC,EAAE;AACF,eAAO,MAAM,MAAM;AAAA,UACjB;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF,CAAC;AAAA,MACH,CAAC;AAAA,IACH,SAAS,KAAK;AACZ,UAAI,GAAG;AAAA,IACT;AAAA,EACF,CAAC;AAEH,WACG,QAAQ,gBAAgB,EACxB,YAAY,iCAAiC,EAC7C,OAAO,OAAO,IAAY,QAAgB;AACzC,QAAI;AACF,YAAM,IAAI,MAAM,IAAI,mBAAmB,IAAI,GAAG;AAC9C,WAAK,GAAG,MAAM,KAAK,CAAC,CAAC;AAAA,IACvB,SAAS,KAAK;AACZ,UAAI,GAAG;AAAA,IACT;AAAA,EACF,CAAC;AAEH,WACG,QAAQ,iBAAiB,EACzB,YAAY,8CAA8C,EAC1D,OAAO,OAAO,IAAY,aAAqB;AAC9C,UAAM,UAAUC,KAAI;AACpB,QAAI;AACF,YAAM,QAAQ,MAAM,KAAK,QAAQ;AACjC,UAAI,CAAC,MAAM,OAAO,EAAG,OAAM,IAAI,MAAM,GAAG,QAAQ,iBAAiB;AACjE,YAAM,WAAW,SAAS,QAAQ;AAClC,YAAM,cACJ,eAAe,QAAQ,KAAK;AAE9B,cAAQ,MAAM,uBAAuB;AACrC,YAAM,SAAS,MAAM,IAAI,UAAU;AAAA,QACjC,WAAW;AAAA,QACX,cAAc;AAAA,QACd,gBAAgB,MAAM;AAAA,MACxB,CAAC;AACD,cAAQ,QAAQ,mBAAmB;AAEnC,cAAQ,MAAM,aAAa,UAAU,MAAM,IAAI,CAAC,EAAE;AAClD,YAAM,aAAa,SAAS,MAAM,iBAAiB,QAAQ,CAAC;AAC5D,YAAM,SAAS,MAAM,MAAM,OAAO,YAAY;AAAA,QAC5C,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,GAAG,OAAO;AAAA,UACV,kBAAkB,OAAO,MAAM,IAAI;AAAA,QACrC;AAAA,QACA,MAAM;AAAA,QACN,QAAQ;AAAA,MACV,CAAqC;AACrC,UAAI,CAAC,OAAO,IAAI;AACd,cAAM,UAAU,MAAM,OAAO,KAAK,EAAE,MAAM,MAAM,EAAE;AAClD,cAAM,IAAI;AAAA,UACR,uBAAuB,OAAO,MAAM,IAAI,OAAO,UAAU,GACvD,UAAU,OAAO,QAAQ,MAAM,GAAG,GAAG,IAAI,EAC3C;AAAA,QACF;AAAA,MACF;AACA,cAAQ,QAAQ,qBAAqB;AAErC,cAAQ,MAAM,gBAAgB;AAC9B,YAAM,IAAI,MAAM,IAAI,mBAAmB,IAAI,EAAE,WAAW,OAAO,UAAU,CAAC;AAC1E,cAAQ,QAAQ,WAAW,EAAE,cAAc,WAAWD,OAAM,KAAK,EAAE,EAAE,CAAC,EAAE;AAExE,WAAK,GAAG,MAAM,KAAK,CAAC,CAAC;AAAA,IACvB,SAAS,KAAK;AACZ,cAAQ,KAAK;AACb,UAAI,GAAG;AAAA,IACT;AAAA,EACF,CAAC;AAEH,WACG,QAAQ,qBAAqB,EAC7B,YAAY,2DAA2D,EACvE,OAAO,OAAO,IAAY,QAAgB;AACzC,QAAI;AACF,YAAM,IAAI,MAAM,IAAI,mBAAmB,IAAI,EAAE,cAAc,IAAI,CAAC;AAChE;AAAA,QACE;AAAA,QACA,MACEA,OAAM,MAAM,QAAG,IACf,YAAY,EAAE,cAAc,WAAWA,OAAM,KAAK,EAAE,EAAE,CAAC;AAAA,IACvD,KAAK,CAAC;AAAA,MACV;AAAA,IACF,SAAS,KAAK;AACZ,UAAI,GAAG;AAAA,IACT;AAAA,EACF,CAAC;AAEH,WACG,QAAQ,uBAAuB,EAC/B;AAAA,IACC;AAAA,EACF,EACC,OAAO,OAAO,IAAY,QAAgB;AACzC,QAAI;AACF,YAAM,IAAI,MAAM,IAAI,mBAAmB,IAAI,EAAE,cAAc,IAAI,CAAC;AAChE;AAAA,QACE;AAAA,QACA,MACEA,OAAM,MAAM,QAAG,IACf,YAAY,EAAE,cAAc,WAAWA,OAAM,KAAK,EAAE,EAAE,CAAC;AAAA,IACvD,KAAK,CAAC;AAAA,MACV;AAAA,IACF,SAAS,KAAK;AACZ,UAAI,GAAG;AAAA,IACT;AAAA,EACF,CAAC;AAEH,WACG,QAAQ,oBAAoB,EAC5B,YAAY,8BAA8B,EAC1C,OAAO,OAAO,IAAY,QAAgB;AACzC,QAAI;AACF,YAAM,IAAI,MAAM,IAAI,uBAAuB,IAAI,GAAG;AAClD;AAAA,QACE;AAAA,QACA,MACEA,OAAM,MAAM,QAAG,IACf,YAAY,EAAE,cAAc;AAAA,IAC5B,KAAK,CAAC;AAAA,MACV;AAAA,IACF,SAAS,KAAK;AACZ,UAAI,GAAG;AAAA,IACT;AAAA,EACF,CAAC;AACL;AAMA,eAAe,yBACb,KACA,UACe;AACf,MAAI,OACF;AACF,MAAI,cAA6B;AACjC,MAAI,UAAU;AACZ,QAAI;AACF,YAAM,QAAQ,MAAM,IAAI,UAAU,EAAE,aAAa,IAAI,IAAI,OAAO,EAAE,CAAC;AACnE,aAAO,MAAM,KAAK,CAAC,KAAK;AACxB,UAAI,CAAC,MAAM;AACT,sBACE,mFACA,IAAI,KACJ;AAAA,MACJ;AAAA,IACF,SAAS,SAAS;AAChB,oBAAc,wDACZ,mBAAmB,QAAQ,QAAQ,UAAU,OAAO,OAAO,CAC7D;AAAA,IACF;AACA,QAAI,aAAa;AACf,cAAQ,OAAO,MAAMA,OAAM,OAAO,IAAI,IAAI,cAAc,IAAI;AAAA,IAC9D;AAAA,EACF;AAEA,OAAK,EAAE,UAAU,KAAK,KAAK,GAAG,MAAM;AAClC,UAAM,SAAS,CAAC,KAAK,GAAG,CAAC;AACzB,QAAI,MAAM;AACR,aAAO,KAAKA,OAAM,MAAM,QAAG,IAAI,kBAAkBA,OAAM,KAAK,KAAK,GAAG,CAAC;AAAA,IACvE;AACA,WAAO,OAAO,KAAK,IAAI;AAAA,EACzB,CAAC;AACH;AAEA,SAASD,UAAS,GAAW,GAAmB;AAC9C,QAAM,QAAQ,oBAAoB,CAAC;AACnC,SAAO,MAAM,SAAS,IAAI,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,WAAM;AAC1D;AAEA,SAAS,UAAU,OAAuB;AACxC,QAAM,QAAQ,CAAC,KAAK,MAAM,MAAM,IAAI;AACpC,MAAI,IAAI;AACR,MAAI,IAAI;AACR,SAAO,KAAK,QAAQ,IAAI,MAAM,SAAS,GAAG;AACxC,SAAK;AACL;AAAA,EACF;AACA,SAAO,GAAG,EAAE,QAAQ,MAAM,IAAI,IAAI,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC;AACjD;;;AC5dA,OAAOG,YAAW;AAOX,SAAS,wBAAwBC,UAAwB;AAC9D,QAAM,UAAUA,SACb,QAAQ,SAAS,EACjB,YAAY,6BAA6B;AAE5C,UACG,QAAQ,MAAM,EACd,YAAY,kCAAkC,EAC9C;AAAA,IACC;AAAA,IACA;AAAA,EACF,EACC,OAAO,mBAAmB,uBAAuB,IAAI,EACrD,OAAO,qBAAqB,mBAAmB,EAC/C,OAAO,UAAU,iBAAiB,EAClC;AAAA,IACC,OAAO,SAKD;AACJ,UAAI,KAAK,KAAM,YAAW,EAAE,MAAM,KAAK,CAAC;AACxC,UAAI;AACF,cAAM,MAAM,MAAM,IAAI,YAAY;AAAA,UAChC,OAAO,KAAK,QAAQ,OAAO,KAAK,KAAK,IAAI;AAAA,UACzC,QAAQ,KAAK;AAAA,UACb,WAAW,KAAK;AAAA,QAClB,CAAC;AACD,aAAK,KAAK,MAAM;AACd,gBAAM,OAAO,IAAI,KAAK,IAAI,CAAC,OAAO;AAAA,YAChC,IAAI,EAAE;AAAA,YACN,MAAMC,UAAS,EAAE,MAAM,EAAE;AAAA,YACzB,MAAMA,UAAS,EAAE,MAAM,EAAE;AAAA,YACzB,MAAM,OAAO,EAAE,cAAc;AAAA,YAC7B,UAAU,OAAO,EAAE,kBAAkB;AAAA,UACvC,EAAE;AACF,gBAAM,MAAM,MAAM,MAAM,CAAC,MAAM,QAAQ,QAAQ,QAAQ,UAAU,CAAC;AAClE,iBAAO,IAAI,cACP,MAAMC,OAAM,IAAI;AAAA;AAAA,yBAA8B,IAAI,WAAW,EAAE,IAC/D;AAAA,QACN,CAAC;AAAA,MACH,SAAS,KAAK;AACZ,YAAI,GAAG;AAAA,MACT;AAAA,IACF;AAAA,EACF;AAEF,UACG,QAAQ,QAAQ,EAChB,YAAY,qCAAqC,EACjD,eAAe,qBAAqB,aAAa,EACjD,OAAO,iBAAiB,0CAA0C,EAClE,OAAO,iBAAiB,0CAA0C,EAClE,OAAO,mBAAmB,6DAA6D,EACvF;AAAA,IACC,OAAO,SAKD;AACJ,UAAI;AACF,cAAM,IAAI,MAAM,IAAI,aAAa;AAAA,UAC/B,MAAM,KAAK;AAAA,UACX,WAAW,KAAK,UAAU;AAAA,UAC1B,MAAM,KAAK;AAAA,UACX,OAAO,KAAK;AAAA,QACd,CAAC;AACD;AAAA,UACE;AAAA,UACA,MACEA,OAAM,MAAM,QAAG,IACf,oBAAoBA,OAAM,KAAK,EAAE,EAAE,CAAC;AAAA,IACpC,KAAK,CAAC;AAAA,QACV;AAAA,MACF,SAAS,KAAK;AACZ,YAAI,GAAG;AAAA,MACT;AAAA,IACF;AAAA,EACF;AAEF,UACG,QAAQ,UAAU,EAClB,YAAY,kBAAkB,EAC9B,OAAO,OAAO,OAAe;AAC5B,QAAI;AACF,YAAM,IAAI,MAAM,IAAI,UAAU,EAAE;AAChC,WAAK,GAAG,MAAM,KAAK,CAAC,CAAC;AAAA,IACvB,SAAS,KAAK;AACZ,UAAI,GAAG;AAAA,IACT;AAAA,EACF,CAAC;AAEH,UACG,QAAQ,aAAa,EACrB,YAAY,iBAAiB,EAC7B,OAAO,mBAAmB,EAC1B,OAAO,iBAAiB,mCAAmC,EAC3D,OAAO,mBAAmB,qCAAqC,EAC/D;AAAA,IACC,OACE,IACA,SACG;AACH,UAAI;AACF,cAAM,OAA+C,CAAC;AACtD,YAAI,KAAK,SAAS,OAAW,MAAK,OAAO,KAAK;AAC9C,YAAI,KAAK,SAAS;AAChB,eAAK,OAAQ,KAAK,SAAS,KAAK,OAAO,KAAK;AAC9C,YAAI,KAAK,UAAU;AACjB,eAAK,QAAS,KAAK,UAAU,KAAK,OAAO,KAAK;AAChD,YAAI,OAAO,KAAK,IAAI,EAAE,WAAW,GAAG;AAClC,gBAAM,IAAI;AAAA,YACR;AAAA,UACF;AAAA,QACF;AACA,cAAM,IAAI,MAAM,IAAI,aAAa,IAAI,IAAI;AACzC;AAAA,UACE;AAAA,UACA,MACEA,OAAM,MAAM,QAAG,IACf,oBAAoBA,OAAM,KAAK,EAAE,EAAE,CAAC;AAAA,IACpC,KAAK,CAAC;AAAA,QACV;AAAA,MACF,SAAS,KAAK;AACZ,YAAI,GAAG;AAAA,MACT;AAAA,IACF;AAAA,EACF;AAEF,UACG,QAAQ,aAAa,EACrB,YAAY,iBAAiB,EAC7B;AAAA,IACC;AAAA,IACA;AAAA,IACA;AAAA,EACF,EACC,OAAO,OAAO,IAAY,SAAgC;AACzD,QAAI;AACF,YAAM,UAAU,MAAM,IAAI,aAAa,IAAI,EAAE,SAAS,KAAK,QAAQ,CAAC;AACpE;AAAA,QACE;AAAA,QACA,MAAMA,OAAM,MAAM,QAAG,IAAI,WAAW,EAAE;AAAA,MACxC;AAAA,IACF,SAAS,KAAK;AACZ,UAAI,GAAG;AAAA,IACT;AAAA,EACF,CAAC;AAEH,UACG,QAAQ,WAAW,EACnB,YAAY,wCAAwC,EACpD;AAAA,IACC;AAAA,IACA;AAAA,EACF,EACC,OAAO,OAAO,IAAY,SAA8B;AACvD,QAAI;AACF,UAAI,KAAK,WAAW,QAAW;AAC7B,cAAM,IAAI;AAAA,UACR;AAAA,QACF;AAAA,MACF;AACA,YAAM,YAAY,KAAK,WAAW,KAAK,OAAO,KAAK;AACnD,YAAM,IAAI,MAAM,IAAI,WAAW,IAAI,EAAE,UAAU,CAAC;AAChD;AAAA,QACE;AAAA,QACA,MACEA,OAAM,MAAM,QAAG,IACf,4BAA4BA,OAAM,KAAK,EAAE,IAAI,CAAC;AAAA,IAC9C,KAAK,CAAC;AAAA,MACV;AAAA,IACF,SAAS,KAAK;AACZ,UAAI,GAAG;AAAA,IACT;AAAA,EACF,CAAC;AACL;AAEA,SAASD,UAAS,GAAW,GAAmB;AAC9C,QAAM,QAAQ,oBAAoB,CAAC;AACnC,SAAO,MAAM,SAAS,IAAI,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,WAAM;AAC1D;;;AC9LA,OAAOE,YAAW;AAalB,IAAM,sBAAoD;AAAA,EACxD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AACA,IAAM,sBAAoD,CAAC,GAAG,IAAI,IAAI,IAAI,GAAG;AAc7E,SAAS,qBAAqB,MAAkD;AAC9E,QAAM,SAAS;AAAA,IACb,MAAM,KAAK;AAAA,IACX,UAAU,KAAK;AAAA,IACf,UAAU,KAAK;AAAA,IACf,UAAU,KAAK;AAAA,IACf,OAAO,KAAK;AAAA,IACZ,WAAW,KAAK;AAAA,IAChB,SAAS,KAAK;AAAA,EAChB;AACA,QAAM,YAAiD;AAAA,IACrD,MAAM;AAAA,IACN,UAAU;AAAA,IACV,UAAU;AAAA,IACV,UAAU;AAAA,IACV,OAAO;AAAA,IACP,WAAW;AAAA,IACX,SAAS;AAAA,EACX;AACA,QAAM,WAAW,OAAO,QAAQ,MAAM,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC,MAAM,MAAM,MAAS;AACzE,MAAI,SAAS,WAAW,EAAG,QAAO;AAElC,QAAM,UAAU,OAAO,QAAQ,MAAM,EAClC,OAAO,CAAC,CAAC,EAAE,CAAC,MAAM,MAAM,MAAS,EACjC,IAAI,CAAC,CAAC,CAAC,MAAM,UAAU,CAAwB,CAAC;AACnD,MAAI,QAAQ,SAAS,GAAG;AACtB,UAAM,IAAI;AAAA,MACR,yCAAyC,QAAQ,KAAK,IAAI,CAAC;AAAA,IAC7D;AAAA,EACF;AAEA,QAAM,QACJ,OAAO,SAAU,YAAY,MAAM,UACnC,OAAO,SAAU,YAAY,MAAM;AACrC,QAAM,WACJ,OAAO,SAAU,YAAY,MAAM,WACnC,OAAO,SAAU,YAAY,MAAM;AACrC,MAAI,CAAC,SAAS,CAAC,UAAU;AACvB,UAAM,IAAI;AAAA,MACR,mCAAmC,KAAK,UAAU,OAAO,QAAQ,CAAC;AAAA,IACpE;AAAA,EACF;AAEA,MAAI,CAAC,oBAAoB,SAAS,OAAO,QAA6B,GAAG;AACvE,UAAM,IAAI;AAAA,MACR,gCAAgC,KAAK,UAAU,OAAO,QAAQ,CAAC,sBAAsB,oBAAoB,KAAK,IAAI,CAAC;AAAA,IACrH;AAAA,EACF;AACA,QAAM,WAAW,OAAO,OAAO,QAAQ;AACvC,MACE,CAAC,OAAO,SAAS,QAAQ,KACzB,CAAC,oBAAoB,SAAS,QAA6B,GAC3D;AACA,UAAM,IAAI;AAAA,MACR,gCAAgC,KAAK,UAAU,OAAO,QAAQ,CAAC,sBAAsB,oBAAoB,KAAK,IAAI,CAAC;AAAA,IACrH;AAAA,EACF;AACA,MAAI,CAAC,2BAA2B,KAAK,OAAO,KAAM,GAAG;AACnD,UAAM,IAAI;AAAA,MACR,6BAA6B,KAAK,UAAU,OAAO,KAAK,CAAC;AAAA,IAC3D;AAAA,EACF;AACA,QAAM,WAAW,OAAO,OAAO,SAAS;AACxC,MAAI,CAAC,OAAO,UAAU,QAAQ,KAAK,WAAW,KAAK,WAAW,IAAI;AAChE,UAAM,IAAI;AAAA,MACR,iCAAiC,KAAK,UAAU,OAAO,SAAS,CAAC;AAAA,IACnE;AAAA,EACF;AACA,QAAM,UAAU,OAAO,OAAO,OAAO;AACrC,MAAI,CAAC,OAAO,SAAS,OAAO,KAAK,UAAU,KAAK,UAAU,GAAG;AAC3D,UAAM,IAAI;AAAA,MACR,+BAA+B,KAAK,UAAU,OAAO,OAAO,CAAC;AAAA,IAC/D;AAAA,EACF;AAEA,SAAO;AAAA,IACL,MAAM,OAAO;AAAA,IACb,UAAU;AAAA,IACV,UAAU,OAAO;AAAA,IACjB;AAAA,IACA,OAAO,OAAO;AAAA,IACd,WAAW;AAAA,IACX;AAAA,EACF;AACF;AAEA,SAAS,oBAAoB,KAAuB;AAClD,SAAO,IACJ;AAAA,IACC;AAAA,IACA;AAAA,EACF,EACC,OAAO,8BAA8B,oCAAoC,EACzE;AAAA,IACC;AAAA,IACA,oBAAoB,oBAAoB,KAAK,GAAG,CAAC;AAAA,EACnD,EACC;AAAA,IACC;AAAA,IACA,wBAAwB,oBAAoB,KAAK,GAAG,CAAC;AAAA,EACvD,EACC,OAAO,2BAA2B,+BAA+B,EACjE,OAAO,6BAA6B,gBAAgB,EACpD,OAAO,2BAA2B,aAAa;AACpD;AAEO,SAAS,sBAAsBC,UAAwB;AAC5D,QAAM,QAAQA,SAAQ,QAAQ,OAAO,EAAE,YAAY,oBAAoB;AAEvE,QACG,QAAQ,MAAM,EACd,YAAY,kBAAkB,EAC9B,OAAO,mBAAmB,uBAAuB,IAAI,EACrD,OAAO,qBAAqB,mBAAmB,EAC/C,OAAO,mBAAmB,uBAAuB,EACjD,OAAO,mBAAmB,uBAAuB,EACjD,OAAO,iBAAiB,gDAAgD,EACxE,OAAO,UAAU,sDAAsD,EACvE;AAAA,IACC,OAAO,SAOD;AACJ,UAAI,KAAK,KAAM,YAAW,EAAE,MAAM,KAAK,CAAC;AACxC,UAAI;AACF,cAAM,MAAM,MAAM,IAAI,UAAU;AAAA,UAC9B,OAAO,KAAK,QAAQ,OAAO,KAAK,KAAK,IAAI;AAAA,UACzC,QAAQ,KAAK;AAAA,UACb,aAAa,KAAK;AAAA,UAClB,aAAa,KAAK;AAAA,UAClB,UAAU,KAAK;AAAA,QACjB,CAAC;AACD,aAAK,KAAK,MAAM;AACd,gBAAM,OAAO,IAAI,KAAK,IAAI,CAAC,OAAO;AAAA,YAChC,IAAI,EAAE;AAAA,YACN,MAAMC,UAAS,EAAE,QAAQ,IAAI,EAAE;AAAA,YAC/B,KAAKA,UAAS,EAAE,KAAK,EAAE;AAAA,YACvB,UAAU,EAAE,wBAAwB,QAAQ;AAAA,YAC5C,SAAS,EAAE,aAAa,EAAE,WAAW,MAAM,GAAG,EAAE,IAAI;AAAA,UACtD,EAAE;AACF,gBAAM,MAAM,MAAM,MAAM,CAAC,MAAM,QAAQ,OAAO,YAAY,SAAS,CAAC;AACpE,iBAAO,IAAI,cACP,MAAMC,OAAM,IAAI;AAAA;AAAA,yBAA8B,IAAI,WAAW,EAAE,IAC/D;AAAA,QACN,CAAC;AAAA,MACH,SAAS,KAAK;AACZ,YAAI,GAAG;AAAA,MACT;AAAA,IACF;AAAA,EACF;AAEF,QACG,QAAQ,UAAU,EAClB,YAAY,sBAAsB,EAClC,OAAO,OAAO,OAAe;AAC5B,QAAI;AACF,YAAM,OAAO,MAAM,IAAI,QAAQ,EAAE;AACjC,WAAK,MAAM,MAAM,KAAK,IAAI,CAAC;AAAA,IAC7B,SAAS,KAAK;AACZ,UAAI,GAAG;AAAA,IACT;AAAA,EACF,CAAC;AAEH;AAAA,IACE,MACG,QAAQ,QAAQ,EAChB,YAAY,gDAAgD,EAC5D,OAAO,mBAAmB,aAAa,EACvC,OAAO,mBAAmB,aAAa,EACvC;AAAA,MACC;AAAA,MACA;AAAA,IACF,EACC,OAAO,qBAAqB,WAAW,EACvC,OAAO,wBAAwB,4BAA4B,EAC3D,OAAO,mBAAmB,4BAA4B,EACtD,OAAO,qBAAqB,gCAAgC,KAAK,EACjE,OAAO,oBAAoB,qCAAqC,KAAK,EACrE;AAAA,MACC;AAAA,MACA;AAAA,MACA;AAAA,IACF,EACC,OAAO,eAAe,qDAAqD,KAAK;AAAA,EACrF,EACG;AAAA,IACC,OAAO,SAWe;AACpB,UAAI;AACF,YAAI,CAAC,KAAK,YAAY,CAAC,KAAK,UAAU;AACpC,gBAAM,IAAI,MAAM,wDAAwD;AAAA,QAC1E;AACA,YAAI,KAAK,SAAS,CAAC,KAAK,UAAU;AAChC,gBAAM,IAAI,MAAM,mCAAmC;AAAA,QACrD;AACA,cAAM,kBAAkB,qBAAqB,IAAI;AAGjD,cAAM,kBAAkB,KAAK,aAAa,oBAAoB;AAC9D,cAAM,OAAO,MAAM,IAAI,WAAW;AAAA,UAChC,aAAa,KAAK;AAAA,UAClB,aAAa,KAAK;AAAA,UAClB,eAAe,KAAK,QAAQ,UAAU;AAAA,UACtC,UAAU,KAAK;AAAA,UACf,MAAM,KAAK;AAAA,UACX,YAAY,KAAK;AAAA,UACjB,UAAU,KAAK;AAAA,UACf,iBAAiB,KAAK;AAAA,UACtB,gBAAgB,KAAK;AAAA,UACrB,0BAA0B,KAAK;AAAA,UAC/B,kBAAkB,mBAAmB;AAAA,UACrC,kBAAkB;AAAA,QACpB,CAAC;AACD;AAAA,UACE;AAAA,UACA,MACEA,OAAM,MAAM,QAAG,IACf,oBACAA,OAAM,KAAK,OAAO,IAClB,KAAK,MACL,OACA,KAAK,IAAI;AAAA,QACb;AAAA,MACF,SAAS,KAAK;AACZ,YAAI,GAAG;AAAA,MACT;AAAA,IACF;AAAA,EACF;AAEF;AAAA,IACE,MACG,QAAQ,aAAa,EACrB,YAAY,+BAA+B,EAC3C;AAAA,MACC;AAAA,MACA;AAAA,IACF,EACC;AAAA,MACC;AAAA,MACA;AAAA,IACF,EACC,OAAO,mBAAmB,EAC1B,OAAO,wBAAwB,sDAAsD,EACrF,OAAO,mBAAmB,wCAAwC,EAClE,OAAO,4BAA4B,EACnC,OAAO,gCAAgC,EACvC,OAAO,2BAA2B,EAClC;AAAA,MACC;AAAA,MACA;AAAA,IACF,EACC,OAAO,uBAAuB,wCAAwC,EACtE,OAAO,wBAAwB,0BAA0B,EACzD,OAAO,qBAAqB,uCAAuC,KAAK,EACxE,OAAO,oCAAoC,oBAAoB,EAC/D;AAAA,MACC;AAAA,MACA;AAAA,IACF;AAAA,EACJ,EACG;AAAA,IACC,OACE,IACA,SAgBG;AACH,UAAI;AACF,cAAM,MAAM,CACV,GACA,SACwB;AACxB,cAAI,MAAM,OAAW,QAAO;AAC5B,gBAAM,OAAO,EAAE,YAAY;AAC3B,cAAI,SAAS,KAAM,QAAO;AAC1B,cAAI,SAAS,MAAO,QAAO;AAC3B,gBAAM,IAAI;AAAA,YACR,qBAAqB,IAAI,KAAK,KAAK,UAAU,CAAC,CAAC;AAAA,UACjD;AAAA,QACF;AACA,cAAM,OAAO,CAAC,MACZ,MAAM,SACF,SACA,MAAM,KACJ,CAAC,IACD,EAAE,MAAM,GAAG,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,OAAO;AAExD,cAAM,OAA6C,CAAC;AACpD,YAAI,KAAK,aAAa,QAAW;AAC/B,gBAAM,OAAO,KAAK,SAAS,YAAY;AACvC,cAAI,SAAS,aAAa,SAAS,SAAS;AAC1C,kBAAM,IAAI;AAAA,cACR,iCAAiC,KAAK,UAAU,KAAK,QAAQ,CAAC;AAAA,YAChE;AAAA,UACF;AACA,eAAK,gBAAgB;AAAA,QACvB;AACA,YAAI,KAAK,UAAU,OAAW,MAAK,WAAW,KAAK;AACnD,YAAI,KAAK,SAAS,OAAW,MAAK,OAAO,KAAK;AAC9C,YAAI,KAAK,YAAY;AACnB,eAAK,aAAa,KAAK,YAAY,KAAK,OAAO,KAAK;AACtD,YAAI,KAAK,aAAa;AACpB,eAAK,WAAW,KAAK,aAAa,KAAK,OAAO,KAAK;AACrD,cAAM,KAAK,IAAI,KAAK,gBAAgB,mBAAmB;AACvD,YAAI,OAAO,OAAW,MAAK,kBAAkB;AAC7C,cAAM,KAAK,IAAI,KAAK,oBAAoB,uBAAuB;AAC/D,YAAI,OAAO,OAAW,MAAK,sBAAsB;AACjD,cAAM,KAAK,IAAI,KAAK,eAAe,kBAAkB;AACrD,YAAI,OAAO,OAAW,MAAK,iBAAiB;AAC5C,cAAM,KAAK,KAAK,KAAK,SAAS;AAC9B,YAAI,OAAO,OAAW,MAAK,aAAa;AACxC,cAAM,KAAK,KAAK,KAAK,QAAQ;AAC7B,YAAI,OAAO,OAAW,MAAK,YAAY;AACvC,cAAM,KAAK,IAAI,KAAK,WAAW,aAAa;AAC5C,YAAI,OAAO,OAAW,MAAK,mBAAmB;AAC9C,cAAM,kBAAkB,qBAAqB,IAAI;AACjD,YAAI,KAAK,kBAAkB,oBAAoB,QAAW;AACxD,gBAAM,IAAI;AAAA,YACR;AAAA,UACF;AAAA,QACF;AACA,YAAI,KAAK,gBAAgB;AACvB,eAAK,mBAAmB;AAAA,QAC1B,WAAW,oBAAoB,QAAW;AACxC,eAAK,mBAAmB;AAGxB,cAAI,OAAO,OAAW,MAAK,mBAAmB;AAAA,QAChD;AACA,cAAM,KAAK,IAAI,KAAK,sBAAsB,yBAAyB;AACnE,YAAI,OAAO,OAAW,MAAK,+BAA+B;AAC1D,cAAM,KAAK,IAAI,KAAK,kBAAkB,qBAAqB;AAC3D,YAAI,OAAO,OAAW,MAAK,2BAA2B;AAEtD,YAAI,OAAO,KAAK,IAAI,EAAE,WAAW,GAAG;AAClC,gBAAM,IAAI;AAAA,YACR;AAAA,UACF;AAAA,QACF;AACA,cAAM,OAAO,MAAM,IAAI,WAAW,IAAI,IAAI;AAC1C;AAAA,UACE;AAAA,UACA,MACEA,OAAM,MAAM,QAAG,IAAI,kBAAkBA,OAAM,KAAK,KAAK,EAAE,CAAC;AAAA,IACxD,KAAK,IAAI;AAAA,QACb;AAAA,MACF,SAAS,KAAK;AACZ,YAAI,GAAG;AAAA,MACT;AAAA,IACF;AAAA,EACF;AAEF,QACG,QAAQ,aAAa,EACrB,YAAY,qBAAqB,EACjC,OAAO,OAAO,OAAe;AAC5B,QAAI;AACF,YAAM,UAAU,MAAM,IAAI,WAAW,EAAE;AACvC;AAAA,QACE;AAAA,QACA,MAAMA,OAAM,MAAM,QAAG,IAAI,SAAS,EAAE;AAAA,MACtC;AAAA,IACF,SAAS,KAAK;AACZ,UAAI,GAAG;AAAA,IACT;AAAA,EACF,CAAC;AAGH,QAAM,kBAAkB,MACrB,QAAQ,aAAa,EACrB;AAAA,IACC;AAAA,EACF;AAEF,kBACG,QAAQ,UAAU,EAClB,YAAY,sDAAsD,EAClE,OAAO,UAAU,iBAAiB,EAClC,OAAO,OAAO,IAAY,SAA6B;AACtD,QAAI,KAAK,KAAM,YAAW,EAAE,MAAM,KAAK,CAAC;AACxC,QAAI;AACF,YAAM,MAAM,MAAM,IAAI,mBAAmB,EAAE;AAC3C,WAAK,KAAK,MAAM;AACd,YAAI,IAAI,KAAK,WAAW,GAAG;AACzB,iBAAOA,OAAM;AAAA,YACX;AAAA,UACF;AAAA,QACF;AACA,cAAM,OAAO,IAAI,KAAK,IAAI,CAAC,OAAO;AAAA,UAChC,SAAS,EAAE;AAAA,UACX,MAAM,EAAE,cAAc,sBAAsB,aAAa;AAAA,UACzD,MAAM,EAAE,WAAW,QAAQ;AAAA,UAC3B,UAAU,EAAE,eAAe,QAAQ;AAAA,QACrC,EAAE;AACF,eAAO,MAAM,MAAM,CAAC,WAAW,QAAQ,QAAQ,UAAU,CAAC;AAAA,MAC5D,CAAC;AAAA,IACH,SAAS,KAAK;AACZ,UAAI,GAAG;AAAA,IACT;AAAA,EACF,CAAC;AAEH,kBACG,QAAQ,UAAU,EAClB;AAAA,IACC;AAAA,EACF,EACC;AAAA,IACC;AAAA,IACA;AAAA,EACF,EACC,OAAO,mBAAmB,oDAAoD,EAC9E,OAAO,4BAA4B,sBAAsB,EACzD,OAAO,mBAAmB,4BAA4B,EACtD,OAAO,uBAAuB,iCAAiC,EAC/D,OAAO,WAAW,wDAAwD,KAAK,EAC/E;AAAA,IACC,OACE,IACA,SAQG;AACH,UAAI;AACF,YAAI,KAAK,UAAU,KAAK,QAAQ,KAAK,OAAO;AAC1C,gBAAM,IAAI,MAAM,oDAAoD;AAAA,QACtE;AACA,cAAM,cAAc,KAAK,QAAQ,CAAC,IAAI,uBAAuB,IAAI;AACjE,cAAM,MAAM,MAAM,IAAI,mBAAmB,IAAI,EAAE,YAAY,CAAC;AAC5D,aAAK,KAAK,MAAM;AACd,cAAI,IAAI,KAAK,WAAW,GAAG;AACzB,mBACEA,OAAM,MAAM,QAAG,IACf;AAAA,UAEJ;AACA,iBACEA,OAAM,MAAM,QAAG,IACf,IAAI,IAAI,KAAK,MAAM;AAAA,IACnB;AAAA,YACE,IAAI,KAAK,IAAI,CAAC,OAAO;AAAA,cACnB,SAAS,EAAE;AAAA,cACX,MACE,EAAE,cAAc,sBAAsB,aAAa;AAAA,cACrD,MAAM,EAAE,WAAW,QAAQ;AAAA,cAC3B,UAAU,EAAE,eAAe,QAAQ;AAAA,YACrC,EAAE;AAAA,YACF,CAAC,WAAW,QAAQ,QAAQ,UAAU;AAAA,UACxC;AAAA,QAEJ,CAAC;AAAA,MACH,SAAS,KAAK;AACZ,YAAI,GAAG;AAAA,MACT;AAAA,IACF;AAAA,EACF;AACJ;AAEA,SAASD,UAAS,GAAW,GAAmB;AAC9C,QAAM,QAAQ,oBAAoB,CAAC;AACnC,SAAO,MAAM,SAAS,IAAI,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,WAAM;AAC1D;;;AClhBA,OAAOE,aAAW;AAOX,SAAS,sBAAsBC,UAAwB;AAC5D,QAAM,QAAQA,SAAQ,QAAQ,OAAO,EAAE,YAAY,0BAA0B;AAE7E,QACG,QAAQ,MAAM,EACd,YAAY,6BAA6B,EACzC,eAAe,eAAe,SAAS,EACvC,OAAO,mBAAmB,uBAAuB,IAAI,EACrD,OAAO,qBAAqB,mBAAmB,EAC/C,OAAO,UAAU,sDAAsD,EACvE;AAAA,IACC,OAAO,SAA4E;AACjF,UAAI,KAAK,KAAM,YAAW,EAAE,MAAM,KAAK,CAAC;AACxC,UAAI;AACF,cAAM,MAAM,MAAM,IAAI,UAAU,KAAK,MAAM;AAAA,UACzC,OAAO,KAAK,QAAQ,OAAO,KAAK,KAAK,IAAI;AAAA,UACzC,QAAQ,KAAK;AAAA,QACf,CAAC;AACD,aAAK,KAAK,MAAM;AACd,gBAAM,OAAO,IAAI,KAAK,IAAI,CAAC,OAAO;AAAA,YAChC,IAAI,EAAE;AAAA,YACN,QAAQ,oBAAoB,EAAE,gBAAgB,EAAE;AAAA,YAChD,MAAM,EAAE,aAAa;AAAA,YACrB,QAAQ,EAAE,UAAU,QAAQ,KAAK,GAAG,EAAE,MAAM,GAAG,EAAE;AAAA,YACjD,YAAY,EAAE,gBAAgB,EAAE,cAAc,MAAM,GAAG,EAAE,IAAI;AAAA,UAC/D,EAAE;AACF,gBAAM,MAAM,MAAM,MAAM,CAAC,MAAM,UAAU,QAAQ,UAAU,YAAY,CAAC;AACxE,iBAAO,IAAI,cACP,MAAMC,QAAM,IAAI;AAAA;AAAA,yBAA8B,IAAI,WAAW,EAAE,IAC/D;AAAA,QACN,CAAC;AAAA,MACH,SAAS,KAAK;AACZ,YAAI,GAAG;AAAA,MACT;AAAA,IACF;AAAA,EACF;AACJ;;;AC3CA,OAAOC,aAAW;AAOX,SAAS,yBAAyBC,UAAwB;AAC/D,QAAM,WAAWA,SACd,QAAQ,UAAU,EAClB,YAAY,0CAA0C;AAEzD,WACG,QAAQ,MAAM,EACd,YAAY,eAAe,EAC3B,OAAO,mBAAmB,uBAAuB,IAAI,EACrD,OAAO,qBAAqB,mBAAmB,EAC/C,OAAO,mBAAmB,sCAAsC,EAChE,OAAO,mBAAmB,uBAAuB,EACjD,OAAO,UAAU,iBAAiB,EAClC;AAAA,IACC,OAAO,SAMD;AACJ,UAAI,KAAK,KAAM,YAAW,EAAE,MAAM,KAAK,CAAC;AACxC,UAAI;AACF,cAAM,MAAM,MAAM,IAAI,aAAa;AAAA,UACjC,OAAO,KAAK,QAAQ,OAAO,KAAK,KAAK,IAAI;AAAA,UACzC,QAAQ,KAAK;AAAA,UACb,OAAO,KAAK;AAAA,UACZ,aAAa,KAAK;AAAA,QACpB,CAAC;AACD,aAAK,KAAK,MAAM;AACd,gBAAM,OAAO,IAAI,KAAK,IAAI,CAAC,OAAO;AAAA,YAChC,IAAI,EAAE;AAAA,YACN,OAAO,oBAAoB,EAAE,KAAK;AAAA,YAClC,UAAU,EAAE,WAAW,QAAQ;AAAA,YAC/B,OAAO,OAAO,EAAE,WAAW;AAAA,YAC3B,WAAW,EAAE,gBAAgB,MAAM,GAAG,EAAE,KAAK;AAAA,UAC/C,EAAE;AACF,gBAAM,MAAM,MAAM,MAAM,CAAC,MAAM,SAAS,YAAY,SAAS,WAAW,CAAC;AACzE,iBAAO,IAAI,cACP,MAAMC,QAAM,IAAI;AAAA;AAAA,yBAA8B,IAAI,WAAW,EAAE,IAC/D;AAAA,QACN,CAAC;AAAA,MACH,SAAS,KAAK;AACZ,YAAI,GAAG;AAAA,MACT;AAAA,IACF;AAAA,EACF;AAEF,WACG,QAAQ,UAAU,EAClB,YAAY,mBAAmB,EAC/B,OAAO,OAAO,OAAe;AAC5B,QAAI;AACF,YAAM,IAAI,MAAM,IAAI,WAAW,EAAE;AACjC,WAAK,GAAG,MAAM,KAAK,CAAC,CAAC;AAAA,IACvB,SAAS,KAAK;AACZ,UAAI,GAAG;AAAA,IACT;AAAA,EACF,CAAC;AAEH,WACG,QAAQ,YAAY,EACpB,YAAY,oCAAoC,EAChD,OAAO,mBAAmB,uBAAuB,IAAI,EACrD,OAAO,qBAAqB,mBAAmB,EAC/C,OAAO,UAAU,iBAAiB,EAClC;AAAA,IACC,OACE,IACA,SACG;AACH,UAAI,KAAK,KAAM,YAAW,EAAE,MAAM,KAAK,CAAC;AACxC,UAAI;AACF,cAAM,MAAM,MAAM,IAAI,iBAAiB,IAAI;AAAA,UACzC,OAAO,KAAK,QAAQ,OAAO,KAAK,KAAK,IAAI;AAAA,UACzC,QAAQ,KAAK;AAAA,QACf,CAAC;AACD,aAAK,KAAK,MAAM;AACd,gBAAM,OAAO,IAAI,KAAK,IAAI,CAAC,OAAO;AAAA,YAChC,IAAI,EAAE;AAAA,YACN,MAAM,EAAE;AAAA,YACR,MAAM,EAAE;AAAA,YACR,QAAQ,EAAE,UAAU,QAAQ,KAAK,GAAG,EAAE,MAAM,GAAG,EAAE;AAAA,YACjD,YAAY,EAAE,gBAAgB,EAAE,cAAc,MAAM,GAAG,EAAE,IAAI;AAAA,UAC/D,EAAE;AACF,gBAAM,MAAM,MAAM,MAAM,CAAC,MAAM,QAAQ,QAAQ,UAAU,YAAY,CAAC;AACtE,iBAAO,IAAI,cACP,MAAMA,QAAM,IAAI;AAAA;AAAA,yBAA8B,IAAI,WAAW,EAAE,IAC/D;AAAA,QACN,CAAC;AAAA,MACH,SAAS,KAAK;AACZ,YAAI,GAAG;AAAA,MACT;AAAA,IACF;AAAA,EACF;AACJ;;;AlBxFA,IAAM,UAAU,IAAIC,SAAQ;AAE5B,QACG,KAAK,WAAW,EAChB,YAAY,yDAAoD,EAChE,QAAQ,OAAO,EACf;AAAA,EACC;AAAA,EACA;AACF,EACC;AAAA,EACC;AAAA,EACA;AACF,EACC,OAAO,cAAc,yCAAyC,EAE9D,KAAK,aAAa,CAAC,gBAAgB;AAClC,QAAM,OAAO,YAAY,KAItB;AACH,aAAW;AAAA,IACT,MAAM,QAAQ,KAAK,IAAI,KAAK,CAAC,QAAQ,OAAO;AAAA,IAC5C,QAAQ,QAAQ,KAAK,MAAM;AAAA,IAC3B,OAAO,KAAK,UAAU,SAAS,CAAC,QAAQ,IAAI;AAAA,EAC9C,CAAC;AACH,CAAC;AAEH,qBAAqB,OAAO;AAC5B,sBAAsB,OAAO;AAC7B,0BAA0B,OAAO;AACjC,wBAAwB,OAAO;AAC/B,sBAAsB,OAAO;AAC7B,sBAAsB,OAAO;AAC7B,0BAA0B,OAAO;AACjC,yBAAyB,OAAO;AAChC,0BAA0B,OAAO;AACjC,uBAAuB,OAAO;AAE9B,QAAQ,WAAW,QAAQ,IAAI;","names":["Command","chalk","program","chalk","chalk","json","program","chalk","chalk","program","chalk","chalk","readFileSync","program","truncate","chalk","chalk","program","chalk","chalk","ora","program","truncate","chalk","ora","chalk","program","truncate","chalk","chalk","program","truncate","chalk","chalk","program","chalk","chalk","program","chalk","Command"]}